【问题标题】:OpenCV - Blob/ Defect/ Anomaly DetectionOpenCV - 斑点/缺陷/异常检测
【发布时间】:2020-12-05 04:39:15
【问题描述】:

我在家做项目基本上只是为了好玩,但我遇到的麻烦比预期的要多。我希望能够在此示例图像中找到音高标记。 enter image description here

我遵循了一些教程和一些东西来从某个位置加载图像并在图像上运行简单的 blob 检测。我的代码目前如下 ->

import cv2
import numpy as np

# Read in the image in grayscale
img = cv2.imread('/home/pi/Downloads/divot1.jpeg', cv2.IMREAD_GRAYSCALE)

params = cv2.SimpleBlobDetector_Params()
params.filterByArea = True
params.minArea = 50

# Determine which openCV version were using
if cv2.__version__.startswith('2.'):
    detector = cv2.SimpleBlobDetector(params)
else:
    detector = cv2.SimpleBlobDetector_create(params)

# Detect the blobs in the image
keypoints = detector.detect(img)
print(len(keypoints))

# Draw detected keypoints as red circles
imgKeyPoints = cv2.drawKeypoints(img, keypoints, np.array([]), (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)


# Display found keypoints
cv2.imshow("Keypoints", imgKeyPoints)
cv2.waitKey(0)

cv2.destroyAllWindows()

我知道在使用 openCV 时还有很多图像处理技术,但我希望有人能指出我正确的方向。我尝试了一些方法,比如各种模糊类型,以消除每片草叶的一些“噪音”。我也尝试弄乱一些参数,尽管我不确定我使用的参数是否有帮助(min/maxAREA、color、convexity)

最终目标是能够找到图像中的深褐色异常,并返回该形状的中心“坐标”。

【问题讨论】:

    标签: python opencv image-processing


    【解决方案1】:

    还没有人提到模糊,所以我会。

    草的精细细节相当于噪音,无论您对图片做什么都会打扰您。模糊它。

    编辑:因为我被要求提供一些参数-“更少”的方法:

    Saliency.

    或者不错的旧统计数据。

    im = cv.imread("green-blurred.jpg")
    yuv = cv.cvtColor(im, cv.COLOR_BGR2YCrCb) # or COLOR_BGR2YUV, should work equivalently here
    #uv = yuv[:,:,(2,3)]
    mean = np.mean(yuv, axis=(0,1))
    std = np.std(yuv, axis=(0,1))
    #mask = ((yuv - mean) / std >= 4.5).any(axis=2)
    # EDIT: there needs to be an abs() on that difference, we want magnitudes, no signs
    mask = (np.abs(yuv - mean) / std >= 4.5).any(axis=2)
    mask_u8 = mask.astype(np.uint8) * 255
    #grayscale = (np.abs(yuv - mean) / std / 5).max(axis=2)
    cv.imshow("mask", mask_u8)
    cv.waitKey(-1)
    

    不是一个完美的方法,但可能可以调整。

    使用任何你喜欢的东西来本地化 blob。 findContours 将是一个简单的选择。使用 cv::moments 获取一些统计信息,您可以将其转化为 blob 的质心(质心)。

    【讨论】:

    • 当我回答第一个答案时,有没有办法绕过使用颜色阈值?音高标记可能并不总是棕色的。这就是我将其命名为缺陷/异常检测的原因。例如,无论颜色如何,图像区域是否有足够显着的变化值得承认。
    • 您可以对颜色进行统计。我会转换为 YUV 空间,它以更合适的方式表示色度。然后找到 UV 值的平均值和标准偏差,以及任何你可以标记的异常(2-3 sigma)。
    • 您还可以研究“显着性”,它基本上突出了图像中“与众不同”的特征。 pyimagesearch.com/2018/07/16/opencv-saliency-detection
    • 其中任何一个都可能是我正在寻找的。我会做一些试验和错误,看看它是如何工作的。非常感谢您的回复。
    • 您好,我先尝试使用统计方法,现在出现错误。你能看看我的新问题吗? stackoverflow.com/questions/65163149/…
    【解决方案2】:

    对不起,我没有时间实现它,但对于这种特殊情况,这样的事情应该可以工作:

    1. Google 搜索“颜色选择器”并找到正确的 HSV 颜色范围。对于这种棕色,看起来您需要大约 20 度到大约 40 度的范围。
    2. 将图像转换为 HSV 颜色空间。 hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    3. 使用 cv2.inRange 创建棕色斑点所在位置的遮罩。掩码 = cv2.inRange(hsv_img, (20,0,0), (40,255,255))
    4. 将蒙版转换为黑白图像。 img2 = np.where(mask, np.uint8(255), np.uint8(0))
    5. 使用 cv2.findContours 查找褐色斑点。 contours,_ = cv2.findContours(img2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    6. 获取最大的点。 brown_spot = sorted(contours, key=cv2.contourArea, reverse=True)[0]
    7. 绘制轮廓。 cv2.drawContours(img, [brown_spot], -1, (255,0,0), 3)

    可能有一些我错过的东西或一些错误,但我认为你可以玩弄它并从这里拿走它:)

    编辑 我忽略了你也想要中心坐标的部分。如果您想要棕色斑点的质心,请获取所有 x 坐标的平均 x 坐标和所有 y 坐标的平均 y 坐标。那应该是您的质心坐标。如果我没记错的话,轮廓上有一个额外的尺寸,您可能需要使用 np.squeeze 将其删除。之后,您可以使用 np.mean(brown_spot[:,0]) 获得 y 坐标(第一列)的平均值,使用 np.mean(brown_spot[:, 1])。 cv2.findContours 只查找周长并且间距不一致,因此您的质心可能有点偏离。如果您想要更准确的质心(或者还要考虑棕色点内的空白区域),则必须使用 connectedComponents 而不是 findContours。

    【讨论】:

    • 感谢您的反馈!有没有一种工具可以根据给定的整体颜色基本上找到“异常值”,这个区域有很大的不同?我知道有像您发布的颜色过滤器,但音高标记可能并不总是棕色。
    猜你喜欢
    • 2017-09-12
    • 2017-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-05
    • 2014-05-13
    • 1970-01-01
    相关资源
    最近更新 更多