具有亚像素精度的图像处理

Posted

技术标签:

【中文标题】具有亚像素精度的图像处理【英文标题】:Image processing with sub pixel accuracy 【发布时间】:2016-04-22 22:38:12 【问题描述】:

我正在编写一个控制工业机械的用户界面程序。

本机是电子生产行业使用的全自动在线丝印机。该机器的确切用途是将焊膏印刷到裸 PCB 上。 该系统包括 2 个摄像头,它们形成一个视觉系统,用于定位基准点并自动化机器所涉及的过程。 我遇到的问题是我需要能够在从相机拍摄的图像中定位形状和对象,这很简单,但是 - 为了获得所需的精度,我需要能够以亚像素精度做到这一点.

两个摄像头组成一个双视觉摄像头,一个摄像头将向上看模板,另一个摄像头向下看 PCB。双视觉相机位于可在 X 和 Y 方向移动的移动托架上。PCB 被夹在桌子上,可以在 X、Y 和θ 方向移动。视觉系统用于检测 PCB 位置和模板位置之间的差异,然后调整工作台以将两者对齐。

编辑:

这是从现有 UI 程序中截取的部分屏幕截图:

模板图像是顶部图像,PCB 是底部图像,这里的图像是灰度图像 - 在我正在查看的新系统中,我正在使用颜色但将使用灰度是必需的。

注意:当您阅读本文时,您可能在想“为什么不直接使用现有 UI 中使用的任何东西?”现有的 UI 是用 VB6 编写的,我想摆脱它,程序的视觉方面是由不再存在的第三方公司编写的 .ocx。

我玩过 AForge.NET,发现它真的很容易使用,我可以用它来定位各种不同的形状并找到它们的中心,这很棒,但它没有亚像素精度。但是我可以以此为起点,然后将亚像素算法应用于单个中心像素甚至整个形状。

编辑:

这是从我使用 AForge 编写的测试程序中截取的示例图像:

红色轮廓和十字准线是我作为视觉辅助/实验添加的。这是用我可能使用的相机拍摄的,它的分辨率为 1280 x 1024,但镜头不是我将使用的实际镜头,这就是图像略微“鱼眼”的原因。感兴趣的物体也会比这更亮。

在实际系统中,镜头将在模板和 PCB 上看到 10mm x 8mm 的正方形,这意味着每个像素将代表 7.8125um^2,但是我可以一次以 1.25um 的增量移动 XYY 表,这如果我不能用相机看到这些动作,那基本上是没用的。 我需要 1um(亚)像素精度。

有谁知道我可以用什么来做到这一点?我已经搜索了很长一段时间,但我似乎只找到了有关以亚像素精度渲染图像的信息。

或者,更好的是,有谁知道我如何自己写一些东西来做这件事?我什至不知道从哪里开始!

我们将不胜感激任何反馈。

【问题讨论】:

您打算通过合并两个相机图像还是通过sub-pixel calculations 来完成此操作?我认为后者需要一些关于图像内容的知识。 亚像素计算(顺便感谢您提供的链接,提供了一些启示!)我已经编辑了我的问题以提供更多信息,希望对您有所帮助。 添加样本输入图像,并添加更多信息,如分辨率、像素比例和所需精度、移动步长大小等,想要的亚像素精度到底是什么(相对于您的机器几何形状)?此外,如果您有统一的光/颜色条件,那么您可以利用每种类型 PCB 的颜色和强度从 x、y 轴上的 2 个相邻像素推断线/边缘的子像素位置 我根据@Spektre 的要求添加了更多信息。你提到的听起来很有趣,也许这种方法可以奏效!但我不得不承认我在图像处理方面几乎没有经验 - 你能否详细说明/指出我将如何做到这一点的任何有用链接的方向? :) @Howard_Schmidtt 编辑完我的答案看看。 【参考方案1】:

新信息说明了很多...我认为您应该更关注粘贴应用的准确性,而不是托架位置的精度。我敢打赌,打印机的点尺寸和误差要大得多,然后 1 um,而且所需的精度取决于 PCB 的使用(接线和间隙宽度)。无论如何,我会这样做:

    线性化图像几何

    你需要去鱼眼图像。由于您的相机/光学设置将固定(尤其是焦点和到 PCB 的距离),您应该为每个 PCB 厚度制作一个棋盘网格的图像。然后创建将棋盘线性化为真实矩形的映射,以便在下一个过程之前丢弃偏差。

    标准化光照条件

    见Enhancing dynamic range and normalizing illumination

    亚像素精度

    图像的每个像素都是其区域内所有东西的集成。因此,如果我们知道任何边界(背景/前景)的两种颜色(c0,c1),那么我们就可以估计它们的子像素位置。让我们从轴对齐的矩形开始。我是这样看的:

    网格的每个正方形代表一个像素区域。 c0 是灰色,c1 是绿色。在相机图像中,您得到的最终颜色是每个像素内所有颜色的组合:

    c = s0*c0 + s1*c1

    其中c 是最终像素颜色,s0,s1 是对应于c0,c1 范围内<0,1> 的颜色的区域,其中s0+s1=1.0。现在我们要计算s0,s1 以获得亚像素精度。所以首先将边界上的像素位置检测为以下之一:

    水平边缘 垂直边 角落

    这可以通过检查相邻像素来完成。 c0,c1 可以从具有饱和颜色的像素中获得(所有邻居都具有相同的颜色)这些位于内部区域的像素中。我会忽略角像素,因为它们的位置可以从最近的 H/V 边缘像素获得(不可能从上面的等式中同时获得 x,y 坐标)。所以现在对于每个 H,V 边缘只需求解系统:

    I.  c = s0*c0 + s1*c1
    II. s0 + s1 = 1.0;
    

    计算s0,s1,垂直边缘的边缘位置是以下之一:

    x=x0 + pixel_size*s0 // if c0 is on the left
    x=x0 + pixel_size*s1 // if c1 is on the left
    

    水平边缘是这样的:

    y=y0 + pixel_size*s0 // if c0 is on the top
    y=y0 + pixel_size*s1 // if c1 is on the bottom
    

    其中x0,y0 是像素左上角的像素,坐标系是x+ 向右,y+ 向下。如果您有不同的设置,只需更改方程式...

    现在,如果您有非轴对齐的边缘,那么您需要计算斜率(一个轴需要多少像素才能在另一个轴上改变dy/dx。并相应地处理这些区域:

    所以唯一改变的是从计算的s0,s1 到实际边缘位置的转换。现在你需要计算左/右或上/下。如果您使用轴对齐示例中的方程式,那么您将获得像素中间的边缘位置。因此,您只需将其两侧的坡度移动x +/- 0.5*dx/dyy +/- 0.5*dy/dx,其中dx,dy 是边缘坡度。

    要获得dx,dy,只需沿着边缘搜索完全饱和的像素,如果找到,则(dx,dy) 是两个最接近的像素之间的距离...

[备注]

您可以在展位灰度和 RGB 上执行此操作。希望这会有所帮助。

【讨论】:

非常感谢@Spektre,这对我帮助很大!正是我正在寻找的那种信息!

以上是关于具有亚像素精度的图像处理的主要内容,如果未能解决你的问题,请参考以下文章

帧间预测--运动补偿

图像边缘检测基于matlab Zernike矩亚像素边缘检测含Matlab源码 1536期

主流浏览器的亚像素精度现状如何?

图像的亚像素边缘检测 MATLAB代码

利用OpenCV的仿射变换函数warpAffine()实现图像的亚像素级平移

利用OpenCV的仿射变换函数warpAffine()实现图像的亚像素级平移