如何使用特征检测检测图像中多次出现的相同对象

时间:2016-05-22 11:31:48

标签: opencv unity3d feature-detection

有没有办法使用特征检测来检测图像中多个相同对象的出现?

早些时候,我尝试使用模板匹配,我能够检测到多次出现但后来由于它依赖于图像方向和大小而丢弃了。

Single Occurrence of ocject

Multiple Occurrence

Question about template matching

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using OpenCVForUnity;

namespace OpenCVForUnitySample
{
public class Feature2DSample : MonoBehaviour
{
    void Start ()
    {
        Texture2D imgTemplate = Resources.Load ("lena") as Texture2D;
        Texture2D imgTexture = Resources.Load ("yVLsd_") as Texture2D;

        Mat matSrc = new Mat (imgTemplate.height, imgTemplate.width, CvType.CV_8UC3);
        Utils.texture2DToMat (imgTemplate, matSrc);
        Debug.Log ("img1Mat dst ToString " + matSrc.ToString ());

        Mat matScene = new Mat (imgTexture.height, imgTexture.width, CvType.CV_8UC3);
        Utils.texture2DToMat (imgTexture, matScene);
        Debug.Log ("img2Mat dst ToString " + matScene.ToString ());

        FeatureDetector detector = FeatureDetector.create (FeatureDetector.ORB);
        DescriptorExtractor extractor = DescriptorExtractor.create (DescriptorExtractor.ORB);

        MatOfKeyPoint keypointsSrc = new MatOfKeyPoint ();
        Mat descriptorsSrc = new Mat ();

        detector.detect (matSrc, keypointsSrc);
        extractor.compute (matSrc, keypointsSrc, descriptorsSrc);

        MatOfKeyPoint keypointsScene = new MatOfKeyPoint ();
        Mat descriptorsScene = new Mat ();

        detector.detect (matScene, keypointsScene);
        extractor.compute (matScene, keypointsScene, descriptorsScene);

        DescriptorMatcher matcher = DescriptorMatcher.create (DescriptorMatcher.BRUTEFORCE_HAMMINGLUT);
        MatOfDMatch matches = new MatOfDMatch ();

        matcher.match (descriptorsSrc, descriptorsScene, matches);

        //NEW CODE
        List<DMatch> matchesList = matches.toList ();

        //– Quick calculation of max and min distances between keypoints
        double max_dist = 0;
        double min_dist = 100;
        for (int i = 0; i < descriptorsSrc.rows (); i++) {
            double dist = (double)matchesList [i].distance;

            if (dist < min_dist)
                min_dist = dist;
            if (dist > max_dist)
                max_dist = dist;
        }

        List<DMatch> good_matches = new List<DMatch> ();
        for (int i = 0; i < descriptorsSrc.rows (); i++) {
            if (matchesList [i].distance < 3 * min_dist) {
                good_matches.Add (matchesList [i]);
            }
        }
        MatOfDMatch gm = new MatOfDMatch ();
        gm.fromList (good_matches);

        List<Point> objList = new List<Point> ();
        List<Point> sceneList = new List<Point> ();

        List<KeyPoint> keypoints_objectList = keypointsSrc.toList ();
        List<KeyPoint> keypoints_sceneList = keypointsScene.toList ();

        for (int i = 0; i < good_matches.Count; i++) {
            objList.Add (keypoints_objectList [good_matches [i].queryIdx].pt);
            sceneList.Add (keypoints_sceneList [good_matches [i].trainIdx].pt);
        }

        MatOfPoint2f obj = new MatOfPoint2f ();
        MatOfPoint2f scene = new MatOfPoint2f ();

        obj.fromList (objList); 
        scene.fromList (sceneList);

        Mat H = Calib3d.findHomography (obj, scene);
        Mat warpimg = matSrc.clone ();

        Mat srcRectMat = new Mat (4, 1, CvType.CV_32FC2);
        Mat dstRectMat = new Mat (4, 1, CvType.CV_32FC2);

        Point[] obj_corners = new Point[4];
        obj_corners [0] = new Point (0, 0);
        obj_corners [1] = new Point ((double)matSrc.cols (), 0);
        obj_corners [2] = new Point (matSrc.cols (), matSrc.rows ()); 
        obj_corners [3] = new Point (0, matSrc.rows ());

        Point[] scene_corners = new Point [4];

        MatOfPoint2f srcPointMat = new MatOfPoint2f (obj_corners);
        MatOfPoint2f dstPointMat = new MatOfPoint2f ();

        Core.perspectiveTransform (srcPointMat, dstPointMat, H);
        scene_corners = dstPointMat.toArray ();
        Mat resultImg = new Mat ();
        Features2d.drawMatches (matSrc, keypointsSrc, matScene, keypointsScene, matches, resultImg);

        Core.line (resultImg, AddPoints (scene_corners [0], new Point ((double)matSrc.cols (), 0)), AddPoints (scene_corners [1], new Point ((double)matSrc.cols (), 0)), new Scalar (0, 255, 0), 4);
        Core.line (resultImg, AddPoints (scene_corners [1], new Point ((double)matSrc.cols (), 0)), AddPoints (scene_corners [2], new Point ((double)matSrc.cols (), 0)), new Scalar (0, 255, 0), 4);
        Core.line (resultImg, AddPoints (scene_corners [2], new Point ((double)matSrc.cols (), 0)), AddPoints (scene_corners [3], new Point ((double)matSrc.cols (), 0)), new Scalar (0, 255, 0), 4);
        Core.line (resultImg, AddPoints (scene_corners [3], new Point ((double)matSrc.cols (), 0)), AddPoints (scene_corners [0], new Point ((double)matSrc.cols (), 0)), new Scalar (0, 255, 0), 4);


        Texture2D texture = new Texture2D (resultImg.cols (), resultImg.rows (), TextureFormat.RGBA32, false);
        Utils.matToTexture2D (resultImg, texture);
        gameObject.GetComponent<Renderer> ().material.mainTexture = texture;

    }

    Point AddPoints (Point p1, Point p2)
    {
        return new Point (p1.x + p2.x, p1.y + p2.y);
    }
}

}

0 个答案:

没有答案