如何使用opencv中的NCC算法实现两幅图像的相似性判断?

从来不作 2015-01-21 09:24:02
要求很简单,有两幅图像,用算法判断一下相似度,如果相似度大于某个值,则说明两幅图像为一幅图像,否则为两幅不同图像。用NCC怎么实现呢?我网上找了下NCC,说什么模板匹配。可是这个模板匹配好像是在一幅图像中找一个特征什么的,期待大家回答。
...全文
11029 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
物联网浅雾 2018-05-15
  • 打赏
  • 举报
回复 1
顺便看到了这个问题,回答一下: NCC是模板匹配,会匹配全图的每个位置,然后留下在这个位置匹配得到的相似度。 所以一般找NCC模板匹配后的极值作为两幅图最大的相似程度(可能是极大值也可能是极小值)。 matlab的函数:normxcorr2直接调用就行,然后找出最大值作为相似程度。
huokui6162 2017-08-24
  • 打赏
  • 举报
回复
你好,请问这个问题解决了吗?
shiter 2015-12-11
  • 打赏
  • 举报
回复
http://blog.csdn.net/wangyaninglm/article/details/43853435
从来不作 2015-01-22
  • 打赏
  • 举报
回复
引用 8 楼 wangyaninglm 的回复:
我想了想,ncc匹配其实也能做 不过现有的: http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/gpu/gpu-basics-similarity/gpu-basics-similarity.html?highlight=psnr 你看psnr用的比较多
如果可以,还是想使用NCC,谢谢你的回答,给我提供了备选方案
shiter 2015-01-22
  • 打赏
  • 举报
回复
我想了想,ncc匹配其实也能做 不过现有的: http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/gpu/gpu-basics-similarity/gpu-basics-similarity.html?highlight=psnr 你看psnr用的比较多
从来不作 2015-01-22
  • 打赏
  • 举报
回复
引用 6 楼 wangyaninglm 的回复:
我看过的文献中,ncc没有用到这块的好像,图片相似度我见过比较多的是PSNR
再详细些,我这里的两幅图像可以看做一台摄像机从不同角度对同一物体拍摄的两幅图像。我在网上搜索NCC,发现是可以进行图像匹配的,你看看他说的对不对http://blog.csdn.net/fengbingchun/article/details/5857810
shiter 2015-01-22
  • 打赏
  • 举报
回复
我看过的文献中,ncc没有用到这块的好像,图片相似度我见过比较多的是PSNR
从来不作 2015-01-22
  • 打赏
  • 举报
回复
重新解释一下我的需求: 我现在有两幅图像,想使用NCC匹配算法判断两者的相似度。网上搜索NCC,反馈给我的是模板匹配。我看了下模板匹配的定义,模板匹配是一项在一幅图像中寻找与另一幅模板图像最匹配(相似)部分的技术。这应该是在一幅图像中寻找感兴趣的部分,怎么用来判断两幅图像的相似度呢?NCC究竟该如何使用,期待大家的回答。最近几天一直在找资料,心好累
从来不作 2015-01-22
  • 打赏
  • 举报
回复
引用 3 楼 wangyaninglm 的回复:
ncc是用来做立体匹配的吧,图像相似检验我看一般都是其他算法,不过具体没有涉及过,我猜测的
准备用直方图匹配来做
shiter 2015-01-21
  • 打赏
  • 举报
回复
ncc是用来做立体匹配的吧,图像相似检验我看一般都是其他算法,不过具体没有涉及过,我猜测的
shiter 2015-01-21
  • 打赏
  • 举报
回复
图像相似度计算之哈希值方法OpenCV实现 分类: OpenCV Image Processing 2014-12-25 21:27 180人阅读 评论(0) 收藏 举报 感知哈希算法(perceptual hash algorithm),它的作用是对每张图像生成一个“指纹”(fingerprint)字符串,然后比较不同图像的指纹。结果越接近,就说明图像越相似。 实现步骤: 1. 缩小尺寸:将图像缩小到8*8的尺寸,总共64个像素。这一步的作用是去除图像的细节,只保留结构/明暗等基本信息,摒弃不同尺寸/比例带来的图像差异; 2. 简化色彩:将缩小后的图像,转为64级灰度,即所有像素点总共只有64种颜色; 3. 计算平均值:计算所有64个像素的灰度平均值; 4. 比较像素的灰度:将每个像素的灰度,与平均值进行比较,大于或等于平均值记为1,小于平均值记为0; 5. 计算哈希值:将上一步的比较结果,组合在一起,就构成了一个64位的整数,这就是这张图像的指纹。组合的次序并不重要,只要保证所有图像都采用同样次序就行了; 6. 得到指纹以后,就可以对比不同的图像,看看64位中有多少位是不一样的。在理论上,这等同于”汉明距离”(Hamming distance,在信息论中,两个等长字符串之间的汉明距离是两个字符串对应位置的不同字符的个数)。如果不相同的数据位数不超过5,就说明两张图像很相似;如果大于10,就说明这是两张不同的图像。 以上内容摘自:http://www.ruanyifeng.com/blog/2011/07/principle_of_similar_image_search.html 下面是用OpenCV实现的测试代码: [cpp] view plaincopyprint? string strSrcImageName = "src.jpg"; cv::Mat matSrc, matSrc1, matSrc2; matSrc = cv::imread(strSrcImageName, CV_LOAD_IMAGE_COLOR); CV_Assert(matSrc.channels() == 3); cv::resize(matSrc, matSrc1, cv::Size(357, 419), 0, 0, cv::INTER_NEAREST); //cv::flip(matSrc1, matSrc1, 1); cv::resize(matSrc, matSrc2, cv::Size(2177, 3233), 0, 0, cv::INTER_LANCZOS4); cv::Mat matDst1, matDst2; cv::resize(matSrc1, matDst1, cv::Size(8, 8), 0, 0, cv::INTER_CUBIC); cv::resize(matSrc2, matDst2, cv::Size(8, 8), 0, 0, cv::INTER_CUBIC); cv::cvtColor(matDst1, matDst1, CV_BGR2GRAY); cv::cvtColor(matDst2, matDst2, CV_BGR2GRAY); int iAvg1 = 0, iAvg2 = 0; int arr1[64], arr2[64]; for (int i = 0; i < 8; i++) { uchar* data1 = matDst1.ptr<uchar>(i); uchar* data2 = matDst2.ptr<uchar>(i); int tmp = i * 8; for (int j = 0; j < 8; j++) { int tmp1 = tmp + j; arr1[tmp1] = data1[j] / 4 * 4; arr2[tmp1] = data2[j] / 4 * 4; iAvg1 += arr1[tmp1]; iAvg2 += arr2[tmp1]; } } iAvg1 /= 64; iAvg2 /= 64; for (int i = 0; i < 64; i++) { arr1[i] = (arr1[i] >= iAvg1) ? 1 : 0; arr2[i] = (arr2[i] >= iAvg2) ? 1 : 0; } int iDiffNum = 0; for (int i = 0; i < 64; i++) if (arr1[i] != arr2[i]) ++iDiffNum; cout<<"iDiffNum = "<<iDiffNum<<endl; if (iDiffNum <= 5) cout<<"two images are very similar!"<<endl; else if (iDiffNum > 10) cout<<"they are two different images!"<<endl; else cout<<"two image are somewhat similar!"<<endl; string strSrcImageName = "src.jpg"; cv::Mat matSrc, matSrc1, matSrc2; matSrc = cv::imread(strSrcImageName, CV_LOAD_IMAGE_COLOR); CV_Assert(matSrc.channels() == 3); cv::resize(matSrc, matSrc1, cv::Size(357, 419), 0, 0, cv::INTER_NEAREST); //cv::flip(matSrc1, matSrc1, 1); cv::resize(matSrc, matSrc2, cv::Size(2177, 3233), 0, 0, cv::INTER_LANCZOS4); cv::Mat matDst1, matDst2; cv::resize(matSrc1, matDst1, cv::Size(8, 8), 0, 0, cv::INTER_CUBIC); cv::resize(matSrc2, matDst2, cv::Size(8, 8), 0, 0, cv::INTER_CUBIC); cv::cvtColor(matDst1, matDst1, CV_BGR2GRAY); cv::cvtColor(matDst2, matDst2, CV_BGR2GRAY); int iAvg1 = 0, iAvg2 = 0; int arr1[64], arr2[64]; for (int i = 0; i < 8; i++) { uchar* data1 = matDst1.ptr<uchar>(i); uchar* data2 = matDst2.ptr<uchar>(i); int tmp = i * 8; for (int j = 0; j < 8; j++) { int tmp1 = tmp + j; arr1[tmp1] = data1[j] / 4 * 4; arr2[tmp1] = data2[j] / 4 * 4; iAvg1 += arr1[tmp1]; iAvg2 += arr2[tmp1]; } } iAvg1 /= 64; iAvg2 /= 64; for (int i = 0; i < 64; i++) { arr1[i] = (arr1[i] >= iAvg1) ? 1 : 0; arr2[i] = (arr2[i] >= iAvg2) ? 1 : 0; } int iDiffNum = 0; for (int i = 0; i < 64; i++) if (arr1[i] != arr2[i]) ++iDiffNum; cout<<"iDiffNum = "<<iDiffNum<<endl; if (iDiffNum <= 5) cout<<"two images are very similar!"<<endl; else if (iDiffNum > 10) cout<<"they are two different images!"<<endl; else cout<<"two image are somewhat similar!"<<endl;
shiter 2015-01-21
  • 打赏
  • 举报
回复
Normalized Cross correlation (NCC) NCC(u,v) = [(wl - w)/(|wl - w|)]*[(wr - w)/(|wr - w|)] 选择最大值

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧