Kar*_*arl 4 opencv image-processing pattern-matching computer-vision template-matching
我的问题在这里显示:问题陈述.我有一个模板图像,我必须在相机图像中检测.在检测到之后,我必须通过使用仿射变换来标准化相机图像.我的工作目标是识别十字架.我尝试使用SURF功能进行图像归一化步骤,但模板图像非常规则,不适合SURF匹配.有什么想法可以做到这一点?也许某种轮廓匹配?
所以我给了这个想法,然后意识到你正在寻找一张WHOLE票而不是那张票的子集并将其转换为常规矩形.这个问题(至少在理论上)并不是那么困难,编写一些代码来自己完成它是相对微不足道的.
到目前为止,最困难的部分将是最初的角点检测.由于您只对整个机票感兴趣,因此机票上的所有内容均无效.你感兴趣的只是四个角落.你可以从你的照片中看到,当一张票位于另一张票的顶部时,角落并不明显.如果你的所有照片都是一张铺在非常黑暗的表面上的票,那么这将是一件轻而易举的事,但这个想法是编写一个可以帮助处理甚至模棱两可的案件的应用程序.话虽如此,我建议采用以下方法:
1)使用图像滤镜来减轻图像的亮区,并使图像的暗区变暗.
我忘记了这种过滤器的名称,但基本上你想要在图像的较暗和较亮区域之间有更多的对比度.
2)锐化给定亮度以上的所有区域,高斯模糊给定黑暗下的所有区域
特征发现算法通常依赖于图像中的"清晰度"以能够检测角落和边缘.通过锐化图像的所有较亮区域(考虑到您的票证为白色)并模糊图像的所有较暗区域,您将增加通过算法检测您正在寻找的角落的机会.
3)使用特征检测来检测四个角
这是事情变得多毛的地方.如果你有一堆乐透彩票,你正在拍照,并且你希望能够通过算法找到它并显示它没有失真,那么你就是在谈论目前正在研究的尖端材料.如果这是你想要做的,那么我建议阅读一些Yanxi Liu的论文,最着名的是基于转换对称的感知分组与城市场景的应用.您很可能必须根据故障单的预制图片创建模板,然后尝试将此模板的确切功能与相机图像中相同功能的扭曲网格相匹配.一旦匹配超过百分比阈值,您就可以尝试找到它的四个角.如果您成功找到它们,那么您可以继续下一步.
另一方面,如果你没有尝试做尖端的东西,那么你可以只做一些书本功能检测.对于角点检测,我建议使用The Harris&Stephens/Plessey/Shi-Tomasi角点检测算法.这与Yanxi在她的一些论文中使用的算法相同,并且在角点检测方面做得非常好.我不确定滤镜是否采用图像的灰度级或是否采用当前的色阶,但是如果它采用后者,那么在使用角点检测算法之前使用Canny边缘检测滤波器将是有利的.一旦你检测到票据的主要角落(希望如此),你就需要设计某种智能查找算法(根据你的照片的视角和内容)来"猜测"哪些角落实际上是你关心的四个角落.
值得注意的是,"Mean Shift Belief Propagation"可以帮助您确定检测算法后最重要的特征.基本上,您在给定的框中获取多个要素点,平均所有坐标,然后将框放在生成的坐标中心.如果移动后盒子中有新点,那么您再次执行此操作.您继续这样做,直到您在框的中心有一个兴趣点.这是对这个想法的简要描述,所以我建议你进一步研究,因为我不知道平均细节.
4)使用双线性插值来确定转移到最终图像所需的颜色.
请务必注意,您不希望从图像中获取扭曲的颜色.在图像上运行所有滤镜和检测算法的目的是找到您感兴趣的要素点.一旦有了这些坐标,就可以回到使用原始图像来拉取颜色.
如果你问这个问题,那么我假设你知道什么是双线性插值.您可以认为扭曲票证的顶部和底部边缘从0(左角)开始,到1(右角)结束.你会认为左边和右边从0(顶角)开始,到1(底角)结束.您可以将相同的逻辑应用于输出图像的尺寸.在输出图像中逐个像素地找到您需要检索颜色的插值坐标,并使用双线性插值从输入图像中提取颜色.
就是这样!(笑)你要做的事情非常复杂,我祝你好运.从我所知道的,创建一个能够完全满足所有情况而无需任何用户输入的算法,几乎是不可能的.此外,您正在查看乐透彩票这一事实引发了这个项目的道德规范问题.无论如何,希望这足以让你的大脑开始.以下是一些其他链接:
Canny边缘检测:http://en.wikipedia.org/wiki/Edge_detection
角点检测:http://en.wikipedia.org/wiki/Corner_detection
Yanxi Liu的论文:http://www.cse.psu.edu/~yanxi/
均值转换信念传播:在我告诉你的论文中使用
编辑
级别分离代码
int threshold = 128;
float percentChange = .5;
int oldr, oldg, oldb, newr, newg, newb, grayscale;
//Assuming that pixels is a 1D array of pixel objects that make up the image you're currently working with. Syntax is of Processing.org
for (int i=0; i<pixels.length; i++) {
oldr = red(pixels[i]);
oldg = green(pixels[i]);
oldb = blue(pixels[i]);
grayscale = Math.floor((oldr + oldg + oldb) / 3.0);
if (grayScale >= threshold) { //Brightness is above threshold, therefore increase brightness
newr = oldr + (255-oldr)*percentChange;
newg = oldg + (255-oldg)*percentChange;
newb = oldb + (255-oldb)*percentChange;
} else { //Brightness is below threshold, therefore increase darkness
newr = oldr - oldr*percentChange;
newg = oldg - oldg*percentChange;
newb = oldb - oldb*percentChange;
}
pixels[i] = color(newr,newg,newb);
}
Run Code Online (Sandbox Code Playgroud)