【问题标题】:Image comparison algorithm for finding the most similar image in a set图像比较算法,用于在一组中找到最相似的图像
【发布时间】:2016-05-11 03:54:24
【问题描述】:

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

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

【问题讨论】:

    标签: image algorithm image-processing computer-vision


    【解决方案1】:

    关键点提取和匹配是该问题的解决方案之一。 使用一些特征检测器如 SIFT、SURF、Fast-To-Track 等,在原始图像和其他图像上提取关键点。近年来,SIFT检测器因其准确性和效率而受到广泛欢迎并得到很大改进。

    之后,通过 Ransac 算法或其他算法匹配特征...

    匹配图像可以由多个真正的匹配点来定义。

    可以参考OpenCV中的关键点算法: 接口: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

    【讨论】:

      【解决方案2】:
      • 一种可能的方法是感知散列,它非常健壮并且可以调整。 Survey paper link

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

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

      前段时间我implemented 一个简单的感知帧哈希示例(基于像素统计,而不是特征)。在“深入”(CNN)之前,我会先尝试这样的事情:-)

      还有查询过程的问题。虽然我不记得我的方法的哈希属性(也许位错误的度量就足够了),但幻灯片中的深度学习尝试保留相似性,以便您在查询时可以获得距离/排名。

      【讨论】:

        【解决方案3】:

        如果你想解决水印攻击,我会推荐你​​图像哈希算法,它们对这种攻击快速且健壮。让我给你举几个例子

        #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,都通过了。

        这个小程序比较原图(左)和他们的水印兄弟(右),compute show的值越小,图像越相似。对于AverageHash,推荐阈值为5(即如果比较结果大于5,则认为图像差异很大)。

        不仅是水印,AverageHash 还提供了另一个“副作用”,该算法在对比度、噪声(高斯、胡椒和盐)、调整大小和 jpeg 压缩攻击下也有效。

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

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

        【讨论】:

          【解决方案4】:

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

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

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

          【讨论】:

            猜你喜欢
            • 2015-12-11
            • 1970-01-01
            • 2011-08-09
            • 2012-01-28
            • 2012-12-12
            • 2010-09-09
            • 1970-01-01
            • 2015-02-19
            • 2010-12-21
            相关资源
            最近更新 更多