OpenCV ORB匹配多个图像Java

时间:2018-10-05 10:23:46

标签: java android-studio opencv orb image-comparison

好的,所以我是一名正在忙于我的年度项目的大学生。本质上,我正在尝试做的是允许用户拥有“ x”数量的图像,这些图像将保存到其Android设备。一旦用户保存了这些图像,便可以使用相机进行“扫描”,并将实时相机视图与保存的图像进行比较,并显示一条消息“找到匹配项”或沿这些行显示的内容。

我有1张图片和只有1张图片的匹配图片。我无法弄清楚如何与多个图像进行比较。我已经尝试搜索解决方案,但是大多数解决方案与C ++或Python有关,这对我没有太大帮助,因为我无法确定如何在Android Studio中进行操作。任何帮助将不胜感激。

此处的图片Current System

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






}

}

0 个答案:

没有答案