python - OpenCV - 获取所有 Blob 像素

标签 python opencv image-processing blob pixel

我有这张图片:

enter image description here

我一直在使用 特征 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 :

enter image description here

问题:我希望能够获得所有 Blob 像素的列表,以便将它们绘制出来。我似乎找不到使用 SimpleBlobDetector 返回所有 Blob 像素的方法。我可以获得关键点(通过 detect 返回),但我相信那些对应于 blob 中心。

我还应该补充一点,我只想绘制出特定大小的 Blob ,这就是为什么抓取所有白色像素的一揽子方法并不理想。

是否有任何与 SimpleBlobDetector(或 OpenCV 中的其他地方)相关的函数返回与所有 Blob 相关的所有像素?

预先感谢您的帮助。

最佳答案

您可以使用 np.column_stack + np.where在二值图像上得到所有点的坐标。对于这个例子,我将每个点都涂成绿色到一个新的蒙版上。这是结果

enter image description here

这是每个像素的(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/

相关文章:

python - 通过使用其质心之间的欧式距离来提高检测精度

python - 有没有办法在单个数据点内绘制多个图以与分类器一起使用?

python - IP摄像机中的MTCNN_face_detection_alignment滞后,opencv cv2视频捕获帧矩阵背后的约定

c++ - Eigen:给map赋值

JavaCV警告标志检测?

python - 检测图像中的特定角点 - OpenCV - Python

python - 将图像分割成任意数量的框

python - 我需要更改当前数据框的格式。我应该怎么做?

python - 定期任务在 Django Celery 中不起作用

python - 如何像流媒体一样播放正在下载的视频?