【问题标题】:Comparing pictures using Android - OpenCV使用 Android 比较图片 - OpenCV
【发布时间】:2023-03-20 06:03:01
【问题描述】:

我想比较两张图片的相似度 代码:

Mat mat1=Highgui.imread("/mnt/sdcard/91.png");
Mat mat2=Highgui.imread("/mnt/sdcard/92.png");
double distance = Imgproc.compareHist(mat1, mat2, Imgproc.CV_COMP_CORREL); //(this line throws an exception)

异常信息:

01-30 10:48:20.203:E/AndroidRuntime(3540):原因:CvException [org.opencv.core.CvException: /home/andreyk/OpenCV2/trunk/opencv/modules/imgproc/src/histogram.cpp:1387: 错误:(-215) H1.type() == H2.type() && H1.type() == CV_32F in 函数双 cv::compareHist(const cv::_InputArray&, const cv::_InputArray&, int)

有人可以帮助我吗?我该如何解决这个问题?

【问题讨论】:

    标签: android opencv compare histogram


    【解决方案1】:

    首先确保两个图像都有 1 个通道(如果没有,则使用 cvtColor 将它们转换为灰度或使用 cvSplit 选择一个通道)并具有一种类型,例如 CV_8UC1。

    然后计算这些图像的直方图。 代码示例:

    int histSize = 180;
    float range[] = {0, 180};
    const float* histRange = {range};
    bool uniform = true;
    bool accumulate = false;
    cv::Mat hist1, hist2;
    cv::calcHist(&mat1, 1, 0, cv::Mat(), hist1, 1, &histSize, &histRange, uniform, accumulate );
    cv::calcHist(&mat2, 1, 0, cv::Mat(), hist2, 1, &histSize, &histRange, uniform, accumulate );
    
    double result = cv::compareHist( hist1, hist2, CV_COMP_CORREL); 
    

    【讨论】:

    • 感谢您的帮助,Ann Orlova
    • 谢谢你的帮助 Ann Orlova。但我还是有点困惑,因为我使用 java 开发。如何使用 cvtColor 将它们转换为灰度?你能给我更多的代码示例吗?
    • 图像转灰度:Imgproc.cvtColor(srcImage, dstImage, Imgproc.COLOR_BGR2GRAY);
    • @AnnOrlova - Java 中的const float* histRange = {range}; 是什么?或者你能至少解释一下那条线的作用吗?
    【解决方案2】:

    在 Android 上,代码类似于:

    Mat image0 = ...; // 
    Mat image1 = ...;
    
    Mat hist0 = new Mat();
    Mat hist1 = new Mat();
    
    int hist_bins = 30;           //number of histogram bins
    int hist_range[]= {0,180};//histogram range
    MatOfFloat ranges = new MatOfFloat(0f, 256f);
    MatOfInt histSize = new MatOfInt(25);
    
    Imgproc.calcHist(Arrays.asList(image0), new MatOfInt(0), new Mat(), hist0, histSize, ranges);
    Imgproc.calcHist(Arrays.asList(image1), new MatOfInt(0), new Mat(), hist1, histSize, ranges);
    
    double res = Imgproc.compareHist(image0, image01, Imgproc.CV_COMP_CORREL);
    

    【讨论】:

      【解决方案3】:

      @skornos 你的代码是错误的。 应该是

      Mat image0 = ...; // 
      Mat image1 = ...;
      
      Mat hist0 = new Mat();
      Mat hist1 = new Mat();
      
      int hist_bins = 30;           //number of histogram bins
      int hist_range[]= {0,180};//histogram range
      MatOfFloat ranges = new MatOfFloat(0f, 256f);
      MatOfInt histSize = new MatOfInt(25);
      
      Imgproc.calcHist(Arrays.asList(image0), new MatOfInt(0), new Mat(), hist0, histSize, ranges);
      Imgproc.calcHist(Arrays.asList(image1), new MatOfInt(0), new Mat(), hist1, histSize, ranges);
      
      double res = Imgproc.compareHist(hist0, hist1, Imgproc.CV_COMP_CORREL);
      

      注意最后一行,应该是 hist0 与 hist1 比较而不是比较图像

      【讨论】:

        【解决方案4】:
              Mat hsvRef = new Mat();
              Mat hsvCard = new Mat();
        
              Mat srcRef = new Mat(refImage.getHeight(), refImage.getWidth(), CvType.CV_8UC2);
              Utils.bitmapToMat(refImage, srcRef);
        
        
              Mat srcCard = new Mat(cardImage.getHeight(), cardImage.getWidth(), CvType.CV_8UC2);
              Utils.bitmapToMat(cardImage, srcCard);
        
              /// Convert to HSV
              Imgproc.cvtColor(srcRef, hsvRef, Imgproc.COLOR_BGR2HSV);
              Imgproc.cvtColor(srcCard, hsvCard, Imgproc.COLOR_BGR2HSV);
        
              /// Using 50 bins for hue and 60 for saturation
              int hBins = 50;
              int sBins = 60;
              MatOfInt histSize = new MatOfInt( hBins,  sBins);
        
              // hue varies from 0 to 179, saturation from 0 to 255
              MatOfFloat ranges =  new MatOfFloat( 0f,180f,0f,256f );
        
              // we compute the histogram from the 0-th and 1-st channels
              MatOfInt channels = new MatOfInt(0, 1);
        
        
        
              Mat histRef = new Mat();
              Mat histCard = new Mat();
        
              ArrayList<Mat> histImages=new ArrayList<Mat>();
              histImages.add(hsvRef);
              Imgproc.calcHist(histImages,
                      channels,
                      new Mat(),
                      histRef,
                      histSize,
                      ranges,
                      false);
              Core.normalize(histRef,
                      histRef,
                      0,
                      1,
                      Core.NORM_MINMAX,
                      -1,
                      new Mat());
        
              histImages=new ArrayList<Mat>();
              histImages.add(hsvCard);
              Imgproc.calcHist(histImages,
                      channels,
                      new Mat(),
                      histCard,
                      histSize,
                      ranges,
                      false);
        
              Core.normalize(histCard,
                      histCard,
                      0,
                      1,
                      Core.NORM_MINMAX,
                      -1,
                      new Mat());
        
              double resp1 = Imgproc.compareHist(histRef, histCard, 0);
              Log.d(TAG, "HIST COMPARE 0" + resp1);
              double resp2 = Imgproc.compareHist(histRef, histCard, 1);
              Log.d(TAG, "HIST COMPARE 1" + resp2);
              double resp3 = Imgproc.compareHist(histRef, histCard, 2);
              Log.d(TAG, "HIST COMPARE 2" + resp3);
              double resp4 = Imgproc.compareHist(histRef, histCard, 3);
              Log.d(TAG, "HIST COMPARE 3" + resp4);
        

        【讨论】:

        • refImage/cardImage是什么类型的?
        • 对不起,参考图像和卡片图像是我从相机拍摄的图像。
        猜你喜欢
        • 1970-01-01
        • 2013-01-29
        • 1970-01-01
        • 2016-09-19
        • 2011-06-18
        • 1970-01-01
        • 2020-09-12
        • 2018-02-06
        相关资源
        最近更新 更多