android ओपनसीवी छवि तुलना और एंड्रॉइड में समानता



image opencv (1)

मैं OpenCV शिक्षार्थी हूं मैं छवि तुलना की कोशिश कर रहा था। मैंने ओपनसीवी 2.4.13.3 का प्रयोग किया है। मेरे पास इन दो छवियों 1.jpg और cam1.jpg

जब मैं openCV में निम्न कमांड का उपयोग करता हूँ

File sdCard = Environment.getExternalStorageDirectory();
String path1, path2;
path1 = sdCard.getAbsolutePath() + "/1.jpg";
path2 = sdCard.getAbsolutePath() + "/cam1.jpg";

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

Mat img1 = Highgui.imread(path1);
Mat img2 = Highgui.imread(path2);

Mat descriptors1 = new Mat();
MatOfKeyPoint keypoints1 = new MatOfKeyPoint();
detector.detect(img1, keypoints1);
extractor.compute(img1, keypoints1, descriptors1);

//second image
// Mat img2 = Imgcodecs.imread(path2);
Mat descriptors2 = new Mat();
MatOfKeyPoint keypoints2 = new MatOfKeyPoint();
detector.detect(img2, keypoints2);
extractor.compute(img2, keypoints2, descriptors2);


//matcher image descriptors
MatOfDMatch matches = new MatOfDMatch();
matcher.match(descriptors1,descriptors2,matches);

// Filter matches by distance
MatOfDMatch filtered = filterMatchesByDistance(matches);

int total = (int) matches.size().height;
int Match= (int) filtered.size().height;
Log.d("LOG", "total:" + total + " Match:"+Match);

विधि फ़िल्टरमैटिसीबायडिस्टेंस

    static MatOfDMatch filterMatchesByDistance(MatOfDMatch matches){
    List<DMatch> matches_original = matches.toList();
    List<DMatch> matches_filtered = new ArrayList<DMatch>();

    int DIST_LIMIT = 30;
    // Check all the matches distance and if it passes add to list of filtered matches
    Log.d("DISTFILTER", "ORG SIZE:" + matches_original.size() + "");
    for (int i = 0; i < matches_original.size(); i++) {
        DMatch d = matches_original.get(i);
        if (Math.abs(d.distance) <= DIST_LIMIT) {
            matches_filtered.add(d);
        }
    }
    Log.d("DISTFILTER", "FIL SIZE:" + matches_filtered.size() + "");

    MatOfDMatch mat = new MatOfDMatch();
    mat.fromList(matches_filtered);
    return mat;
}

लॉग

total:122 Match:30

जैसा कि हम लॉग मैच 30 से देख सकते हैं
लेकिन जैसा कि हम दोनों छवियों को एक ही दृश्य तत्व (में) देख सकते हैं
मैं OpenCV का उपयोग करके मैच = 90 कैसे प्राप्त करूं?
यह महान होगा अगर कोई कोड स्निपेट के साथ मदद कर सकता है।
यदि opencv का उपयोग करना संभव नहीं है तो अन्य विकल्प क्या हैं जो हम देख सकते हैं?


लेकिन जैसा कि हम दोनों छवियों को एक ही दृश्य तत्व (में) देख सकते हैं

इसलिए, हमें पूरी छवियों की तुलना नहीं करनी चाहिए, लेकिन उस पर "समान दृश्य तत्व" यदि आप "टेम्प्लेट" और "कैमरा" चित्रों की स्वयं की तुलना नहीं करते हैं, लेकिन उसी तरह संसाधित (उदाहरण के लिए बाइनरी ब्लैक / श्वेत में परिवर्तित) "टेम्पलेट" और "कैमरा" छवियों की तुलना में आप Match मान को बेहतर कर सकते हैं। उदाहरण के लिए, ("टेम्पलेट" और "कैमरा") दोनों चित्रों पर नीले (टेम्पलेट लोगो की पृष्ठभूमि) खोजने का प्रयास करें और उन वर्गों की तुलना करें (रुचि के क्षेत्र)। कोड ऐसा कुछ हो सकता है:

Bitmap bmImageTemplate = <get your template image Bitmap>;
Bitmap bmTemplate = findLogo(bmImageTemplate);  // process template image

Bitmap bmImage = <get your camera image Bitmap>;
Bitmap bmLogo = findLogo(bmImage); // process camera image same way

compareBitmaps(bmTemplate, bmLogo);

कहा पे

private Bitmap findLogo(Bitmap sourceBitmap) {
    Bitmap roiBitmap = null;
    Mat sourceMat = new Mat(sourceBitmap.getWidth(), sourceBitmap.getHeight(), CvType.CV_8UC3);
    Utils.bitmapToMat(sourceBitmap, sourceMat);
    Mat roiTmp = sourceMat.clone();

    final Mat hsvMat = new Mat();
    sourceMat.copyTo(hsvMat);

    // convert mat to HSV format for Core.inRange()
    Imgproc.cvtColor(hsvMat, hsvMat, Imgproc.COLOR_RGB2HSV);

    Scalar lowerb = new Scalar(85, 50, 40);         // lower color border for BLUE
    Scalar upperb = new Scalar(135, 255, 255);      // upper color border for BLUE
    Core.inRange(hsvMat, lowerb, upperb, roiTmp);   // select only blue pixels

    // find contours
    List<MatOfPoint> contours = new ArrayList<>();
    List<Rect> squares = new ArrayList<>();
    Imgproc.findContours(roiTmp, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);

    // find appropriate bounding rectangles
    for (MatOfPoint contour : contours) {
        MatOfPoint2f areaPoints = new MatOfPoint2f(contour.toArray());
        RotatedRect boundingRect = Imgproc.minAreaRect(areaPoints);

        double rectangleArea = boundingRect.size.area();

        // test min ROI area in pixels
        if (rectangleArea > 400) {
            Point rotated_rect_points[] = new Point[4];
            boundingRect.points(rotated_rect_points);

            Rect rect = Imgproc.boundingRect(new MatOfPoint(rotated_rect_points));
            double aspectRatio = rect.width > rect.height ?
                    (double) rect.height / (double) rect.width : (double) rect.width / (double) rect.height;
            if (aspectRatio >= 0.9) {
                squares.add(rect);
            }
        }
    }

    Mat logoMat = extractSquareMat(roiTmp, getBiggestSquare(squares));

    roiBitmap = Bitmap.createBitmap(logoMat.cols(), logoMat.rows(), Bitmap.Config.ARGB_8888);
    Utils.matToBitmap(logoMat, roiBitmap);
    return roiBitmap;
}

विधि extractSquareMat() बस पूरी तस्वीर से ब्याज (लोगो) का क्षेत्र निकालना

public static Mat extractSquareMat(Mat sourceMat, Rect rect) {
    Mat squareMat = null;
    int padding = 50;

    if (rect != null) {
        Rect truncatedRect = new Rect((int) rect.tl().x + padding, (int) rect.tl().y + padding,
                rect.width - 2 * padding, rect.height - 2 * padding);
        squareMat = new Mat(sourceMat, truncatedRect);
    }

    return squareMat ;
}

और अपने कोड के लिए compareBitmaps() बस आवरण की तुलना करें:

private void compareBitmaps(Bitmap bitmap1, Bitmap bitmap2) {
    Mat mat1 = new Mat(bitmap1.getWidth(), bitmap1.getHeight(), CvType.CV_8UC3);
    Utils.bitmapToMat(bitmap1, mat1);

    Mat mat2 = new Mat(bitmap2.getWidth(), bitmap2.getHeight(), CvType.CV_8UC3);
    Utils.bitmapToMat(bitmap2, mat2);

    compareMats(mat1, mat2);
}

विधि के रूप में आपका कोड:

private void compareMats(Mat img1, Mat img2) {
    FeatureDetector detector = FeatureDetector.create(FeatureDetector.ORB);
    DescriptorExtractor extractor = DescriptorExtractor.create(DescriptorExtractor.BRIEF);
    DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);

    Mat descriptors1 = new Mat();
    MatOfKeyPoint keypoints1 = new MatOfKeyPoint();
    detector.detect(img1, keypoints1);
    extractor.compute(img1, keypoints1, descriptors1);

    //second image
    // Mat img2 = Imgcodecs.imread(path2);
    Mat descriptors2 = new Mat();
    MatOfKeyPoint keypoints2 = new MatOfKeyPoint();
    detector.detect(img2, keypoints2);
    extractor.compute(img2, keypoints2, descriptors2);


    //matcher image descriptors
    MatOfDMatch matches = new MatOfDMatch();
    matcher.match(descriptors1,descriptors2,matches);

    // Filter matches by distance
    MatOfDMatch filtered = filterMatchesByDistance(matches);

    int total = (int) matches.size().height;
    int Match= (int) filtered.size().height;
    Log.d("LOG", "total:" + total + " Match:" + Match);
}

static MatOfDMatch filterMatchesByDistance(MatOfDMatch matches){
    List<DMatch> matches_original = matches.toList();
    List<DMatch> matches_filtered = new ArrayList<DMatch>();

    int DIST_LIMIT = 30;
    // Check all the matches distance and if it passes add to list of filtered matches
    Log.d("DISTFILTER", "ORG SIZE:" + matches_original.size() + "");
    for (int i = 0; i < matches_original.size(); i++) {
        DMatch d = matches_original.get(i);
        if (Math.abs(d.distance) <= DIST_LIMIT) {
            matches_filtered.add(d);
        }
    }
    Log.d("DISTFILTER", "FIL SIZE:" + matches_filtered.size() + "");

    MatOfDMatch mat = new MatOfDMatch();
    mat.fromList(matches_filtered);
    return mat;
}

आपके प्रश्न के परिणाम से सहेजे गए छवियों (50% के लिए स्केल किए गए) के परिणामस्वरूप यह है:

D/DISTFILTER: ORG SIZE:237
D/DISTFILTER: FIL SIZE:230
D/LOG: total:237 Match:230

नायब! यह केवल त्वरित टेम्पलेट के लिए दृष्टिकोण को प्रदर्शित करने के लिए एक त्वरित और गंदे उदाहरण है।





image-processing