子像素精度的图像处理

时间:2016-01-17 20:21:04

标签: c# image-processing computer-vision vision subpixel

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

该机器是一种用于电子生产行业的自动在线丝网印刷机。该机器的确切用途是将焊膏印刷到裸PCB上。 该系统包括2个摄像机,形成视觉系统,用于定位基准点并自动化机器所涉及的过程。 我的问题是我需要能够找到从相机拍摄的图像中的形状和物体,这是足够直接的,但是 - 为了获得所需的精度,我需要能够以亚像素精度执行此操作

这两个相机组成一个双视觉相机,一个相机将向上看模板,另一个向下看PCB。双视觉相机位于移动的托架上,在X和Y上移动.PCB被夹在桌子上,而不是在X,Y和θ中移动。视觉系统用于检测PCB位置和模板位置之间的差异,然后调整表格以使两者对齐。

编辑:

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

This

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

注意:当您正在阅读本文时,您可能会想到"为什么不在现有用户界面中使用您使用的任何内容?&? #34;现有的用户界面是用VB6编写的,这是我想要离开的,而程序的愿景是由不再存在的第三方公司编写的.ocx。

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

编辑:

以下是使用AForge编写的测试程序中的示例图像:

Here

红色轮廓和十字准线是我作为视觉辅助/实验添加的。这是我可能使用的相机拍摄的,其分辨率为1280 x 1024,但镜头不是我将使用的实际镜头,这就是为什么图像略微&#39 ; fisheyed&#39 ;.感兴趣的物体也会比这更好。

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

有没有人知道我可以用来做这件事的任何事情?我现在已经搜索了很长一段时间,但我似乎找到的只是以亚像素精度渲染图像的信息。

或者,更好的是,有没有人知道我自己可以写些什么来做这件事?我甚至不知道从哪里开始!

非常感谢任何反馈。

1 个答案:

答案 0 :(得分:0)

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

  1. 线性化图像几何

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

  2. 规范照明条件

  3. 亚像素精度

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

    sub-pixel aligned

    网格的每个方格表示像素区域。 c0为灰色,c1为绿色。在相机图像中,您将最终颜色作为每个像素内所有颜色的组合:

    • c = s0*c0 + s1*c1

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

    • 水平边
    • 垂直边缘

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

    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。并相应地处理这些区域:

    sub-pixel non aligned

    因此,唯一改变的是从计算x +/- 0.5*dx/dy到实际边缘位置的转换。现在你需要计算左/右侧或上/下。如果您使用轴对齐示例中的公式,则可以获得像素中间的边缘位置。因此,您只需将y +/- 0.5*dy/dxdx,dy两侧的坡度移至dx,dy,即(dx,dy)为边坡。

    slope

    要获得{{1}}只是沿着边缘搜索完全饱和的像素,如果找到则{{1}}是2个最接近的像素之间的距离......

  4. <强> [注释]

    你可以在展位灰度和RGB上做到这一点。希望这有点帮助。