Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/184.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android中的OpenCV图像比较_Android_Opencv_Feature Detection_Surf_Image Comparison - Fatal编程技术网

Android中的OpenCV图像比较

Android中的OpenCV图像比较,android,opencv,feature-detection,surf,image-comparison,Android,Opencv,Feature Detection,Surf,Image Comparison,[编辑] 我设计了一些图像比较代码。匹配的部分仍然有点缺陷,我希望得到一些帮助。该项目可在- 我有两张图像Img1和Img2: 当我在openCV中使用以下命令时 Mat img1 = Highgui.imread("mnt/sdcard/IMG-20121228.jpg"); Mat img2 = Highgui.imread("mnt/sdcard/IMG-20121228-1.jpg"); try{ double l2_norm = Core.norm( img1, img2

[编辑] 我设计了一些图像比较代码。匹配的部分仍然有点缺陷,我希望得到一些帮助。该项目可在-

我有两张图像Img1和Img2:

当我在openCV中使用以下命令时

Mat img1 = Highgui.imread("mnt/sdcard/IMG-20121228.jpg");
Mat img2 = Highgui.imread("mnt/sdcard/IMG-20121228-1.jpg");

try{
    double l2_norm = Core.norm( img1, img2 );
    tv.setText(l2_norm+"");
} catch(Exception e) {
    //image is not a duplicate
}
我得到l2_范数的一个双值。此双精度值因重复图像对而异。但如果图像不同,则会引发异常。这就是我识别重复图像的方法吗?还是有更好的方法?我在谷歌上搜索了很多遍,没有找到一个真正令人信服的答案。我想知道如何比较两幅图像并根据图像得到
true
false
的布尔值的代码和说明

编辑

我已经试过了,但是
if
条件从未满足过。我假设存在一些差异,但是对于
标量
,没有
比较
函数。我该怎么办

编辑

这种方法又有缺陷。虽然它可以用来比较图像,精度相当高,但当图像大小不同时,它就失败了

当图像大小不同且我打印标量值时,我得到以下结果:

[9768383.0,1.0052889E7,1.0381814E7,0.0][1.5897384E7,1.6322252E7,1.690251E7,0.0]

第二个数字和第三个数字之间的差异虽然不大,但与比较相同大小的图像时的差异相当大。然而,第一个数字变化最大

比较两幅图像内容的最快方法是什么

[编辑]

我正在使用我找到的代码

我不知道如何初始化
MatOfKeyPoint
变量
keypoints
logoKeypoints
。以下是我的代码片段:

           FeatureDetector detector = FeatureDetector.create(FeatureDetector.SURF);
        //FeatureDetector detector = FeatureDetector.create(FeatureDetector.FAST);
        //Imgproc.cvtColor(img1, img1, Imgproc.COLOR_RGBA2RGB);
        //Imgproc.cvtColor(img2, img2, Imgproc.COLOR_RGBA2RGB);

        DescriptorExtractor SurfExtractor = DescriptorExtractor
        .create(DescriptorExtractor.SURF);


        //extract keypoints
        MatOfKeyPoint keypoints, logoKeypoints;
        long time= System.currentTimeMillis();
        detector.detect(img1, keypoints);
        Log.d("LOG!", "number of query Keypoints= " + keypoints.size());
        detector.detect(img2, logoKeypoints);
        Log.d("LOG!", "number of logo Keypoints= " + logoKeypoints.size());
        Log.d("LOG!", "keypoint calculation time elapsed" + (System.currentTimeMillis() -time));

        //Descript keypoints
        long time2 = System.currentTimeMillis();
        Mat descriptors = new Mat();
        Mat logoDescriptors = new Mat();
        Log.d("LOG!", "logo type" + img2.type() + "  intype" + img1.type());
        SurfExtractor.compute(img1, keypoints, descriptors);
        SurfExtractor.compute(img2, logoKeypoints, logoDescriptors);
        Log.d("LOG!", "Description time elapsed" + (System.currentTimeMillis()- time2));

显然,我无法将变量
关键点
logoKeypoints
初始化为null,因为我将收到null指针异常。如何初始化它们?

使用
cv2.absDiff
计算图片之间的差异,使用
cv2.sumElems
计算所有像素差异之和


然后发明一个阈值来判断两幅图像是否相似。

你应该明白这不是一个简单的问题,你可以遵循不同的概念。我将只指出两个没有源代码的解决方案

  • 直方图比较:您可以将两幅图像转换为灰度,生成范围为[0,…,255]的直方图。每个像素值都将被计数。然后使用两个直方图进行比较。如果像素强度的分布等于或高于某个tRESHOLD(可能是所有像素的90%),则可以将该图像视为重复。但是:这是最简单的解决方案之一,如果任何图片具有相等的分布,那么它就不稳定
  • 兴趣点检测器/描述符:查看SIFT/SURF图像检测器和描述符。探测器将尝试确定图像中强度的唯一关键点。将在该位置I(x,y)处计算描述符。使用bruteforce方法和欧氏距离的法线匹配器可以使用描述符匹配这些图像。如果图像是重复的,则给定匹配的比率应该非常高。这个解决方案很好实现,关于这个主题可能有足够多的教程
  • 我希望这有帮助。如果你有问题,请提问

    [UPDATE-1] C++教程:

    一些JavaCV教程:

    [UPDATE-2] 下面是一个使用默认参数的SIFT检测器和SIFT描述符的示例。单应性的RANSAC阈值为65,重投影误差(ε)为10,启用交叉验证。你可以试着数一数匹配的数字。如果内联异常值比率太高,则可以将此对视为重复项。 例如:这些图像在IMG1中生成180个关键点,在IMG2中生成198个关键点。匹配的描述符有163个,其中只有3个是异常值。所以这给出了一个很好的比率,这只意味着这些图像可能是重复的

    [UPDATE-3] 我不明白你为什么可以初始化MatOfKeypoints。还有一个公共构造函数。而且:你可以使用你想要分析的图像的垫子。这很好


    要匹配,请使用原因,您需要SURF或SIFT的欧几里德距离。

    您可以尝试以下代码:

    Mat img1 = Highgui.imread("mnt/sdcard/IMG-20121228.jpg");
    Mat img2 = Highgui.imread("mnt/sdcard/IMG-20121228-1.jpg");
    Mat result = new Mat();
    
    Core.compare(img1,img2,result,Core.CMP_NE);
    
    int val = Core.countNonZero(result);
    
    if(val == 0) {
        //Duplicate Image
    } else {
        //Different Image
    }
    
    在这里,代码比较函数将比较两个图像,如果图像之间存在不相似性,则特定矩阵值将为255,所有其他值将为零。然后可以计算非零值的数量,以确定图像是否相等。这只适用于完全相同的图像

    如果要比较忽略灯光效果的图像,我建议您先生成边缘图像(使用OpenCV的canny函数),然后比较图像


    希望这个答案能帮助你

    本OpenCV教程希望提供有关该主题的一些信息。试抓和其他的不一样!如果抛出异常(catch block),则会出现完全错误的情况@卫星D-我知道。这就是为什么我问是否有更好的方法。我不相信你需要,MatofKeypoints,logoKeypoints;很好。方法检测器。检测(img1,关键点);然后将使用找到的特征填充关键点。否则,请尝试MatofKeypoints=new MatOfKeyPoint()@Emile你能为图像关键点比较提供正确的代码吗?你能解释一下吗?我必须为absDiff设置一个阈值。所以,这是有缺陷的。或者您可以告诉我最安全的阈值是什么?首先,很抱歉您必须使用cv.sum,因为sumelems似乎只是python。其次,需要sum返回值的阈值!您可以将其包装在一个方法中,该方法根据sum的返回值返回true或false
               FeatureDetector detector = FeatureDetector.create(FeatureDetector.SURF);
            //FeatureDetector detector = FeatureDetector.create(FeatureDetector.FAST);
            //Imgproc.cvtColor(img1, img1, Imgproc.COLOR_RGBA2RGB);
            //Imgproc.cvtColor(img2, img2, Imgproc.COLOR_RGBA2RGB);
    
            DescriptorExtractor SurfExtractor = DescriptorExtractor
            .create(DescriptorExtractor.SURF);
    
    
            //extract keypoints
            MatOfKeyPoint keypoints, logoKeypoints;
            long time= System.currentTimeMillis();
            detector.detect(img1, keypoints);
            Log.d("LOG!", "number of query Keypoints= " + keypoints.size());
            detector.detect(img2, logoKeypoints);
            Log.d("LOG!", "number of logo Keypoints= " + logoKeypoints.size());
            Log.d("LOG!", "keypoint calculation time elapsed" + (System.currentTimeMillis() -time));
    
            //Descript keypoints
            long time2 = System.currentTimeMillis();
            Mat descriptors = new Mat();
            Mat logoDescriptors = new Mat();
            Log.d("LOG!", "logo type" + img2.type() + "  intype" + img1.type());
            SurfExtractor.compute(img1, keypoints, descriptors);
            SurfExtractor.compute(img2, logoKeypoints, logoDescriptors);
            Log.d("LOG!", "Description time elapsed" + (System.currentTimeMillis()- time2));
    
    MatOfKeyPoint reference = new MatOfKeyPoint(matOfReferenceImage);
    
    Mat img1 = Highgui.imread("mnt/sdcard/IMG-20121228.jpg");
    Mat img2 = Highgui.imread("mnt/sdcard/IMG-20121228-1.jpg");
    Mat result = new Mat();
    
    Core.compare(img1,img2,result,Core.CMP_NE);
    
    int val = Core.countNonZero(result);
    
    if(val == 0) {
        //Duplicate Image
    } else {
        //Different Image
    }