图像处理之积分图应用三(基于NCC快速相似度匹配算法)

from:https://blog.csdn.net/jia20003/article/details/53021614

图像处理之积分图应用三(基于NCC快速相似度匹配算法)

基于Normalized cross correlation(NCC)用来比较两幅图像的相似程度已经是一个常见的图像处理手段。在工业生产环节检测、监控领域对对象检测与识别均有应用。NCC算法可以有效降低光照对图像比较结果的影响。而且NCC最终结果在0到1之间,所以特别容易量化比较结果,只要给出一个阈值就可以判断结果的好与坏。传统的NCC比较方法比较耗时,虽然可以通过调整窗口大小和每次检测的步长矩形部分优化,但是对工业生产检测然后不能达到实时需求,通过积分图像实现预计算,比较模板图像与生产出电子版之间的细微差异,可以帮助企业提高产品质量,减少次品出厂率,把控质量。

一:NCC相关的数学知识

什么是NCC - (normalized cross correlation)归一化的交叉相关性,是数学上统计两组数据之间是否有关系的判断方法,貌似搞大数据分析比较流行相关性分析和计算。正常的计算公式如下:

mxn表示窗口大小,这样的计算复杂度就为O(m x n x M x N)。从上面公式就可以看出其中均值和平方和可以通过积分图预计算得到,对于模板和目标图像大小一致的应用场景来说

NCC的计算公式可以表示为如下:

其中根据积分图像可以提前计算出任意窗口大小和与平方和,这样就对

上述两个计算实现了窗口半径无关的常量时间计算,唯一缺少的是下面计算公式

通过积分图像建立起来窗口下面的待检测图像与模板图像的和与平方和以及他们的交叉乘积五个积分图索引之后,这样就完成了整个预计算生成。依靠索引表查找计算结果,NCC就可以实现线性时间的复杂度计算,而且时间消耗近似常量跟窗口半径大小无关,完全可以满足实时对象检测工业环境工作条件。

 

二:算法步骤

1. 预计算模板图像和目标图像的积分图

2. 根据输入的窗口半径大小使用积分图完成NCC计算

3. 根据阈值得到匹配或者不匹配区域。

4. 输出结果

为了减小计算量,我们可以要把输入的图像转换为灰度图像,在灰度图像的基础上完成整个NCC计算检测。我们这个给出的基于RGB图像的NCC计算完整代码,读者可以在此基础上修改实现单通道图像检测。

三: 运行结果:

输入的模板图像与待检测图像,左边是模板图像,右边是待检测图像,左上角有明显污点。图像显示如下:

  

输入待检测图像与模板比较以及检测计算出NCC的图像显示如下:

其中左侧是待检测图像,上面有黑色污点,右侧输出的非黑色区域表明,程序已经发现此区域与标准模板不同,越白的区域表示周围跟模板相同位置反差越大,越是可疑的污染点,这样就可以得到准确定位,最终带检测图像绘制最可疑红色矩形窗口区域

四:相关代码实现

1. 计算两张图像每个像素交叉乘积的积分图代码如下:

	public void caculateXYSum(byte[] x, byte[] y, int width, int height) {if(x.length != y.length)return;xysum = new float[width*height];this.width = width;this.height = height;// rowsint px = 0, py = 0;int offset = 0, uprow=0, leftcol=0;float sp2=0, sp3=0, sp4=0;for(int row=0; row<height; row++ ) {offset = row*width;uprow = row-1;for(int col=0; col<width; col++) {leftcol=col-1;px=x[offset]&0xff;py=y[offset]&0xff;int p1 = px*py;// 计算平方查找表sp2=(leftcol<0) ? 0:xysum[offset-1]; // p(x-1, y)sp3=(uprow<0) ? 0:xysum[offset-width]; // p(x, y-1);sp4=(uprow<0||leftcol<0) ? 0:xysum[offset-width-1]; // p(x-1, y-1);xysum[offset]=p1+sp2+sp3-sp4;offset++;}}}
获取任意窗口大小的交叉乘积的代码如下:
	public float getXYBlockSum(int x, int y, int m, int n) {int swx = x + n/2;int swy = y + m/2;int nex = x-n/2-1;int ney = y-m/2-1;float sum1, sum2, sum3, sum4;if(swx >= width) {swx = width - 1;}if(swy >= height) {swy = height - 1;}if(nex < 0) {nex = 0;}if(ney < 0) {ney = 0;}sum1 = xysum[ney*width+nex];sum4 = xysum[swy*width+swx];sum2 = xysum[swy*width+nex];sum3 = xysum[ney*width+swx];return ((sum1 + sum4) - sum2 - sum3);}

 

其余部分的积分图计算,参见本人博客《图像处理之积分图算法》
2. 预计算建立积分图索引的代码如下:

		// per-calculate integral image for targetImagebyte[] R = new byte[width * height];byte[] G = new byte[width * height];byte[] B = new byte[width * height];getRGB(width, height, pixels, R, G, B);IntIntegralImage rii = new IntIntegralImage();rii.setImage(R);rii.process(width, height);IntIntegralImage gii = new IntIntegralImage();gii.setImage(G);gii.process(width, height);IntIntegralImage bii = new IntIntegralImage();bii.setImage(B);bii.process(width, height);// setup the refer and target image index sum tablerii.caculateXYSum(R, referRGB[0].getImage(), width, height);gii.caculateXYSum(G, referRGB[1].getImage(), width, height);bii.caculateXYSum(B, referRGB[2].getImage(), width, height);int size = (xr * 2 + 1) * (yr * 2 + 1);

3. 通过积分图查找实现快速NCC计算的代码如下:

		int r1=0, g1=0, b1=0;int r2=0, g2=0, b2=0;float sr1=0.0f, sg1=0.0f, sb1 = 0.0f;float sr2=0.0f, sg2=0.0f, sb2 = 0.0f;float xyr = 0.0f, xyg = 0.0f, xyb = 0.0f;for (int row = yr; row < height - yr; row++) {for (int col = xr; col < width - xr; col++) {r1 = rii.getBlockSum(col, row, (yr * 2 + 1), (xr * 2 + 1));g1 = gii.getBlockSum(col, row, (yr * 2 + 1), (xr * 2 + 1));b1 = bii.getBlockSum(col, row, (yr * 2 + 1), (xr * 2 + 1));r2 = referRGB[0].getBlockSum(col, row, (yr * 2 + 1), (xr * 2 + 1));g2 = referRGB[1].getBlockSum(col, row, (yr * 2 + 1), (xr * 2 + 1));b2 = referRGB[2].getBlockSum(col, row, (yr * 2 + 1), (xr * 2 + 1));sr1 = rii.getBlockSquareSum(col, row, (yr * 2 + 1), (xr * 2 + 1));sg1 = gii.getBlockSquareSum(col, row, (yr * 2 + 1), (xr * 2 + 1));sb1 = bii.getBlockSquareSum(col, row, (yr * 2 + 1), (xr * 2 + 1));sr2 = referRGB[0].getBlockSquareSum(col, row, (yr * 2 + 1), (xr * 2 + 1));sg2 = referRGB[1].getBlockSquareSum(col, row, (yr * 2 + 1), (xr * 2 + 1));sb2 = referRGB[2].getBlockSquareSum(col, row, (yr * 2 + 1), (xr * 2 + 1));xyr = rii.getXYBlockSum(col, row, (yr * 2 + 1), (xr * 2 + 1));xyg = gii.getXYBlockSum(col, row, (yr * 2 + 1), (xr * 2 + 1));xyb = bii.getXYBlockSum(col, row, (yr * 2 + 1), (xr * 2 + 1));float nccr = calculateNCC(r1, r2, sr1, sr2, xyr, size);float nccg = calculateNCC(g1, g2, sg1, sg2, xyg, size);float nccb = calculateNCC(b1, b2, sb1, sb2, xyb, size);outPixels[row * width + col] = (nccr + nccg + nccb);}}System.out.println("time consum : " + (System.currentTimeMillis() - time));

4. 归一化输出NCC图像与结果代码如下:

		// normalization the datafloat max = 0.0f, min = 100.0f;for(int i=0; i<outPixels.length; i++) {max = Math.max(max, outPixels[i]);min = Math.min(min, outPixels[i]);}// create output image float delta = max - min;BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);int ry = -1;int rx = -1;for(int row = 0; row<height; row++) {for(int col=0; col<width; col++) {int gray = (int)(((outPixels[row*width+col]-min) / delta) *255);gray = 255 - gray;if(min == outPixels[row*width+col]) {bi.setRGB(col, row, Color.RED.getRGB());ry = row;rx = col;} else {int color = (0xff << 24) | (gray << 16) | (gray << 8) | gray;bi.setRGB(col, row, color);}}}if(rx > 0 && ry > 0) {Graphics2D g2d = image.createGraphics();g2d.setPaint(Color.RED);g2d.drawRect(rx-xr, ry-yr, xr*2, yr*2);}

相比传统的NCC计算方法,此方法的计算效率是传统方法几百倍提升,而且窗口越大效率提升越明显,有人对此作出的统计如下:

可见基于积分图快速NCC可以极大提升执行效率减少计算时间,实现窗口半径无关NCC比较。

最后

本文是关于积分图使用的第三篇文章,可以说积分图在实际图像处理中应用十分广泛,本人会继续努力深挖与大家分享。希望各位顶下次文以表支持, 谢谢!本人坚持分享有用实用的图像处理算法!需要大家多多支持。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/458148.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入浅出地理解机器人手眼标定

from&#xff1a;https://blog.csdn.net/qq_16481211/article/details/79764730 所谓手眼系统&#xff0c;就是人眼镜看到一个东西的时候要让手去抓取&#xff0c;就需要大脑知道眼镜和手的坐标关系。如果把大脑比作B&#xff0c;把眼睛比作A&#xff0c;把手比作C,如果A和B的…

centos 6.5 安装 mongodb

官方给出的链接地址&#xff1a;https://docs.mongodb.org/manual/tutorial/install-mongodb-on-red-hat/ 安装后重要的日志 win10 上使用mongochef连接不上数据库 解决方案&#xff1a; 修改 /etc/mongod.conf 将bindIP 改为0.0.0.0 监听外网转载于:https://www.cnblogs.com/l…

opencv3/C++ 机器学习-SVM应用实例:药品(胶囊)识别与分类

from&#xff1a;https://blog.csdn.net/akadiao/article/details/79278072 版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 https://blog.csdn.net/akadiao/article/details/79278072 问题描述&#xff1a; 现对6种不同颜色药品&#xff08;胶囊…

linux命令学习-1-less

less 工具也是对文件或其它输出进行分页显示的工具&#xff0c;应该说是linux正统查看文件内容的工具&#xff0c;功能极其强大。less 的用法比起 more 更加的有弹性。在 more 的时候&#xff0c;我们并没有办法向前面翻&#xff0c; 只能往后面看&#xff0c;但若使用了 less …

jspspy database help

.转载于:https://www.cnblogs.com/outline/p/5316051.html

SVM 调参策略

转自&#xff1a;SVM 调参策略&#xff1a;https://blog.csdn.net/u014484783/article/details/78220646 SVM 怎样能得到好的结果 1. 对数据做归一化&#xff08;simple scaling&#xff09; 2. 应用 RBF kernel 3. 用cross-validation和grid-search 得到最优的c和g 4. 用…

美好的⼀天 从ActionTab开始 美观、智能、⾼效的新标签⻚ iTab 新标签页iTab新标签页Atop100工具推荐

文章目录 ActionTabiTab 新标签页iTab新标签页&#xff0c;小组件&#xff0c;起始页&#xff0c;标签页&#xff0c;日历&#xff0c;股票&#xff0c;浏览器扩展 https://www.actiontab.cn/ ActionTab 收费&#xff1f;&#xff1f;&#xff1f;&#xff1f; iTab 新标签页iT…

机器学习中的算法(2)-支持向量机(SVM)基础

from:http://www.cnblogs.com/LeftNotEasy/archive/2011/05/18/2034566.html 版权声明&#xff1a; 本文由LeftNotEasy发布于http://leftnoteasy.cnblogs.com, 本文可以被全部的转载或者部分使用&#xff0c;但请注明出处&#xff0c;如果有问题&#xff0c;请联系wheeleastgm…

Kinect深度图与摄像头RGB的标定与配准(转载文章)

作者原文地址&#xff1a;http://blog.csdn.net/aichipmunk/article/details/9264703 自从有了Kinect&#xff0c;根据深度图提取前景就非常方便了。因此出现了很多虚拟现实、视频融合等应用。但是&#xff0c;Kinect自身的RGB摄像头分辨率有限&#xff0c;清晰度也不及一些专业…

台北到淡水版Firefox无法播放视频

台北到淡水版的Firefox所有的视频都无法播放&#xff0c;禁用了各种插件也还是没法播放&#xff0c;最后才确定是SWF的问题&#xff0c;大家有同样问题的&#xff0c;可以下载我的放到SWF文件夹下&#xff0c;目录结构如下图&#xff1a; ​Firefox的SWF下载地址1 ​Firefox的S…

最详细、最完整的相机标定讲解

相机标定详解 最近做项目要用到标定&#xff0c;因为是小白&#xff0c;很多东西都不懂&#xff0c;于是查了一堆的博客&#xff0c;但没有一个博客能让我完全能看明白整个过程&#xff0c;绝大多数都讲的不全面&#xff0c;因此自己总结了一篇博客&#xff0c;给自己理一下思…

卷积与反卷积动图

各种卷积与反卷积动态图 反卷积: 详细文字链接&#xff1a;https://www.zhihu.com/question/43609045/answer/132235276(该链接中并没有下面的动态图) Deconvolution大致可以分为以下几个方面&#xff1a;&#xff08;1&#xff09;unsupervised learning&#xff0c;其实就…

ASP.NET-权限管理五张表

ASP.NET 权限管理五张表权限管理的表&#xff08;5张表&#xff09;每个表里面必有的一些信息序号名称 字段 类型 主键默认值是否为空备注1 用户ID ID INT 是 null 否用户ID2用户名称UserNamevarchar(100)否null否用户名称3用户密码UserPasswordvarchar(20)否null否用…

神经网络CNN解释

from&#xff1a;https://blog.csdn.net/ruiyiin/article/details/77113973 这篇文章原地址为An Intuitive Explanation of Convolutional Neural Networks&#xff0c;卷积神经网络的讲解非常通俗易懂。 什么是卷积神经网络&#xff1f;为什么它们很重要&#xff1f; 卷积神经…

pcl里面使用KdTree来搜索

from:https://blog.csdn.net/qq_25491201/article/details/51135054 下面这个教程我们将学会怎么用KdTree找一个特殊点附近的K个最近邻&#xff0c;然后我们也将复习怎么通过一个特殊的半径来找里面所有的近邻。 一个k-d树&#xff0c;或者k维的树是一个计算机科学里面的数据…

HI3559A和AI深度学习框架caffe

from:http://blog.sina.com.cn/s/blog_156e567660102ygdf.html 1、HI3559A支持深度学习框架caffe。其中的NNIE神经网络加速单元是主要的属性。 2、caffe是一种快速深度学习框架和TensorFlow一样是一组标准深度学习开源框架。 3、对应想尝试AI深度学习的朋友可以按照网上的流…

Google Protocol Buffer 的使用和原理

from: https://www.ibm.com/developerworks/cn/linux/l-cn-gpb/index.html 简介 什么是 Google Protocol Buffer&#xff1f; 假如您在网上搜索&#xff0c;应该会得到类似这样的文字介绍&#xff1a; Google Protocol Buffer( 简称 Protobuf) 是 Google 公司内部的混合语言…

常用的几种卷积神经网络介绍

常用的几种卷积神经网络介绍 标签&#xff08;空格分隔&#xff09;&#xff1a; 深度学习 这是一篇基础理论的博客&#xff0c;基本手法是抄、删、改、查&#xff0c;毕竟介绍这几个基础网络的博文也挺多的&#xff0c;就算是自己的一个笔记吧&#xff0c;以后忘了多看看。主…

深度学习案例

1. neural-style&#xff1a;利用卷积神经网络将一幅图像的内容与另一幅图像的风格相结合 https://github.com/jcjohnson/neural-style 2.Nerual Doodles&#xff1a;把 2 位的 Doodle 转成精良的艺术品 https://github.com/alexjc/neural-doodle 3. srez&#xff1a;通过深度…

深度学习图像标注工具汇总

对于监督学习算法而言&#xff0c;数据决定了任务的上限&#xff0c;而算法只是在不断逼近这个上限。世界上最遥远的距离就是我们用同一个模型&#xff0c;但是却有不同的任务。但是数据标注是个耗时耗力的工作&#xff0c;下面介绍几个图像标注工具&#xff1a; Labelme Labe…