【问题标题】:Detection of grid points from scanned prints in Python / OpenCV在 Python / OpenCV 中从扫描的打印件中检测网格点
【发布时间】:2021-10-28 17:43:15
【问题描述】:

我扫描了由不同喷墨打印机(爱普生、惠普、佳能等)打印的文档。每张照片都具有非常高的质量(例如 1.6GB),您可以放大并查看使用频率调制的图片的半色调。

我的任务是根据网格点、网格的图案、点的距离等进行特征提取。

相关特征是这些点的大小(每台打印机打印不同大小的这些点 - 必须计算平均值和标准差)。

稍后我将不得不使用 ML 训练一个模型,训练后的模型应该将打印分类到特定的打印机(所以基本上这个打印属于打印机 XYZ)。

但现在我已经在特征工程和预处理方面苦苦挣扎,因为这是我的第一个计算机视觉项目,而且我对 opencv 不太熟悉。

我有一个想法,我的计划是使用图像的 opencv 进行二进制转换,以通过 Sobel 或 Prewitt 滤波器或其他方式确定边缘(边缘检测)。 所以我认为我必须先进行一些模糊处理,然后再进行边缘检测?

我不确定这是否是正确的方法,所以我在这里问,你怎么看? 如果您能给我一些提示或步骤以获得最佳或好的方法,我会很高兴。

【问题讨论】:

  • 您可以使用 cv2.inRange() 设置颜色阈值。一次选择一种颜色。然后可能使用 cv2.connectedComponentsWithStats() 来查找所有隔离区域及其大小。然后您可以获得所有区域的平均大小和标准差。或者,在阈值化之后,您可以获得每个孤立区域的轮廓并从中获取大小。

标签: python opencv computer-vision


【解决方案1】:

这是 Python/OpenCV 中的一种方式。

使用 cv2.inRange() 的颜色阈值。在这种情况下,我将对蓝点设置阈值。然后获取所有外部轮廓以找到所有孤立区域。根据轮廓,计算等效圆直径。然后计算平均值和标准差。

输入:

import cv2
import numpy as np
import math

img = cv2.imread("color_dots.png")

# threshold on blue color
lower = (190,150,100)
upper = (255,255,170)
thresh = cv2.inRange(img, lower, upper)

# get external contours
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
count = len(contours)

sum = 0
sum2 = 0
for cntr in contours:
    # get area from contours and then diameters of equivalent circles
    area = cv2.contourArea(cntr)
    # area = pi*radius**2 = pi*(diameter/2)**2 = (pi/4)*diameter**2
    # diameter = sqrt(4*area/pi) = 2*sqrt(area/pi)
    diameter = 2 * math.sqrt(area/math.pi)
    sum = sum + diameter
    sum2 = sum2 + diameter * diameter

# compute average2 (mean)
average = sum/count
average2 = sum2/count

# compute standard deviation
variance = average2 - average*average
standard_deviation = math.sqrt(variance)

# print results
print("average:", average)
print("std_dev:", standard_deviation)

# save result
cv2.imwrite("color_dots_blue_threshold.png",thresh)

# display result
cv2.imshow("thresh", thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()

阈值图像:

结果:

average: 3.0747726858108635
std_dev: 0.541288251281962

【讨论】:

  • 哇太棒了!谢谢!我不知道最好分成每种颜色(蓝色,黄色,青色)......还有什么有趣的,是点之间的平均距离,我怎样才能做到这一点?是否可以用opencv计算距离?
  • 蛮力方法是从轮廓中获取质心并计算每个点到每个其他点的距离。然后为每个找到最短的距离。
  • 这些可能感兴趣:codereview.stackexchange.com/questions/28207/…stackoverflow.com/questions/51022381/…。但这可能是最好的。它计算两个数组之间的所有距离。他们在数组中寻找给定输入位置的最小输出。见docs.scipy.org/doc/scipy/reference/generated/…
  • 再次感谢!我还将对其他点设置阈值,并对您示例中的阈值下限和上限有疑问:如何像您对蓝色所做的那样确定值? lower = (190, 150, 100)upper = (255, 255, 170)
  • 我在其他工具中测量了一些蓝色值,并对范围进行了初步估计。然后只需尝试和调整,直到黑/白点的大小与输入相匹配。使用 cv2.imshow() 进行视觉检查。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-02-13
  • 2013-01-09
  • 2014-11-17
  • 2012-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多