2015-03-23 2 views
5

В настоящее время я использую OpenCV для сравнения двух изображений, чтобы узнать, похожи они или нет в Android. Я использую ORB Feature Detectors и Descriptor Extractors. Вот что я до сих пор. Я нахожу все ключевые моменты функции в первом изображении, а затем нахожу все ключевые точки функции во втором изображении. Затем я нахожу дескрипторы для этих ключевых точек, а затем выполняю совпадение между двумя изображениями.OpenCV Android: Как нарисовать соответствующие ключевые точки над сравниваемыми изображениями?

private void matchImages() { 
    Mat refMat = new Mat(); 
    Mat srcMat = new Mat(); 

    Bitmap refBitmap = ((BitmapDrawable) mRefImg.getDrawable()).getBitmap(); 
    Bitmap srcBitmap = ((BitmapDrawable) mSrcImg.getDrawable()).getBitmap(); 

    Utils.bitmapToMat(refBitmap, refMat); 
    Utils.bitmapToMat(srcBitmap, srcMat); 

    MatOfDMatch matches = new MatOfDMatch(); 
    MatOfDMatch goodMatches = new MatOfDMatch(); 

    LinkedList<DMatch> listOfGoodMatches = new LinkedList<>(); 

    LinkedList<Point> refObjectList = new LinkedList<>(); 
    LinkedList<Point> srcObjectList = new LinkedList<>(); 

    MatOfKeyPoint refKeypoints = new MatOfKeyPoint(); 
    MatOfKeyPoint srcKeyPoints = new MatOfKeyPoint(); 

    Mat refDescriptors = new Mat(); 
    Mat srcDescriptors = new Mat(); 

    MatOfPoint2f reference = new MatOfPoint2f(); 
    MatOfPoint2f source = new MatOfPoint2f(); 

    FeatureDetector orbFeatureDetector = FeatureDetector.create(FeatureDetector.ORB); 
    orbFeatureDetector.detect(refMat, refKeypoints); 
    orbFeatureDetector.detect(srcMat, srcKeyPoints); 

    DescriptorExtractor descriptorExtractor = DescriptorExtractor.create(DescriptorExtractor.ORB); 
    descriptorExtractor.compute(refMat, refKeypoints, refDescriptors); 
    descriptorExtractor.compute(srcMat, srcKeyPoints, srcDescriptors); 

    DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING); 
    matcher.match(refDescriptors, srcDescriptors, matches); 

    double max_dist = 0; 
    double min_dist = 100; 
    List<DMatch> matchesList = matches.toList(); 

    for (int i = 0; i < refDescriptors.rows(); i++) { 
     Double distance = (double) matchesList.get(i).distance; 
     if (distance < min_dist) min_dist = distance; 
     if (distance > max_dist) max_dist = distance; 
    } 

    for (int i = 0; i < refDescriptors.rows(); i++) { 
     if (matchesList.get(i).distance < 3 * min_dist) { 
      listOfGoodMatches.add(matchesList.get(i)); 
     } 
    } 

    goodMatches.fromList(listOfGoodMatches); 

    List<KeyPoint> refObjectListKeypoints = refKeypoints.toList(); 
    List<KeyPoint> srcObjectListKeypoints = srcKeyPoints.toList(); 

    for (int i = 0; i < listOfGoodMatches.size(); i++) { 
     refObjectList.addLast(refObjectListKeypoints.get(listOfGoodMatches.get(i).queryIdx).pt); 
     srcObjectList.addLast(srcObjectListKeypoints.get(listOfGoodMatches.get(i).trainIdx).pt); 
    } 

    reference.fromList(refObjectList); 
    source.fromList(srcObjectList); 

    String result; 
    if(listOfGoodMatches.size() > MIN_MATCH_THRESHOLD && listOfGoodMatches.size() < MAX_MATCH_THRESHOLD) { 
     result = "They MATCH!"; 
    } else { 
     result = "They DON'T match!"; 
    } 

    AlertDialog alert = new AlertDialog.Builder(this) 
      .setMessage(result) 
      .setPositiveButton("OK", new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        // close 
       } 
      }).create(); 
    alert.show(); 

    Mat outputImage = new Mat(); 
    Bitmap comboBmp = combineImages(refBitmap, srcBitmap); 
    Utils.bitmapToMat(comboBmp, outputImage); 

    Features2d.drawMatches(refMat, refKeypoints, srcMat, srcKeyPoints, goodMatches, outputImage); 

    Bitmap bitmap = Bitmap.createBitmap(outputImage.cols(), outputImage.rows(), Bitmap.Config.ARGB_8888); 

    Utils.matToBitmap(outputImage, bitmap); 
    mRefImg.setImageBitmap(comboBmp); 
    mRefImg.invalidate(); 
    mSrcImg.setImageBitmap(bitmap); 
    mSrcImg.invalidate(); 
} 

Это просто приложение «песочницы», которое я создал, чтобы проверить и поиграть с этой библиотекой. В результате приведенного выше кода дает следующее если сравнить два изображения:

Result of comparing two images

Как вы можете видеть, фон из матчей черный. Как я могу нарисовать эти соответствия по изображению слева? Пример того, как бы хотелось, чтобы мой результат выглядел вот так: https://stackoverflow.com/a/14909358/3779845

ответ

6

Я не уверен, что это все равно поможет вам, но как я исправил проблему с черным фоном, вместо использования RGBA изображение i использовано

Imgproc.cvtColor(gabarito, gabaritoRgb, Imgproc.COLOR_RGBA2RGB, 1); 
Imgproc.cvtColor(prova, provaRgb, Imgproc.COLOR_RGBA2RGB, 1); 

для преобразования моих изображений в RGB, а затем я использовал новые изображения в функции drawMatched!

Features2d.drawMatches(gabaritoRgb, keypointsGabarito, provaRgb, keypointsProva, matches, 
        imagemDeSaida); 
Смежные вопросы