java+opencv 目標影像調整

流放荒帝發表於2016-10-28

java+opencv 進行影像匹配,FeatureDetector ,DescriptorExtractor
DescriptorMatcher 配合使用。分別進行關鍵點檢測,提取描述向量,特徵匹配。
廢話少說直接上程式碼。有問題可留言!!!opencv+java 論壇

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfDMatch;
import org.opencv.core.MatOfKeyPoint;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Size;
import org.opencv.highgui.Highgui;
import org.opencv.imgproc.Imgproc;
import org.opencv.features2d.DMatch;
import org.opencv.features2d.DescriptorExtractor;
import org.opencv.features2d.DescriptorMatcher;
import org.opencv.features2d.FeatureDetector;
import org.opencv.features2d.Features2d;
import org.opencv.calib3d.*;

public class testFeatureDetector
{
    /**
     * 
     * @param scene 參考圖
     * @param object 目標需要調整圖
     */
    static void tiaozheng2(Mat scene,Mat object) 
    {

        FeatureDetector detector = FeatureDetector.create(FeatureDetector.SURF);
        DescriptorExtractor descriptor = DescriptorExtractor.create(DescriptorExtractor.ORB);
        DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);
        // DETECTION

        // first image
        Mat descriptors_scene= new Mat();
        MatOfKeyPoint keypoints_scene= new MatOfKeyPoint();
        detector.detect(scene, keypoints_scene);
        descriptor.compute(scene, keypoints_scene, descriptors_scene);

        // second image
        Mat descriptors_object= new Mat();
        MatOfKeyPoint keypoints_object = new MatOfKeyPoint();
        detector.detect(object, keypoints_object);
        descriptor.compute(object, keypoints_object,descriptors_object);
        // MATCHING
        // match these two keypoints sets
        List<MatOfDMatch> matches = new ArrayList<MatOfDMatch>();
        matcher.knnMatch(descriptors_object, descriptors_scene,matches, 5);
        /////////////////////////////////////////////////////////////
        // ratio test
        LinkedList<DMatch> good_matches = new LinkedList<DMatch>();
        for (Iterator<MatOfDMatch> iterator = matches.iterator(); iterator.hasNext();) {
            MatOfDMatch matOfDMatch = (MatOfDMatch) iterator.next();
            if (matOfDMatch.toArray()[0].distance / matOfDMatch.toArray()[1].distance < 0.9) {
                good_matches.add(matOfDMatch.toArray()[0]);
            }
        }
        // get keypoint coordinates of good matches to find homography and remove outliers using ransac
        List<Point> pts_object = new ArrayList<Point>();
        List<Point> pts_scene = new ArrayList<Point>();
        for(int i = 0; i<good_matches.size(); i++){
            pts_object.add(keypoints_object.toList().get(good_matches.get(i).queryIdx).pt);
            pts_scene.add(keypoints_scene.toList().get(good_matches.get(i).trainIdx).pt);
        }
        // convertion of data types - there is maybe a more beautiful way
        Mat outputMask = new Mat();
        MatOfPoint2f pts_objectMat = new MatOfPoint2f();
        pts_objectMat.fromList(pts_object);
        MatOfPoint2f pts_sceneMat = new MatOfPoint2f();
        pts_sceneMat.fromList(pts_scene);

        Mat Homog = Calib3d.findHomography(pts_objectMat, pts_sceneMat, Calib3d.RANSAC, 10, outputMask);
        Mat resultMat=new Mat(new Size(object.cols(),object.rows()),object.type());   
        Imgproc.warpPerspective(object,object,  Homog, resultMat.size());

//      // outputMask contains zeros and ones indicating which matches are filtered
        LinkedList<DMatch> better_matches = new LinkedList<DMatch>();
        for (int i = 0; i < good_matches.size(); i++) 
        {
        //  System.out.println(outputMask.get(i, 0)[0]);
            if (outputMask.get(i, 0)[0] != 0.0) {
                better_matches.add(good_matches.get(i));
            }
        } 
//      System.out.println(better_matches.toString());
       /////////////////////////////////////////////////////////////
//      // DRAWING OUTPUT
        Mat outputImg = new Mat();
        // this will draw all matches, works fine
        MatOfDMatch better_matches_mat = new MatOfDMatch();
        better_matches_mat.fromList(better_matches);
     //   System.out.println(better_matches_mat.toString());
        Features2d.drawMatches( object, keypoints_object, scene, keypoints_scene,better_matches_mat, outputImg);
        Mat outputImg2 = new Mat();
        Features2d.drawMatches2( object, keypoints_object, scene, keypoints_scene,matches, outputImg2);
        Highgui.imwrite("result.jpg", outputImg);
        Highgui.imwrite("result2.jpg", outputImg2);
    }

    /**
     * 
     * @param scene 參考圖
     * @param object 目標需要調整圖
     */
    static void tiaozheng(Mat scene,Mat object)
    {

        FeatureDetector  detector =FeatureDetector.create(FeatureDetector.SURF);  
        MatOfKeyPoint keypoints_object = new MatOfKeyPoint();
        MatOfKeyPoint keypoints_scene = new MatOfKeyPoint();

        detector.detect(object, keypoints_object);
        detector.detect(scene, keypoints_scene);

        Mat descriptors_object=new Mat();
        Mat descriptors_scene=new Mat();

        DescriptorExtractor extractor=DescriptorExtractor.create(DescriptorExtractor.ORB); 
        extractor.compute( object, keypoints_object, descriptors_object );
        extractor.compute( scene, keypoints_scene, descriptors_scene );
        DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);

        MatOfDMatch matches = new MatOfDMatch();
        matcher.match(descriptors_object, descriptors_scene, matches);
        DMatch[] tmmpDMatchs=matches.toArray();

        double max_dist = 0; double min_dist =400;
        for( int i = 0; i < descriptors_object.rows(); i++ )
        { 
            double dist =tmmpDMatchs[i].distance;
            if( dist < min_dist ) min_dist = dist;
            if( dist > max_dist ) max_dist = dist;
        }

        LinkedList<DMatch> good_matches = new LinkedList<DMatch>();
        for (int i = 0; i < descriptors_object.rows();++i) 
        {
            double dist =tmmpDMatchs[i].distance;
            if (dist < 3*min_dist ) 
            {
                good_matches.add(tmmpDMatchs[i]);
            }
        }

        List<Point> pts_scene = new ArrayList<Point>();
        List<Point> pts_object = new ArrayList<Point>();//
        for(int i = 0; i<good_matches.size(); i++)
        {
            pts_object.add(keypoints_object.toList().get(good_matches.get(i).queryIdx).pt);
            pts_scene.add(keypoints_scene.toList().get(good_matches.get(i).trainIdx).pt);
        }

        Mat outputMask = new Mat();
        MatOfPoint2f pts_sceneMat = new MatOfPoint2f();
        pts_sceneMat.fromList(pts_scene);
        MatOfPoint2f pts_objectMat = new MatOfPoint2f();
        pts_objectMat.fromList(pts_object);

        Mat Homog = Calib3d.findHomography(pts_objectMat, pts_sceneMat, Calib3d.RANSAC, 10, outputMask);
        Mat resultMat=new Mat(new Size(scene.cols(),scene.rows()),scene.type());
        Imgproc.warpPerspective(object,object,  Homog, resultMat.size());
    }

    public  static void main(String args[])
    {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);


        Mat scene=Highgui.imread("00.jpg");//參考  
        Mat object=Highgui.imread("11.jpg");//調整目標
        object.convertTo(object, CvType.CV_8UC3);// 目標圖
        scene.convertTo(scene, CvType.CV_8UC3);// 參考圖
        Mat img2=object.submat(new Rect(0,0,object.width(),object.height()*9/10));
        Mat img1=scene.submat(new Rect(0,0,object.width(),object.height()*9/10));
        Highgui.imwrite("scene.jpg",img1);//調整目標
        Highgui.imwrite("object.jpg",img2);//調整目標
    //  tiaozheng(img1,img2);

        tiaozheng2(img1,img2);
        Highgui.imwrite("object2.jpg",img2);
    }
}







參考圖

需要調整的圖

調整結果1
調整結果2

粗糙匹配點
篩選匹配結果

“`

相關文章