openCV ORB 图片特征检测 与 匹配

2019-08-01  本文已影响0人  MrY_124d
视频流匹配 特征检测对比

导入openCVLibrary libray 就不说了

相机返回来的数据流

    @Override
    public void onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {

        mRgba = inputFrame.rgba();
        mGray = inputFrame.gray();

        Mat matLin = mGray.clone();
        Core.flip(mGray, matLin, 0);//-1 0 1    //旋转90
        Core.transpose(matLin, mGray);// 翻转

orb 的使用

public ImageMatcher() {
    orb = ORB.create(2000);
    gftt = GFTTDetector.create();
    descriptorMatcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);
}

摸版图片

    public boolean src(Mat scene) {
        this.sceneMat = scene;
        sceneKeyPoint = new MatOfKeyPoint();
        sceneDescriptors = new Mat();
//        //发现特征
//        gftt.detect(scene,sceneKeyPoint);
//        //描述
//        orb.compute(scene,sceneKeyPoint,sceneDescriptors);
        orb.detectAndCompute(scene, new Mat(), sceneKeyPoint, sceneDescriptors);
        return sceneKeyPoint.toArray().length > 8;
    }

    public void match(Mat objectMat){
        try {
            long t = System.currentTimeMillis();

            MatOfKeyPoint objectKeyPoint = new MatOfKeyPoint();
            Mat objectDescriptors = new Mat();
//            gftt.detect(objectMat,objectKeyPoint);
//            orb.compute(objectMat,objectKeyPoint,objectDescriptors);
            orb.detectAndCompute(objectMat, new Mat(), objectKeyPoint, objectDescriptors);
            //匹配
            List<MatOfDMatch> matches = new ArrayList<>();
            descriptorMatcher.knnMatch(sceneDescriptors, objectDescriptors, matches, 2);
//          descriptorMatcher.radiusMatch(sceneDescriptors,objectDescriptors,matches,200f);

            //帅选
            List<MatOfDMatch> goodMatOfDMatch = new ArrayList<>();
            List<DMatch> goodMatches = new ArrayList<>();
            for (MatOfDMatch match : matches) {
                DMatch[] dMatches = match.toArray();
                if (dMatches[0].distance < 0.7 * dMatches[1].distance) {
                    goodMatches.add(dMatches[0]);
                    goodMatOfDMatch.add(match);
                }
            }

            if (goodMatches.size() > 4) {
                List<KeyPoint> sceneKeyPoints = sceneKeyPoint.toList();
                List<KeyPoint> objectKeyPoints = objectKeyPoint.toList();

                List<Point> objectPoints = new ArrayList<>();
                List<Point> scenePoints = new ArrayList<>();
                for (DMatch goodMatch : goodMatches) {
                    scenePoints.add(sceneKeyPoints.get(goodMatch.queryIdx).pt);
                    objectPoints.add(objectKeyPoints.get(goodMatch.trainIdx).pt);
                }
                MatOfPoint2f sceMatOfPoint2f = new MatOfPoint2f();
                MatOfPoint2f objMatOfPoint2f = new MatOfPoint2f();
                sceMatOfPoint2f.fromList(scenePoints);
                objMatOfPoint2f.fromList(objectPoints);

                //因为需要使用findHomography函数来实现RANSAC算法,对特征点进行筛选
                Mat H = Calib3d.findHomography(sceMatOfPoint2f, objMatOfPoint2f, Calib3d.RANSAC, 3);

                /**
                 * 透视变换(Perspective Transformation)是将图片投影到一个新的视平面(Viewing Plane),也称作投影映射(Projective Mapping)。
                 */
                Mat scene_corners = new Mat(4, 1, CvType.CV_32FC2);
                scene_corners.put(0, 0, 0, 0);
                scene_corners.put(1, 0, sceneMat.cols(), 0);
                scene_corners.put(2, 0, sceneMat.cols(), sceneMat.rows());
                scene_corners.put(3, 0, 0, sceneMat.rows());

                //使用 perspectiveTransform 将模板图进行透视变以矫正图象得到标准图片
                Mat object_corners = new Mat(4, 1, CvType.CV_32FC2);
                Core.perspectiveTransform(scene_corners, object_corners, H);

                //矩形四个顶点
                Point pointA = new Point(object_corners.get(0, 0));
                Point pointB = new Point(object_corners.get(1, 0));
                Point pointC = new Point(object_corners.get(2, 0));
                Point pointD = new Point(object_corners.get(3, 0));

                if (listener != null)
                    listener.onMatcherPoint(pointA, pointB, pointC, pointD);

                //将匹配的图像用用四条线框出来
                //            Imgproc.line(objectMat, pointA, pointB, new Scalar(0, 255, 0), 2);//上 A->B
                //            Imgproc.line(objectMat, pointB, pointC, new Scalar(0, 255, 0), 2);//右 B->C
                //            Imgproc.line(objectMat, pointC, pointD, new Scalar(0, 255, 0), 2);//下 C->D
                //            Imgproc.line(objectMat, pointD, pointA, new Scalar(0, 255, 0), 2);//左 D->A

                //            Imgproc.rectangle(objectMat, pointA, pointC, new Scalar(0, 255, 0), 2);
                //            //绘制匹配图
                //            Bitmap bitmap = Bitmap.createBitmap(objectMat.cols(), objectMat.rows(), Bitmap.Config.ARGB_4444);
                //            Utils.matToBitmap(objectMat, bitmap);
                L.t(t);
            } else {
                if (listener != null) {
                    listener.onMatcherLose();
                }
            }
            if (listener != null) {
                listener.detect(sceneKeyPoint, objectKeyPoint);
                Bitmap bitmap = getDrawMatches2Bitmap(sceneMat, sceneKeyPoint, objectMat, objectKeyPoint, goodMatOfDMatch);
                listener.drawMatches2(bitmap);
            }
        } catch (Exception e) {
            //e.printStackTrace();
        }
    }
上一篇下一篇

猜你喜欢

热点阅读