如何提高 CV2 的 HoughCircles 的准确性

How to improve accuracy of CV2's HoughCircles

为了学习新东西,我一直在涉足 OpenCV,我提议自己做的项目之一(根据朋友的建议)是确定抗菌药物中药丸产生的圆圈的直径敏感性测试。 An example of one can be found here. 在寻找实现此目的的方法时,我发现了 CV2 的 HoughCircles 的存在,因此我开始了漫长的阅读之旅,同时也只是反复试验以取得某种不错的结果。到目前为止,我想说我对该功能的工作原理有一个“不错”的理解,但是,我绝对不知道如何充分利用它。

输入我目前拥有的代码:

import numpy
import cv2

image = cv2.imread("antibiograma.png")
output = image.copy()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.blur(gray, (20,30), cv2.BORDER_DEFAULT)
height, width = blur.shape[:2]

minR = round(width/65)
maxR = round(width/11)
minDis = round(width/7)

circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1.3, minDis, param1=23, param2=72, minRadius=minR, maxRadius=maxR)

if circles is not None:
    circles = numpy.round(circles[0, :]).astype("int")
    for (x, y, r) in circles:
        cv2.circle(output, (x, y), r, (0, 255, 0), 2)
        cv2.rectangle(output, (x - 5, y - 5), (x + 5, y + 5), (0, 128, 255), -1)
cv2.imshow("result", numpy.hstack([image, output]))
cv2.waitKey()

其中大部分内容是从我试图了解其工作原理时查找的一些资源复制而来的,其中修改了大多数参数以更好地适应我正在使用的图像。

结果……不是很好。好像标记了圆圈的大致位置,but not very accurately。大多数圆圈都有一些令人讨厌的偏移,比它们应该的大一点,特别是有一个(最左边的那个)几乎完全错误。更不用说其中一些数字(特别是 dp 和 param2)也可能是 幻数 ,这是我不太满意的,我很确定这将是当我决定将其应用于不同的抗生素敏感性测试时我编写的代码(我必须补充说,我打算这样做)。

编辑:我还决定稍微调整一下图像并应用以下 t运行sformation:

im4 = 255.0 * (im/255.0)**2

取MatPlotLib生成的图和运行通过HoughCircles(不同参数)得到的图:

circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 2.3, minDis, param1=1250, param2=50, maxRadius=maxR)

Which gave me this result。然而,更准确的是,除了忽略最左边的药丸之外,还会遇到幻数问题。

所以,归结为两件事:

  1. 怎样才能更好的提高函数的准确率?
  2. 我如何确定一组适用于多张图像的参数?

如果这些看起来愚蠢和基本,我深表歉意,我对这整件事还很陌生,所以我很感激任何帮助。

干杯!

对于 OpenCV 开箱即用的算法结果,该测试示例实际上看起来不错。总有改进的余地。

这是我能够做到的:

import numpy
import cv2

image = cv2.imread("bact.png")
output = image.copy()

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

hist = cv2.equalizeHist(gray)

blur = cv2.GaussianBlur(hist, (31,31), cv2.BORDER_DEFAULT)
height, width = blur.shape[:2]

minR = round(width/65)
maxR = round(width/11)
minDis = round(width/7)

circles = cv2.HoughCircles(blur, cv2.HOUGH_GRADIENT, 1, minDis, param1=14, param2=25, minRadius=minR, maxRadius=maxR)

if circles is not None:
    circles = numpy.round(circles[0, :]).astype("int")
    for (x, y, r) in circles:
        cv2.circle(output, (x, y), r, (0, 255, 0), 2)
        cv2.rectangle(output, (x - 5, y - 5), (x + 5, y + 5), (0, 128, 255), -1)
cv2.imshow("result", numpy.hstack([image, output]))
cv2.waitKey()

我能想到的一些有助于改进或找到更好参数的建议:

  1. 将模糊图像传递给HoughCircles函数。目前,您传递的是图像的灰度版本,而不是模糊版本。

  2. 模糊大小和类型。 Blurrier images can help downstream algorithms。对于内核,大小也往往是相同的形状,例如 (20,20),使用 (20,30) 可能会得到不同的结果。

  3. Consider contrast correction 类似于 equalizeHist 或 CLAHE - 它可以帮助对对比度低或边缘褪色的图像进行边缘检测。

  4. 幻数。According to the docs,param2 可以变大以消除误报,因此请试验一下。至于 param1 和 dp,您可能需要置换一些组合并查看哪种效果最好。而且,如果您要比较具有不同照明条件的多个图像集,您可能必须首先考虑对图像进行归一化。幻数似乎是开箱即用算法的重要组成部分,因此找到有效方法的最佳方法是同时排列输入和输出图像以查看有效方法,然后进行微调。

祝你在与生物学相关的 OpenCV 之旅中好运:)