Python 使用OpenCV检测小数点

Python 使用OpenCV检测小数点,python,image,opencv,image-processing,computer-vision,Python,Image,Opencv,Image Processing,Computer Vision,使用opencv-python,我试图在类似以下图像的图像中找到dot字符的位置: 42个图片集可以在这里找到:-批量下载可用 我无法创建一个opencv检测器,该检测器可以始终在这些类型的图像中找到大多数点,在单个图像上工作的任何东西(带有一些参数的斑点检测器)通常在其他图像上失败 我的大多数尝试都是使用SimpleBlobDetector这是正确的方法吗? opencv不是完成任务的合适工具吗?(我需要一个随时可用的工具,目前不可能训练神经网络) 非常感谢您的帮助。您可以尝试使用Hough

使用
opencv-python
,我试图在类似以下图像的图像中找到
dot
字符的位置:

42个图片集可以在这里找到:-批量下载可用

我无法创建一个
opencv
检测器,该检测器可以始终在这些类型的图像中找到大多数点,在单个图像上工作的任何东西(带有一些参数的斑点检测器)通常在其他图像上失败

我的大多数尝试都是使用
SimpleBlobDetector
这是正确的方法吗? opencv不是完成任务的合适工具吗?(我需要一个随时可用的工具,目前不可能训练神经网络)


非常感谢您的帮助。

您可以尝试使用
Hough Circles

circles = cv2.HoughCircles(img,cv2.HOUGH_GRADIENT,1,20,
                            param1=50,param2=30,minRadius=5,maxRadius=25)
摘自


这里是一个使用阈值+轮廓过滤的简单方法,而不是使用
SimpleBlobDetector

  • 将图像转换为灰度,然后使用大津阈值获得二值图像
  • 执行形态打开以消除小噪音
  • 查找轮廓并使用轮廓区域进行过滤

下面是一些图片的结果。小数点以绿色突出显示

代码

导入cv2
将numpy作为np导入
image=cv2.imread('3.jpg')
original=image.copy()
灰色=cv2.CVT颜色(图像,cv2.COLOR\u BGR2GRAY)
thresh=cv2.阈值(灰色,0,255,cv2.thresh\u二进制+cv2.thresh\u大津)[1]
kernel=cv2.getStructuringElement(cv2.morp_ELLIPSE,(3,3))
opening=cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel,迭代次数=2)
cnts=cv2.查找孔(开口、cv2.外部翻新、cv2.链近似简单)
如果len(cnts)==2个其他cnts[1],则cnts=cnts[0]
对于碳纳米管中的碳:
面积=cv2。轮廓面积(c)
打印(面积)
如果面积小于200:
cv2.等高线图(原始[c],-1,(36255,12),-1)
cv2.imshow('thresh',thresh)
cv2.imshow(“开始”,开始)
cv2.imshow(“原件”,原件)
cv2.waitKey()

注意:假设图像只包含数字,而不包含其他伪影,此方法将很好地工作。备选办法包括:

  • Hough圆变换已实现为。缺点是函数有很多参数,通常只适用于“完美”圆。由于图像中的小数点不是完美的圆,因此可能无法获得一致的结果,并且可能会出现误报
  • 使用
    cv2.arcLength()
    cv2.approxPolyDP()
    进行轮廓近似,该算法使用该算法,也称为拆分和合并算法。其思想是曲线可以由一系列短线段近似。为了做到这一点,我们计算轮廓的周长,然后根据顶点的数量近似轮廓的形状。请看一个例子
HoughCircles还会拾取数字的内部黑环吗(假设它们在最小/最大半径范围内?或者它只适用于高强度区域。@PeptineWitch算法搜索具有高度径向对称性的候选字符,因此如果字体字符具有椭圆,则不会拾取它们,如果字体具有带圆形内环的字符,则正如您所说,最小/最大半径应小心精选齐全。
import cv2
import numpy as np

image = cv2.imread('3.jpg')
original = image.copy()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2)

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)
    print(area)
    if area < 200:
        cv2.drawContours(original, [c], -1, (36,255,12), -1)

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