用于在一组中找到最相似图像的图像比较算法

时间:2016-05-11 03:54:25

标签: image algorithm image-processing computer-vision

是否有算法可以将一个图像作为输入,将一个图像列表作为第二个输入,并告诉哪一个最相似?在我们的问题中,由于水印,我们可以得到相同的购买看起来不同的图像。因此,即使水印不同,我们也需要识别匹配的图像。

神经网络是否用于此?有特定的算法吗?

4 个答案:

答案 0 :(得分:2)

关键点提取和匹配是此问题的解决方案之一。 使用一些特征检测器作为SIFT,SURF,Fast-To-Track,...来提取原始图像和其他图像上的关键点。在这些日子里,SIFT探测器变得普及并且因为其准确性和效率而得到了很大改进。

之后,功能由Ransac算法或其他人匹配......

匹配图像可以由许多真实匹配点定义。

可以在OpenCV中引用关键点算法: API:http://docs.opencv.org/2.4/modules/refman.html 例如:http://docs.opencv.org/2.4/doc/tutorials/features2d/table_of_content_features2d/table_of_content_features2d.html#table-of-content-feature2d

答案 1 :(得分:1)

  • 一种可能的方法是感知哈希,它非常强大且可以调整。 Survey paper link

  • 当然,这也可以通过深度学习完成,但这需要更多的工作。 Slides

始终需要定义您的问题设置。是否有像素相等的结果(甚至是像素工作的经典散列);有不同的压缩(需要坚固性);有颜色变换甚至几何变换(如旋转);大小changings ... 经典的感知哈希算法非常强大,即使对于适度的变换也是如此。

前段时间我implemented一个感知框架哈希的简单示例(基于像素统计,而不是功能)。我会先尝试这样的事情,然后再深入了解#34; (CNNs): - )

还有查询过程的问题。虽然我不记得我的方法的哈希属性(可能是比特错误的度量标准就足够了),但幻灯片中的深度学习方法试图保持相似性,这样你就可以获得距离/排名查询。

答案 2 :(得分:0)

最简单的方法是注册(对齐)(对于Matlab和OpenCV都存在ECC注册),您可以设计自己的方法来为此创建方案。

更好的方法是使用Matlab中的MSER或FAST功能。使用他们的文档,他们确实按照你的要求做。

PS:在Matlab 2015b中有一个内置级联训练器,可以满足您的要求。拍摄参考图像,询问没有参考图像的背景和WALLA你有自己的级联分类器准备好,在闲暇时使用它来分类图像左右,侧面和底部,儿子。

答案 3 :(得分:0)

如果你想解决水印攻击,我会建议你使用图像哈希算法,它们对这种攻击很快且很健壮。让我给你看一些例子

origin 00 watermark 00 origin 01 watermark 01 origin 02 watermark 02 origin 03 watermark 03

#include <opencv2/core.hpp>
#include <opencv2/core/ocl.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/img_hash.hpp>
#include <opencv2/imgproc.hpp>

#include <iostream>       

void watermark_attack(cv::Ptr<cv::img_hash::ImgHashBase> algo)
{
    std::vector<std::string> const origin_img
    {
        "origin_00.png", "origin_01.png",
        "origin_02.png", "origin_03.png"
    };
    std::vector<std::string> const watermark_img
    {
        "watermark_00.png", "watermark_01.png",
        "watermark_02.png", "watermark_03.png"
    };

    cv::Mat origin_hash, watermark_hash;
    for(size_t i = 0; i != origin_img.size(); ++i){
        cv::Mat const input = cv::imread(origin_img[i]);
        cv::Mat const watermark_input = cv::imread(watermark_img[i]);
        //compute the hash value of image without watermark
        algo->compute(input, origin_hash);
        //compute the hash value of image with watermark  
        algo->compute(watermark_input, watermark_hash);
        //compare the different between the hash values
        //of original image and watermark image
        std::cout<<algo->compare(origin_hash, watermark_hash)
                <<std::endl;
    }    
}

int main()
{
    using namespace cv::img_hash;

    //disable opencl acceleration may(or may not) boost up speed of img_hash
    cv::ocl::setUseOpenCL(false);

    watermark_attack(AverageHash::create());          
}

结果是1,2,1,2,全部通过。

这个小程序将原始图像(左)与其水印兄弟(右)进行比较,计算显示的值越小,图像越相似。对于AverageHash的情况,建议阈值为5(这意味着如果比较结果大于5,则认为图像非常不同)。

不仅水印,AverageHash还提供了另外的副作用,这个算法在对比度,噪音(高斯,胡椒和盐),调整大小和jpeg压缩攻击下工作。

使用图像哈希的另一个好处是,您可以将图像的哈希值存储在文件中,您无需一次又一次地计算哈希值。

Simple and fast method to compare images for similarity会显示有关opencv的img_hash模块的更多详细信息。