匹配openCV中最接近的图像?

Posted

技术标签:

【中文标题】匹配openCV中最接近的图像?【英文标题】:Matching closest image in openCV? 【发布时间】:2014-08-27 13:28:39 【问题描述】:

这就是我遇到的困境。对于我的应用程序,我需要在一组图像中将图像 L1 与匹配的 L2 匹配。 L1L2 是完全相同的图像,除了 L1 小得多(它需要高档吗?),并且可以被人为边缘很少,但尽管如此,它们来自完全相同的源图像。颜色确实很重要,因为使用颜色信息将消除当前图像与要匹配的图像之间可能存在的歧义。使用 OpenCV(或者可能有更好的选择?),找到匹配图像的最佳方法是什么(L2)。

重申一下,要匹配的图像无论如何都不会旋转或扭曲,只会调整大小。

我想会有一个函数来评估要匹配的图像与所提供集合中的所有图像的接近程度。然后我们选择评分最高的那个作为匹配。我不确定如何比较图像。任何帮助都会很棒。谢谢。

【问题讨论】:

如果它们真的是完全相同的图像(除了缩放和一些伪影),我想首先将 L2 缩小到 L1 的大小,即计算 cv::absDiff。在这种情况下,具有最低平均像素差(L2 范数)的图像应该是您最相似的图像。 【参考方案1】:

前往 github 并查看 opencv-master\samples\cpp\matcher_simple.cpp(或 matching_to_many_images.cpp)

它不仅可以满足您的需求,而且还适用于具有透视失真的图像(例如旋转、仿射变换和照明变化)。简而言之,它非常强大。

但 SIFT 和 SURF 已获得专利,您可能无法将其用于商业应用,这很糟糕。但是有很多选择,只是谷歌周围!

【讨论】:

如果它们已获得专利,您甚至不能将它们用于研究或开源,除非您获得专利持有人的明确许可。幸运的是;这些专利仅存在于美国。 @Nallath 我相信你只需要引用他们的论文来进行研究。只是不要使用他们的代码并购买 matlab 或其他东西 这将取决于他们发布它的许可证。他们甚至可以(如果他们愿意的话)阻止您对该领域进行研究。【参考方案2】:

OpenCV 有a tutorial on similarity measurement for images。

在进行比较之前,您需要放大 L1,或缩小 L2。如果您将 L2 与大量图像进行比较,缩小 L2 可能更有意义(因为您不必为每个要比较的图像调用 resize,并且要比较的像素更少)。

例如

cv::Mat L1 = ...;
cv::Mat L2 = ...;

cv::Mat L2small;
cv::resize(L2, L2small, L1.size());
double pnsr = getPSNR(L1, L2small);
// where code for getPSNR() is in the tutorial

【讨论】:

【参考方案3】:

我认为您可以使用类似于用于测量文档相似度的词袋模型的东西。看看这个:link

我正在重现下面的等式:

G = X'*X

其中 X = [x1 x2 ... xn]

在您的情况下,使用图像的标准化直方图作为向量 xi。

我认为您不必在这种方法中调整图像大小,而且会更快。

编辑

我在 Matlab 中使用 opencv 示例中提供的一些示例图像进行了尝试:

im1 = imread('baboon.jpg');
im2 = imread('board.jpg');
im3 = imread('fruits.jpg');
im4 = imread('fruits - small.jpg'); % fruits.jpg scaled down 25% using mspaint

% using grayscale for simplicity
gr1 = rgb2gray(im1);
gr2 = rgb2gray(im2);
gr3 = rgb2gray(im3);
gr4 = rgb2gray(im4);

[cnt_baboon, x] = imhist(gr1);
[cnt_board, x] = imhist(gr2);
[cnt_fruits, x] = imhist(gr3);
[cnt_fruits_small, x] = imhist(gr4);

% X: not normalized
X = [cnt_baboon cnt_board cnt_fruits cnt_fruits_small];
H = X'*X;
N = sqrt(diag(H)*diag(H)');
% normalize. this would be faster
G = H./N

生成的 G 矩阵:

G =

1.0000    0.8460    0.7748    0.7729
0.8460    1.0000    0.8741    0.8686
0.7748    0.8741    1.0000    0.9947
0.7729    0.8686    0.9947    1.0000

您可以看到 G(3,4)(和 G(4,3))非常接近 1。

【讨论】:

【参考方案4】:

我认为您正在寻找直方图匹配。有用于直方图匹配的内置函数,例如 bhattacharya 距离等,它们并不要求您的两个图像也具有相同的大小。

只需在 opencv 网站上查看此链接, link

【讨论】:

以上是关于匹配openCV中最接近的图像?的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV 查找图像的紧密匹配

Python+OpenCV图像处理—— 模板匹配

Python+OpenCV图像处理—— 模板匹配

opencv图像匹配常用特征点

Opencv模板匹配

将图像放入轮廓(OpenCV)