Как преобразовать из 32-разрядного в 8-разрядный без потери информации?

#python #opencv #contour #bounding-box #8-bit

Вопрос:

Я попытался найти контуры в своем изображении с cv2.findContours помощью . Так как он использует изображения CV_8UC1 , с помощью которых я пытался преобразовать свой массив dtype=np.uint8 , до того, как он стал 32-разрядным. Но там я теряю информацию. Есть ли какой-нибудь другой способ?

Вторая проблема-ограничивающая рамка. Информация сохраняется, rect но она не отображается на картинке. Кто-нибудь знает, почему?

Вот моя картинка/массив в 32 битах:

введите описание изображения здесь

И это моя фотография, когда я добавил dtype=np.uint8 :

введите описание изображения здесь

 img_hr = np.array(b[1],dtype=np.uint8)

img_hr=img_hr*255
plt.imshow(img_hr)

hierachy, img_threshold = cv2.threshold(img_hr, 100, 255, cv2.THRESH_BINARY)

contours,_ = cv2.findContours(img_threshold, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

cv2.drawContours(img_threshold, contours, -1, (0, 255, 0), 2, cv2.LINE_AA)

for cnt in contours:         
      rect = cv2.minAreaRect(cnt)
      box = cv2.boxPoints(rect)
      box = np.int0(box)
      cv2.drawContours(img_threshold,[box],0,(0,0,255),2)
      cv2.circle(img_threshold,(int(rect[0][0]),int(rect[0][1])),5,(255,0,0),-1)

plt.imshow(img_threshold)
 

Надеюсь, вы понимаете мою проблему. Если нет, пожалуйста, спросите. Я ценю вашу помощь. Спасибо

Комментарии:

1. Я не очень хорошо понимаю ваш вопрос, но ничто не мешает вам находить контуры с помощью 8-битного изображения и применять контуры обратно к исходным 32-битным данным, когда они у вас есть.

2. Моя проблема в том, что я теряю контуры, как показано на рисунках, при преобразовании с 32 на 8 бит. Мне не нужно конвертировать обратно в 32-разрядную версию.

3. Когда ваши данные были 32-разрядными, какие пиксели были самыми яркими и самыми темными? И какими они были после того, как вы перешли на 8-битный?

4. 32 бит: мин-> 6.723715 e-20; макс ->> 255; 8 бит: мин ->>>0; макс ->>>>255

Ответ №1:

Я сам нашел решение:

Сначала я использовал 32-разрядное изображение, чтобы найти контуры cv2.threshold в 32-разрядном изображении. После этого я преобразую 32-разрядный массив в 8-разрядный np.array(img_threshold_32bit,dtype=np.uint8) без потери каких-либо контуров. Итак, теперь вход для cv2.drawContours -это 8-битный массив.

Но у меня все еще есть проблема в том, что ограничивающий прямоугольник не нарисован на графике. Есть какие-нибудь идеи?

Вот код:

 img_hr = np.array(b[1])

hierachy, img_threshold_32bit = cv2.threshold(img_hr, 100, 255, cv2.THRESH_BINARY)
img_8bit = np.array(img_threshold_32bit,dtype=np.uint8)
contours,_ = cv2.findContours(img_8bit, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img_8bit, contours, -1, (0, 255, 0), 2, cv2.LINE_AA)

for cnt in contours:
      rect = cv2.minAreaRect(cnt)
      box = cv2.boxPoints(rect)
      box = np.int0(box)
      cv2.drawContours(img_8bit,[box],0,(0,0,255),2)
      cv2.circle(img_8bit,(int(rect[0][0]),int(rect[0][1])),5,(255,0,0),-1)

plt.imshow(img_8bit)
 

Ответ №2:

поскольку вы рисуете сами, drawContours рисует только контуры контуров или заполненные контуры. вы должны найти координаты прямоугольника для каждого контура с помощью boundingRec или minAreaRect, а затем нарисовать его с помощью функций рисования opencv

проверьте этот пример кода https://github.com/birolkuyumcu/opencvbook_python/blob/master/Ders6/Ders6.py#L114

Комментарии:

1. Я думаю, что именно это я и сделал. Как я уже сказал, я нашел счетчик правильно, minAreaRect потому что моя переменная rect имеет правильные значения для ограничивающей рамки. А затем я использую drawContours , но ограничивающая рамка не показана на изображении

2. drawContours рисует ТОЛЬКО контуры контуров или заполненные контуры. прочитайте код, чтобы нарисовать прямоугольник, вы должны использовать функцию cv2.rectangle