我有这张图片:
我一直在使用 opencv特征 SimpleBlobDetector
识别黑色背景上的白色像素 Blob 。代码如下。
blobDetectorParameters = cv2.SimpleBlobDetector_Params()
blobDetectorParameters.filterByArea = True
blobDetectorParameters.minArea = 1
blobDetectorParameters.maxArea = 100
blobDetectorParameters.minDistBetweenBlobs = 1
blobDetectorParameters.filterByCircularity = False
blobDetectorParameters.filterByColor = False
blobDetectorParameters.filterByConvexity = False
blobDetectorParameters.filterByInertia = False
detector = cv2.SimpleBlobDetector_create(blobDetectorParameters)
keypoints = detector.detect(image)
imageWithKeypoints = cv2.drawKeypoints(image, keypoints, numpy.array([]), (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv2.imshow("Keypoints", imageWithKeypoints)
cv2.waitKey(0)
如下图所示正确识别了 Blob :
问题:我希望能够获得所有 Blob 像素的列表,以便将它们绘制出来。我似乎找不到使用 SimpleBlobDetector
返回所有 Blob 像素的方法。我可以获得关键点(通过 detect
返回),但我相信那些对应于 blob 中心。
我还应该补充一点,我只想绘制出特定大小的 Blob ,这就是为什么抓取所有白色像素的一揽子方法并不理想。
是否有任何与 SimpleBlobDetector
(或 OpenCV 中的其他地方)相关的函数返回与所有 Blob 相关的所有像素?
预先感谢您的帮助。
最佳答案
您可以使用 np.column_stack
+ np.where
在二值图像上得到所有点的坐标。对于这个例子,我将每个点都涂成绿色到一个新的蒙版上。这是结果
这是每个像素的(x,y)
坐标
[[ 28 32]
[ 28 33]
[ 29 33]
[ 31 25]
[ 31 26]
[ 37 43]
[ 37 44]
[ 37 45]
[ 38 43]
[ 38 44]
[ 38 45]
[ 85 96]
[118 116]
[118 118]
[119 116]
[119 117]
[120 116]
[121 87]
[121 115]
[122 87]
[122 115]
[123 87]
[123 97]
[123 115]
[124 87]
[124 97]
[124 115]
[125 93]
[125 95]
[125 96]
[125 114]
[125 115]
[126 94]
[126 95]
[126 96]
[126 113]
[126 114]
[127 90]
[127 94]
[127 95]
[127 96]
[127 112]
[127 113]
[128 90]
[128 91]
[128 95]
[128 102]
[128 103]
[128 104]
[128 111]
[128 112]
[129 101]
[129 102]
[129 103]
[129 104]
[130 84]
[130 85]
[130 101]
[130 102]]
代码
import numpy as np
import cv2
image = cv2.imread('1.png')
mask = np.zeros(image.shape, dtype=np.uint8)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
coords = np.column_stack(np.where(thresh > 0))
for coord in coords:
mask[coord[0], coord[1]] = (36,255,12)
print(coords)
cv2.imshow('mask', mask)
cv2.waitKey()
更新:您可以使用等高线区域过滤来达到您想要的结果。具体来说,我们可以使用 cv2.findContours()
获取所有 Blob 的轮廓,然后使用 cv2.contourArea()
使用轮廓区域进行过滤。如果轮廓通过某个最小阈值区域,那么我们绘制它,否则我们忽略轮廓。我们可以使用 cv2.drawContours()
绘制 blob,通过为最后一个参数传入 -1
,我们填充轮廓,否则任何正值都会绘制轮廓的 Blob 。这是一个例子:
import numpy as np
import cv2
image = cv2.imread('1.png')
mask = np.zeros(image.shape, dtype=np.uint8)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
threshold_area = 0.5
for c in cnts:
area = cv2.contourArea(c)
if area > threshold_area:
cv2.drawContours(mask, [c], -1, (36,255,12), -1)
cv2.imshow('mask', mask)
cv2.waitKey()
关于python - OpenCV - 获取所有 Blob 像素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59144828/