OpenCV ORB Сопоставление нескольких изображений Java - PullRequest
0 голосов
/ 05 октября 2018

Хорошо, так что я студент университета, занятый выполнением годового проекта.По сути, я пытаюсь разрешить пользователю иметь количество «х» изображений, которые они сохранят на своем устройстве Android.После сохранения этих изображений пользователь может «сканировать» с помощью камеры, и изображение с камеры в реальном времени будет сравниваться с сохраненными изображениями, и будет отображаться сообщение «найдено совпадений» или что-то в этом духе.

Iполучили соответствие, работающее для 1 изображения и только 1 изображения.Я не могу понять, как сравнить с более чем 1 изображение.Я пытался найти решения, но большинство из них связаны с C ++ или Python, что мне не очень помогает, поскольку я не могу понять, как это сделать в Android Studio.Любая помощь будет принята с благодарностью.

Изображение здесь Текущая система

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

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());






}

}

...