Python OpenCV – поиск черных областей в двоичном изображении

Есть какой-либо метод / функция в оболочке python Opencv, которая находит черные области в двоичном изображении? (например, regionprops в Matlab) До сих пор я загружаю исходное изображение, преобразую его в двоичное изображение через порог, а затем инвертирую его, чтобы выделить черные области (теперь белые).

Я не могу использовать сторонние библиотеки, такие как cvblobslob или cvblob

4 Solutions collect form web for “Python OpenCV – поиск черных областей в двоичном изображении”

В принципе, вы используете функцию findContours , в сочетании со многими другими функциями, специально предназначенными для OpenCV.

Используемые полезные функции (удивление, неожиданность, все они появляются на странице « Структурный анализ и форма дескрипторов» в Документах OpenCV):

  • findContours
  • drawContours
  • moments
  • contourArea
  • arcLength
  • boundingRect
  • convexHull
  • fitEllipse

пример кода (у меня есть все свойства из области regionprops Matlab, кроме WeightedCentroid и EulerNumber – вы можете разработать EulerNumber с помощью cv2.RETR_TREE в findContours и посмотреть на полученную иерархию, и я уверен, что WeightedCentroid тоже не будет так тяжело.

 # grab contours cs,_ = cv2.findContours( BW.astype('uint8'), mode=cv2.RETR_LIST, method=cv2.CHAIN_APPROX_SIMPLE ) # set up the 'FilledImage' bit of regionprops. filledI = np.zeros(BW.shape[0:2]).astype('uint8') # set up the 'ConvexImage' bit of regionprops. convexI = np.zeros(BW.shape[0:2]).astype('uint8') # for each contour c in cs: # will demonstrate with cs[0] but you could use a loop. i=0 c = cs[i] # calculate some things useful later: m = cv2.moments(c) # ** regionprops ** Area = m['m00'] Perimeter = cv2.arcLength(c,True) # bounding box: x,y,width,height BoundingBox = cv2.boundingRect(c) # centroid = m10/m00, m01/m00 (x,y) Centroid = ( m['m10']/m['m00'],m['m01']/m['m00'] ) # EquivDiameter: diameter of circle with same area as region EquivDiameter = np.sqrt(4*Area/np.pi) # Extent: ratio of area of region to area of bounding box Extent = Area/(BoundingBox[2]*BoundingBox[3]) # FilledImage: draw the region on in white cv2.drawContours( filledI, cs, i, color=255, thickness=-1 ) # calculate indices of that region.. regionMask = (filledI==255) # FilledArea: number of pixels filled in FilledImage FilledArea = np.sum(regionMask) # PixelIdxList : indices of region. # (np.array of xvals, np.array of yvals) PixelIdxList = regionMask.nonzero() # CONVEX HULL stuff # convex hull vertices ConvexHull = cv2.convexHull(c) ConvexArea = cv2.contourArea(ConvexHull) # Solidity := Area/ConvexArea Solidity = Area/ConvexArea # convexImage -- draw on convexI cv2.drawContours( convexI, [ConvexHull], -1, color=255, thickness=-1 ) # ELLIPSE - determine best-fitting ellipse. centre,axes,angle = cv2.fitEllipse(c) MAJ = np.argmax(axes) # this is MAJor axis, 1 or 0 MIN = 1-MAJ # 0 or 1, minor axis # Note: axes length is 2*radius in that dimension MajorAxisLength = axes[MAJ] MinorAxisLength = axes[MIN] Eccentricity = np.sqrt(1-(axes[MIN]/axes[MAJ])**2) Orientation = angle EllipseCentre = centre # x,y # ** if an image is supplied with the BW: # Max/Min Intensity (only meaningful for a one-channel img..) MaxIntensity = np.max(img[regionMask]) MinIntensity = np.min(img[regionMask]) # Mean Intensity MeanIntensity = np.mean(img[regionMask],axis=0) # pixel values PixelValues = img[regionMask] 

После инвертирования двоичного изображения, чтобы превратить черные в белые области, примените функцию cv.FindContours. Это даст вам границы региона, в котором вы нуждаетесь.

Позже вы можете использовать cv.BoundingRect, чтобы получить минимальный ограничивающий прямоугольник вокруг области. После того, как вы получили вершины прямоугольника, вы можете найти его центр и т. Д.

Чтобы найти центр тяжести региона, используйте функцию cv.Moment после нахождения контуров. Затем используйте cv.GetSpatialMoments в направлениях x и y. Это объясняется в справочнике opencv.

Чтобы найти область, используйте функцию cv.ContourArea.

Преобразуйте его в двоичное изображение с использованием порога с флагом CV_THRESH_BINARY_INV , вы получите порог + инверсию за один шаг.

Если вы можете использовать другую бесплатную библиотеку, вы можете использовать SciPy . Он имеет очень удобный способ подсчета областей:

 from scipy import ndimage def count_labels(self, mask_image): """This function returns the count of labels in a mask image.""" label_im, nb_labels = ndimage.label(mask_image) return nb_labels 

При необходимости вы можете использовать:

 import cv2 as opencv image = opencv.inRange(image, lower_threshold upper_threshold) 

прежде чем получить изображение маски, которое содержит только черно-белое, где белые – объекты в заданном диапазоне.

  • OpenCV - настройка фотографии с углом наклона (наклоном)
  • Python - Перспективное преобразование для OpenCV от угла поворота
  • открыть cv python при попытке найти углы шахматной доски
  • OpenCV 2.0 и Python
  • OpenCV находит цвет в круге и значение позиции Python
  • Как сегментировать изогнутый стержень для расчета угла?
  • Преобразование изображений в OpenCV
  • как добавить границу вокруг изображения в opencv python
  • Python - лучший язык программирования в мире.