Найти самый большой Contour- OpenCV, Python - Получение ошибок - PullRequest
0 голосов
/ 10 февраля 2019

Я пытаюсь найти самый большой контур вокруг автомобиля на изображении.
Чтобы найти контур, я узнал следующее из официальной документации OpenCv:

 #convert the image to grayscale from rgb 
 1. image_gray = cv2.cvtColor(image,cv2.COLOR_RGB2GRAY)
 2. threshold  = cv2.threshold(image_gray, 127,(0,255,0),0)
 3. image2, contours_list, hierarchy = cv2.findContours(threshold, cv2.RETR_LIST, cv2.CHAIN_APROX_SIMPLE)

задача -1:
Я уже применил cv2.GaussianBlur () и преобразовал его вФормат HSV для создания масок для последующего обнаружения определенного цвета с использованием методов MorphologyEx.Проблема в том, что код на шаге 2 выше требует, чтобы изображение было либо в формате RGB, чтобы преобразовать его в шкалу серого, либо в сам формат Grey, но у меня есть формат HSV, для которого нет такого флага, как cv2.COLOR_HSV2GRAY.

Я написал следующие 2 версии одного и того же метода, чтобы найти самый большой контур, и они выдают 2 разные ошибки:
В этом методе я сначала создаю порог, для которого требуется изображение в оттенках серого, чтобы перейти к методу cv2.findContour

def find_biggest_contour(image):
   image = image.copy() 
   #1
   image_gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
   #2 
   threshold = cv2.threshold(image_gray,127, 255,0)
   #3
   image2, contours, heirarchy = cv2.findContours(threshold, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) # countours is a python list
   contours_sizes= [(cv2.contourArea(cnt), cnt) for cnt in contours]
   biggest_contour = max(contours_sizes, key=lambda x: x[0])[1]
   #define a mask
   mask = np.zeros(image.shape, np.uint8)
   cv2.drawContours(mask,[biggest_contour], -1, (0,255,0), 3)# 3=thickness, -1= draw all contours, 2nd arg must be a list 
   return biggest_contour, mask

этот метод выдает мне следующую ошибку:
error for the 1st version of method Другая версия выглядит следующим образом (в основном, у меня естьоткуда-то взял):

def find_biggest_contour(image):
   image = image.copy()
   im2,contours, hierarchy = cv2.findContours(image, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

   contour_sizes = [(cv2.contourArea(contour), contour) for contour in contours]
   biggest_contour = max(contour_sizes, key=lambda x: x[0])[1]

   mask = np.zeros(image.shape, np.uint8)
   cv2.drawContours(mask, [biggest_contour], -1, 255, -1)
   return biggest_contour, mask

Этот метод выдает следующую ошибку:
error for the 2nd version of method

Пожалуйста, помогите мне исправить ошибки.Я новичок в opencv.

Ответы [ 2 ]

0 голосов
/ 11 февраля 2019

Из OpenCV 4.0, findContours() возвращает только 2 значения, поэтому должно быть:

contours, hierarchy = cv2.findContours(threshold, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
0 голосов
/ 10 февраля 2019

Я не знаю точно, что вызывает у вас проблему, но держу пари, что она была вызвана этой

threshold = cv2.threshold(image_gray,127, 255,0)

этой функцией

cv2.threshold()

возвращает кортеж , поэтому вам нужно распаковать больше vals.например,

_,threshold = cv2.threshold(image_gray,127, 255,0)

, где _ игнорирует первое возвращаемое значение кортежа

, а * threshold - матрица.

так в основном то, что мы сделали, это:

_, matrix = (127,'Matrix')
>>> print(matrix)
'Matrix'

То, что вы сделали, это:

matrix = (127,'Matrix')
>>> print(matrix)
(127,'Matrix')

Полный код: работает для меня

import cv2
import numpy as np

hsv_image = cv2.imread('someimage.jpg',1) # pretend its HSV
rgbimg = cv2.cvtColor(hsv_image, cv2.COLOR_HSV2RGB)
image_gray = cv2.cvtColor(rgbimg, cv2.COLOR_BGR2GRAY)
_,threshold = cv2.threshold(image_gray,127, 255,0)

im2,contours, hierarchy = cv2.findContours(threshold, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
contour_sizes = [(cv2.contourArea(contour), contour) for contour in contours]

biggest_contour = max(contour_sizes, key=lambda x: x[0])[1]

Примечание для упоминания:

Важно понимать, что OpenCV по какой-то причине (я слышал из исторической) использует не RGB, а цветовое пространство BGR.Пока вы работаете с оттенками серого или только внутри opencv (без использования RGB), вы даже не узнаете.Но как только вы преобразуете свой массив в PIL, вы узнаете ... Еще одно замечание.В вашем случае все в порядке, потому что BGR в серый или RGB в серый приводит к одному и тому же изображению ...

...