image - 检测图像中的小点

标签 image opencv image-processing computer-vision

我有带有黑点的灰度图像,可以将其转换为二进制(黑/白)图像。

样本:

灰度输入:

enter image description here

黑白图像:

enter image description here

我需要在红色圆圈中找到点

enter image description here

如果没有尖角,点之间的距离或多或少是均匀的。

我有一个基于原始灰度图像和 Harris 角点检测器以及聚类的半工作解决方案,但它非常慢且不那么直接。

我已经尝试过对圆圈进行霍夫变换,但是这些点太小(大约 10x10 像素),无法在没有太多噪音的情况下正确检测到。

但是,我能够非常正确地检测灰度图像中的线条 - 参见图像中的红线。我已经使用这些知识并根据与线的距离过滤点。

enter image description here

但是,在某些情况下,这会失败。例如下面的图片就很成问题了——whick 边框有一个“洞”并且点太近了,连接到粗线。我也从被检测为点的数字中得到误报。

enter image description here

您对可能的解决方案有任何想法,最好是使用 OpenCV?

注意这只是一个样本,点可能不在细线上,而是分开或细线太亮等。所以线不能用来检测点。

最佳答案

一个潜在的解决方案是使用 morphological operationscv2.MORPH_ELLIPSE内核来隔离小点。这个想法是用 Otsu's threshold 获得二值图像。然后使用轮廓区域过滤过滤掉大的非连接对象。从我们执行变形打开以隔离点。最后我们找到轮廓并隔离点。结果如下:

enter image description here
enter image description here

enter image description here
enter image description here

代码

import cv2
import numpy as np

# Load image, grayscale, Otsu's threshold
image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Filter out large non-connecting objects
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    area = cv2.contourArea(c)
    if area < 500:
        cv2.drawContours(thresh,[c],0,0,-1)

# Morph open using elliptical shaped kernel
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=3)

# Find circles 
cnts = cv2.findContours(opening, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    area = cv2.contourArea(c)
    if area > 20 and area < 50:
        ((x, y), r) = cv2.minEnclosingCircle(c)
        cv2.circle(image, (int(x), int(y)), int(r), (36, 255, 12), 2)

cv2.imshow('thresh', thresh)
cv2.imshow('opening', opening)
cv2.imshow('image', image)
cv2.waitKey()

关于image - 检测图像中的小点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60603243/

相关文章:

c++ - 在 C++ 中计算单 channel 直方图的均值和标准差

python - 如何通过鼠标点击而不是猜测和检查来获取 ROI 边界框坐标

image - "docker pull"命令协议(protocol)

Python 与 C++ OpenCV matchTemplate

image-processing - OpenCV:如何知道HaarTraining的进度状态

python - 我应该在openCV中使用哪种HSV颜色范围来滤除蓝色像素?

c++ - 使用 HOGDescriptor 训练 CvSVM 检测图像中的人类

c# - WPF 如何将 Image.Source 居中

如果图像保存在缓存中,jQuery .load 不会触发(仅限 Chrome)

php - timthump 如何与查询字符串 url 一起使用