Python OpenCV - 在二进制图像中查找黑色区域 [英] Python OpenCV - Find black areas in a binary image
问题描述
Opencv的python包装器中有任何方法/函数在二进制映像中找到黑色区域? (像Matlab中的 regionprops )
到目前为止,我加载了源图像,通过阈值将其转换为二进制图像,然后反转它以突出显示黑色区域(现在是白色)。
There is any method/function in the python wrapper of Opencv that finds black areas in a binary image? (like regionprops in Matlab) Up to now I load my source image, transform it into a binary image via threshold and then invert it to highlight the black areas (that now are white).
我无法使用第三方库,例如cvblobslob或cvblob
I can't use third party libraries such as cvblobslob or cvblob
推荐答案
基本上,您可以使用 findContours
函数,结合OpenCV特别为此目的提供的许多其他函数。
Basically, you use the findContours
function, in combination with many other functions OpenCV provides for especially this purpose.
有用的函数em>全部出现在OpenCV文档中的结构分析和形状描述符页面上):
Useful functions used (surprise, surprise, they all appear on the Structural Analysis and Shape Descriptors page in the OpenCV Docs):
findContours
drawContours
moments
contourArea
arcLength
boundingRect
convexHull
fitEllipse
示例代码(我拥有所有属性来自Matlab的 regionprops
除了 WeightedCentroid
和 EulerNumber
- 您可以通过 EulerNumber
在 findContours
中使用 cv2.RETR_TREE
并查看结果层次结构,我确定 WeightedCentroid
也不会那么难。
example code (I have all the properties from Matlab's regionprops
except WeightedCentroid
and EulerNumber
- you could work out EulerNumber
by using cv2.RETR_TREE
in findContours
and looking at the resulting hierarchy, and I'm sure WeightedCentroid
wouldn't be that hard either.
# 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]
这篇关于Python OpenCV - 在二进制图像中查找黑色区域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!