Nicholas Mott
Nicholas Mott

Reputation: 112

OpenCV ORB Matching multiple images Java

Ok, so I am a university student busy doing my year project. Essentially what I am trying to do is allow the user to have a "x" amount of images that they will save to their android device. Once the user has saved these images they can "scan" using the camera and the live camera view will be compared to the saved images and a message will be displayed "match found" or something along those lines.

I have got the matching working for 1 image and only 1 image. I cant quite work out how to compare to more than 1 image. I have tried to search for solutions but most of them are C++ or Python related, which doesnt really help me as I cant work out how to do it in Android Studio. Any assistance will be greatly appreciated.

Image here Current System

PS: This is a university project for proof of concept, my matching at the bottom seems to work for what I have tested so I am not too worried about increasing the accuracy at this stage, only allowing of comparison of more than one image.

public class ScanTattooActivity extends Activity implements CameraBridgeViewBase.CvCameraViewListener2 {

private static final String TAG = "Scan Tattoo::Activity";
private int w, h;
private CameraBridgeViewBase mOpenCvCameraView;
TextView tvName;
Scalar RED = new Scalar(255, 0, 0);
Scalar GREEN = new Scalar(0, 255, 0);
FeatureDetector detector;
DescriptorExtractor descriptor;
DescriptorMatcher matcher;
Mat descriptors2,descriptors1;
Mat img1;
MatOfKeyPoint keypoints1,keypoints2;
int match_count = 0;

static {
    if (!OpenCVLoader.initDebug())
        Log.d("ERROR", "Unable to load OpenCV");
    else
        Log.d("SUCCESS", "OpenCV loaded");
}

private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
    @Override
    public void onManagerConnected(int status) {
        switch (status) {
            case LoaderCallbackInterface.SUCCESS: {
                Log.i(TAG, "OpenCV loaded successfully");
                mOpenCvCameraView.enableView();
                try {
                    initializeOpenCVDependencies();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            break;
            default: {
                super.onManagerConnected(status);
            }
            break;
        }
    }
};

private void initializeOpenCVDependencies() throws IOException {
    mOpenCvCameraView.enableView();
    detector = FeatureDetector.create(FeatureDetector.ORB);
    descriptor = DescriptorExtractor.create(DescriptorExtractor.ORB);
    matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);
    img1 = new Mat();
    AssetManager assetManager = getAssets();
    InputStream istr = assetManager.open("ajpeg2.jpg");
    Bitmap bitmap = BitmapFactory.decodeStream(istr);
    Utils.bitmapToMat(bitmap, img1);
    Imgproc.cvtColor(img1, img1, Imgproc.COLOR_RGB2GRAY);
    img1.convertTo(img1, 0); //converting the image to match with the type of the cameras image
    descriptors1 = new Mat();
    keypoints1 = new MatOfKeyPoint();
    detector.detect(img1, keypoints1);
    descriptor.compute(img1, keypoints1, descriptors1);

}


public ScanTattooActivity() {

    Log.i(TAG, "Instantiated new " + this.getClass());



}

/**
 * Called when the activity is first created.
 */
@Override
public void onCreate(Bundle savedInstanceState) {

    Log.i(TAG, "called onCreate");
    super.onCreate(savedInstanceState);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    setContentView(R.layout.activity_scan_tattoo);
    mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.scantattoo_activity_java_surface_view);
    mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
    mOpenCvCameraView.setCvCameraViewListener(this);
    //tvName = (TextView) findViewById(R.id.text1);

}

@Override
public void onPause() {
    super.onPause();
    if (mOpenCvCameraView != null)
        mOpenCvCameraView.disableView();
}

@Override
public void onResume() {
    super.onResume();
    if (!OpenCVLoader.initDebug()) {
        Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
        OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
    } else {
        Log.d(TAG, "OpenCV library found inside package. Using it!");
        mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
    }


}

public void onDestroy() {
    super.onDestroy();
    if (mOpenCvCameraView != null)
        mOpenCvCameraView.disableView();
}

public void onCameraViewStarted(int width, int height) {
    w = width;
    h = height;


}

public void onCameraViewStopped() {
}

public Mat recognize(Mat aInputFrame) {



    Imgproc.cvtColor(aInputFrame, aInputFrame, Imgproc.COLOR_RGB2GRAY);
    descriptors2 = new Mat();
    keypoints2 = new MatOfKeyPoint();
    detector.detect(aInputFrame, keypoints2);
    descriptor.compute(aInputFrame, keypoints2, descriptors2);
    int count = 0;


    // Matching
    MatOfDMatch matches = new MatOfDMatch();
    if (img1.type() == aInputFrame.type()) {
        matcher.match(descriptors1, descriptors2, matches);

    } else {
        return aInputFrame;
    }
    List<DMatch> matchesList = matches.toList();

    Double max_dist = 0.0;
    Double min_dist = 100.0;

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

    double goodMatchesSum = 0;

    LinkedList<DMatch> good_matches = new LinkedList<DMatch>();
    for (int i = 0; i < matchesList.size(); i++) {
        if (matchesList.get(i).distance <= (1.5 * min_dist))
            good_matches.addLast(matchesList.get(i));
            goodMatchesSum += matchesList.get(i).distance;
            count ++;
    }

    MatOfDMatch goodMatches = new MatOfDMatch();
    goodMatches.fromList(good_matches);
    Mat outputImg = new Mat();
    MatOfByte drawnMatches = new MatOfByte();
    if (aInputFrame.empty() || aInputFrame.cols() < 1 || aInputFrame.rows() < 1) {
        return aInputFrame;
    }
    Features2d.drawMatches(img1, keypoints1, aInputFrame, keypoints2, goodMatches, outputImg, GREEN, RED, drawnMatches, Features2d.NOT_DRAW_SINGLE_POINTS);
    Imgproc.resize(outputImg, outputImg, aInputFrame.size());


    double matchPercentage =  goodMatchesSum/ (double) good_matches.size();



    if(matchPercentage/count >= 5)
    {


        match_count ++;

        if(match_count > 20)
        {

            "good match"
        }

    }
    else if (matchPercentage/count < 5)
    {
        "Bad match, compare next image"


    }







    return outputImg;
}



public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
    return recognize(inputFrame.rgba());






}

}

Upvotes: 0

Views: 949

Answers (0)

Related Questions