Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.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
Opencv 查找两个图像是否相似_Opencv_Image Processing - Fatal编程技术网

Opencv 查找两个图像是否相似

Opencv 查找两个图像是否相似,opencv,image-processing,Opencv,Image Processing,我试图通过图像匹配发现两幅图像与openCV相似。我正在运行以下代码: public static void match(String firstImage, String secondImage, String outputFile) { FeatureDetector detector = FeatureDetector.create(FeatureDetector.ORB); DescriptorExtractor descriptor = DescriptorExtra

我试图通过图像匹配发现两幅图像与openCV相似。我正在运行以下代码:

public static void match(String firstImage, String secondImage, String outputFile) {

    FeatureDetector detector = FeatureDetector.create(FeatureDetector.ORB);
    DescriptorExtractor descriptor = DescriptorExtractor.create(DescriptorExtractor.ORB);
    DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);


    Mat firstImg = Imgcodecs.imread(firstImage, Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);
    MatOfKeyPoint firstKeypoints = new MatOfKeyPoint();
    Mat firstDescriptors = new Mat();
    detector.detect(firstImg, firstKeypoints);
    descriptor.compute(firstImg, firstKeypoints, firstDescriptors);

    Mat secondImg = Imgcodecs.imread(secondImage,      Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);
    MatOfKeyPoint secondKeypoints = new MatOfKeyPoint();
    Mat secondDescriptors = new Mat();
    detector.detect(secondImg, secondKeypoints);
    descriptor.compute(secondImg, secondKeypoints, secondDescriptors);

    MatOfDMatch matches = new MatOfDMatch();
    matcher.match(firstDescriptors, secondDescriptors, matches);

    float minDis = Float.MAX_VALUE;
    for (int i = 0;i < matches.rows();i++) {
        if (matches.toArray()[i].distance < minDis)
            minDis = matches.toArray()[i].distance;
    }
    LinkedList<DMatch> goodMatches = new LinkedList<>();
    for (int i = 0;i < matches.rows();i++) {
        if (matches.toArray()[i].distance < minDis*3)
            goodMatches.add(matches.toArray()[i]);
    }


    List<Point> pts1 = new ArrayList<Point>();
    List<Point> pts2 = new ArrayList<Point>();
    for(int i = 0; i<goodMatches.size(); i++){
        pts1.add(firstKeypoints.toList().get(goodMatches.get(i).queryIdx).pt);
        pts2.add(secondKeypoints.toList().get(goodMatches.get(i).trainIdx).pt);
    }

    // convertion of data types - there is maybe a more beautiful way
    Mat outputMask = new Mat();
    MatOfPoint2f pts1Mat = new MatOfPoint2f();
    pts1Mat.fromList(pts1);
    MatOfPoint2f pts2Mat = new MatOfPoint2f();
    pts2Mat.fromList(pts2);

    Calib3d.findHomography(pts1Mat, pts2Mat, Calib3d.RANSAC, 15, outputMask, 2000, 0.995);

    // outputMask contains zeros and ones indicating which matches are filtered
    LinkedList<DMatch> betterMatches = new LinkedList<DMatch>();
    for (int i = 0; i < goodMatches.size(); i++) {
        if (outputMask.get(i, 0)[0] != 0.0) {
            betterMatches.add(goodMatches.get(i));
        }
    }

    Mat outputImg = new Mat();
    MatOfDMatch betterMatchesMat = new MatOfDMatch();
    betterMatchesMat.fromList(betterMatches);
    Features2d.drawMatches(firstImg, firstKeypoints, secondImg, secondKeypoints, betterMatchesMat, outputImg);
    Imgcodecs.imwrite(outputFile, outputImg);
}
publicstaticvoidmatch(stringfirstimage、stringsecondimage、stringoutputfile){
FeatureDetector=FeatureDetector.create(FeatureDetector.ORB);
DescriptorExtractor descriptor=DescriptorExtractor.create(DescriptorExtractor.ORB);
DescriptorMatcher matcher=DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);
Mat firstImg=Imgcodecs.imread(firstImage,Imgcodecs.CV\u LOAD\u IMAGE\u GRAYSCALE);
MatOfKeyPoint firstKeypoints=新的MatOfKeyPoint();
Mat firstDescriptors=新Mat();
检测器。检测(第一个img、第一个关键点);
compute(firstImg、firstKeypoints、firstdescriptor);
Mat secondImg=Imgcodecs.imread(secondImage,Imgcodecs.CV\u LOAD\u IMAGE\u GRAYSCALE);
MatOfKeyPoint secondKeypoints=新的MatOfKeyPoint();
Mat secondDescriptors=新Mat();
检测器。检测(第二个IMG、第二个关键点);
compute(secondImg、secondKeypoints、seconddescriptor);
MatOfDMatch matches=新的MatOfDMatch();
匹配(第一个描述符,第二个描述符,匹配);
float minDis=float.MAX_值;
for(int i=0;i对于(int i=0;i,用外行术语来说,相关性决定了两个变量/数据集/等之间的线性关系。这种关系可能是正线性的,也可能是负线性的。皮尔逊R是求取两个变量之间相关系数的常用方法

皮尔逊R的结果介于
-1
+1
之间

  • -1
    ->彼此之间高度非线性
  • +1
    ->彼此高度线性
这是说明两个变量的相似性或不同性的数值方法

在这种情况下,我假设灰度图像是两个变量。在计算它之前,我将图像展平为一维数组

Pearson的R可以通过使用scipy库(在Python中)来确定

要获取有关pearsonr及其返回类型的更多信息,请选中

因此,我使用python计算了所有三个图像的皮尔逊R,并将它们相互关联

这就是我得到的:

  • 对于前两个图像:
    (0.62908215058685268,0.0)
  • 对于第二个和第三个图像:
    (-0.34523397781005682,0.0)
  • 对于第一个和第三个图像:
    (-0.36356339857880066,0.0)
因此,我们可以说(在数字/统计方面)前两张图片有些相似(考虑到一张有手提包,另一张没有)


如果对两幅相同的图像执行Pearson's R,您将获得1的结果,用于检查相似图像的两个透视图之间单应矩阵的适当性,我编写了此函数。您可以从各种可能性中选择您喜欢的,这取决于您认为哪一个更合适:

 private static boolean check_homography(Mat homography_mat){
    /* Check 1. Compute the determinant of the homography, and see if it's too close 
     to zero for comfort*/
    if(!homography_mat.empty())
    {
        double Determinant = Core.determinant(homography_mat);
        if (Determinant > 0.1)
            return true;
        else 
            return false;
    }
    else 
        return false;

    /* Check 2. Compute its SVD, and verify that the ratio of the first-to-last 
     singular value is not too high (order of 1.0E7). */   
    Mat singularValues = new Mat();
    Core.SVDecomp(homography_mat, singularValues, new Mat(), new Mat(), Core.SVD_NO_UV);

    System.out.print("\n Printing the singular values of the homography");
    for (int i = 0; i < singularValues.rows(); i++){
        for ( int j = 0; j < singularValues.cols(); j++){
            System.out.print("\n Element at ( " + i + ", " + j + " ) is " + singularValues.get(i, j)[0]);
        }
    }
    double conditionNumber = singularValues.get(0, 0)[0] / singularValues.get(2, 0)[0];
    System.out.print("\n Condition number is : " + conditionNumber);

    if(conditionNumber < Math.pow(10, 7)){
        System.out.print("\n Homography matrix is non-singular");
        return true;
        }
    else{
        System.out.print("\n Homography matrix is singular (or very close)");
        return false;
        }
    /* Check 3. Check the compare absolute values at (0,0) and (0,1) with (1,1) and (1,0) 
     * respectively. If the two differences are close to 0, the homography matrix is 
     * good. (This just takes of rotation and not translation)
     * */
    if(Math.abs((Math.abs(homography_mat.get(0, 0)[0]) - Math.abs(homography_mat.get(1, 1)[0]))) <= 0.1){
        if(Math.abs((Math.abs(homography_mat.get(0, 1)[0]) - Math.abs(homography_mat.get(1, 0)[0]))) <= 0.1){
            System.out.print("\n The homography matrix is good");
            return true;
        }
    }
        else{
            System.out.print("\n The homography matrix is bad");
            return false;
        }
    return false;
    /*
     * Check 4: If the determinant of the top-left 2 by 2 matrix (rotation) > 0, transformation is orientation
     * preserving.
     * Else if the determinant is < 0, it is orientation reversing
     * 
     * */
     Determinant of the rotation mat
    double det = homography_mat.get(0, 0)[0] * homography_mat.get(1,1)[0] - homography_mat.get(0, 1)[0] * homography_mat.get(1, 0)[0];
    if (det < 0)
        return false;

    double N1 = Math.sqrt(homography_mat.get(0, 0)[0] * homography_mat.get(0, 0)[0] + homography_mat.get(1, 0)[0] * homography_mat.get(1, 0)[0]);
    if (N1 > 4 || N1 < 0.1)
        return false;

    double N2 = Math.sqrt(homography_mat.get(0, 1)[0] * homography_mat.get(0, 1)[0] + homography_mat.get(1, 1)[0] * homography_mat.get(1, 1)[0]);
    if (N2 > 4 || N2 < 0.1)
        return false;

    double N3 = Math.sqrt(homography_mat.get(2, 0)[0] * homography_mat.get(2, 0)[0] + homography_mat.get(2,1)[0] * homography_mat.get(2, 1)[0]);
    if (N3 < 0.002)
        return false;

    return true;

}
private静态布尔检查单应(Mat单应){
/*检查1.计算单应性的行列式,看它是否太接近
为了舒适而归零*/
if(!homography_mat.empty())
{
双行列式=核心行列式(单应矩阵);
如果(行列式>0.1)
返回true;
其他的
返回false;
}
其他的
返回false;
/*检查2.计算其SVD,并验证第一个与最后一个的比率
奇异值不太高(阶数为1.0E7)。*/
Mat singularValues=新Mat();
SVDecomp(单应矩阵,奇异值,new mat(),new mat(),Core.SVD_NO_UV);
System.out.print(“\n打印单应性的奇异值”);
对于(int i=0;i4 | | N2<0.1)
返回false;
double N3=数学sqrt(单应矩阵get(2,0)[0]*单应矩阵get(2,0)[0]+单应矩阵get(2,1)[0]*单应矩阵get(2,1)[0]);
如果(N3<0.002)
返回false;
返回true;
}
注意-我在使用ORB时为Java、OpenCV编写了此代码。我个人(我想我有经验)可以查看单应矩阵,或多或少地说它是好是坏,因此检查1。希望有帮助

编辑 此外,正如@Mika提到的
 private static boolean check_homography(Mat homography_mat){
    /* Check 1. Compute the determinant of the homography, and see if it's too close 
     to zero for comfort*/
    if(!homography_mat.empty())
    {
        double Determinant = Core.determinant(homography_mat);
        if (Determinant > 0.1)
            return true;
        else 
            return false;
    }
    else 
        return false;

    /* Check 2. Compute its SVD, and verify that the ratio of the first-to-last 
     singular value is not too high (order of 1.0E7). */   
    Mat singularValues = new Mat();
    Core.SVDecomp(homography_mat, singularValues, new Mat(), new Mat(), Core.SVD_NO_UV);

    System.out.print("\n Printing the singular values of the homography");
    for (int i = 0; i < singularValues.rows(); i++){
        for ( int j = 0; j < singularValues.cols(); j++){
            System.out.print("\n Element at ( " + i + ", " + j + " ) is " + singularValues.get(i, j)[0]);
        }
    }
    double conditionNumber = singularValues.get(0, 0)[0] / singularValues.get(2, 0)[0];
    System.out.print("\n Condition number is : " + conditionNumber);

    if(conditionNumber < Math.pow(10, 7)){
        System.out.print("\n Homography matrix is non-singular");
        return true;
        }
    else{
        System.out.print("\n Homography matrix is singular (or very close)");
        return false;
        }
    /* Check 3. Check the compare absolute values at (0,0) and (0,1) with (1,1) and (1,0) 
     * respectively. If the two differences are close to 0, the homography matrix is 
     * good. (This just takes of rotation and not translation)
     * */
    if(Math.abs((Math.abs(homography_mat.get(0, 0)[0]) - Math.abs(homography_mat.get(1, 1)[0]))) <= 0.1){
        if(Math.abs((Math.abs(homography_mat.get(0, 1)[0]) - Math.abs(homography_mat.get(1, 0)[0]))) <= 0.1){
            System.out.print("\n The homography matrix is good");
            return true;
        }
    }
        else{
            System.out.print("\n The homography matrix is bad");
            return false;
        }
    return false;
    /*
     * Check 4: If the determinant of the top-left 2 by 2 matrix (rotation) > 0, transformation is orientation
     * preserving.
     * Else if the determinant is < 0, it is orientation reversing
     * 
     * */
     Determinant of the rotation mat
    double det = homography_mat.get(0, 0)[0] * homography_mat.get(1,1)[0] - homography_mat.get(0, 1)[0] * homography_mat.get(1, 0)[0];
    if (det < 0)
        return false;

    double N1 = Math.sqrt(homography_mat.get(0, 0)[0] * homography_mat.get(0, 0)[0] + homography_mat.get(1, 0)[0] * homography_mat.get(1, 0)[0]);
    if (N1 > 4 || N1 < 0.1)
        return false;

    double N2 = Math.sqrt(homography_mat.get(0, 1)[0] * homography_mat.get(0, 1)[0] + homography_mat.get(1, 1)[0] * homography_mat.get(1, 1)[0]);
    if (N2 > 4 || N2 < 0.1)
        return false;

    double N3 = Math.sqrt(homography_mat.get(2, 0)[0] * homography_mat.get(2, 0)[0] + homography_mat.get(2,1)[0] * homography_mat.get(2, 1)[0]);
    if (N3 < 0.002)
        return false;

    return true;

}