2013-02-19 75 views
0

我刚刚冒险进入计算机视觉并试图揭开它的各种错综复杂的神秘面纱。我正在尝试用冲浪特征探测器来增强卡尔曼滤波器。但我不明白如何调用和使用卡尔曼方法后,单帧和有界矩形已构造在使用冲浪功能检测到的帧。我已经检测到这些功能,并在与传入帧进行比较后使用参考图像提取关键点。然后我使用了flann匹配器。OpenCV:基于特征检测的对象检测和跟踪

现在,使用卡尔曼滤波器是否可行,因为我想跟踪运动并获得预测运动。我搜索了很多,但没有发现,冲浪功能可以与卡尔曼滤波器一起使用。我所得到的是使用cvBlobs进行跟踪的建议。但是,理论上卡尔曼滤波器用于跟踪目的。然而,我很困惑,因为使用冲浪进行视频跟踪的几种实现方式表明,冲浪本身可用于跟踪。但我的问题是

  • 如果卡尔曼滤波器无法与冲浪使用,那么我该如何实现的时刻,因为我需要运动预测的信息,以获得坐标测量值。

  • 可以使用kalman过滤器进行跟踪,如果是,如何在检测到对象后使用以下代码检测对象并使用矩形进行绑定。

    示例:要跟踪的对象book1.png。一些帧frame1rame2

    /*目标检测和从视频识别*/

    INT主() { 垫对象= imread( “book1.png”,CV_LOAD_IMAGE_GRAYSCALE);

    if(!object.data) 
    { 
        std::cout<< "Error reading object " << std::endl; 
        return -1; 
    } 
    
    //Detect the keypoints using SURF Detector 
    int minHessian = 500; 
    
    SurfFeatureDetector detector(minHessian); 
    std::vector<KeyPoint> kp_object; 
    
    detector.detect(object, kp_object); 
    
    //Calculate descriptors (feature vectors) 
    SurfDescriptorExtractor extractor; 
    Mat des_object; 
    
    extractor.compute(object, kp_object, des_object); 
    
    FlannBasedMatcher matcher;   
    
    namedWindow("Good Matches"); 
    namedWindow("Tracking"); 
    
    std::vector<Point2f> obj_corners(4); 
    
    //Get the corners from the object 
    obj_corners[0] = cvPoint(0,0); 
    obj_corners[1] = cvPoint(object.cols, 0); 
    obj_corners[2] = cvPoint(object.cols, object.rows); 
    obj_corners[3] = cvPoint(0, object.rows); 
    
    char key = 'a'; 
    int framecount = 0; 
    VideoCapture cap("booksvideo.avi"); 
    
    for(; ;) 
    { 
        Mat frame; 
        cap >> frame; 
        imshow("Good Matches", frame); 
    
    
        Mat des_image, img_matches; 
        std::vector<KeyPoint> kp_image; 
        std::vector<vector<DMatch > > matches; 
        std::vector<DMatch > good_matches; 
        std::vector<Point2f> obj; 
        std::vector<Point2f> scene; 
        std::vector<Point2f> scene_corners(4); 
        Mat H; 
        Mat image; 
    
        //cvtColor(frame, image, CV_RGB2GRAY); 
    
        detector.detect(image, kp_image); 
        extractor.compute(image, kp_image, des_image); 
    
        matcher.knnMatch(des_object, des_image, matches, 2); 
    
        //THIS LOOP IS SENSITIVE TO SEGFAULTS 
        for(int i = 0; i < min(des_image.rows-1,(int) matches.size()); i++) 
        { 
         if((matches[i][0].distance < 0.6*(matches[i][4].distance)) && ((int) matches[i].size()<=2 && (int) matches[i].size()>0)) 
         { 
          good_matches.push_back(matches[i][0]); 
         } 
        } 
    
        //Draw only "good" matches 
        drawMatches(object, kp_object, image, kp_image, good_matches, img_matches, Scalar::all(-1), Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS); 
    
        if (good_matches.size() >= 4) 
        { 
         for(int i = 0; i < good_matches.size(); i++) 
         { 
          //Get the keypoints from the good matches 
          obj.push_back(kp_object[ good_matches[i].queryIdx ].pt); 
          scene.push_back(kp_image[ good_matches[i].trainIdx ].pt); 
         } 
    
         H = findHomography(obj, scene, CV_RANSAC); 
    
         perspectiveTransform(obj_corners, scene_corners, H); 
    
         //Draw lines between the corners (the mapped object in the scene image) 
         line(img_matches, scene_corners[0] + Point2f(object.cols, 0), scene_corners[1] + Point2f(object.cols, 0), Scalar(0, 255, 0), 4); 
         line(img_matches, scene_corners[1] + Point2f(object.cols, 0), scene_corners[2] + Point2f(object.cols, 0), Scalar(0, 255, 0), 4); 
         line(img_matches, scene_corners[2] + Point2f(object.cols, 0), scene_corners[3] + Point2f(object.cols, 0), Scalar(0, 255, 0), 4); 
         line(img_matches, scene_corners[3] + Point2f(object.cols, 0), scene_corners[0] + Point2f(object.cols, 0), Scalar(0, 255, 0), 4); 
    
        } 
    
        //Show detected matches 
        imshow("Good Matches", img_matches); 
        for(int i = 0; i < good_matches.size(); i++) 
        { 
         printf("-- Good Match [%d] Keypoint 1: %d -- Keypoint 2: %d \n", i, good_matches[i].queryIdx, good_matches[i].trainIdx); 
        } 
    
        waitKey(0); 
    

    }

    返回0;

    }

回答

2

我还没有见过特征匹配和筛选,你所描述的组合。我的一个想法是用卡尔曼滤波器跟踪质量中心(和大小),并在运行下一帧的特征匹配之前使用该信息来掩盖外部区域。我不确定你的约束是什么,但是你可能会考虑一个模板匹配或者camshift类型的跟踪,也可以使用卡尔曼过滤器来帮助搜索。

+1

好吧,那么如何使用camshift和surf?我发现这个代码使用颜色值http://opencv-srf.blogspot.ca/2010/09/object-detection-using-color-seperation.html。但是,这里的冲浪适用于灰度图像。因此,即使我使用灰度图,那么在使用冲浪检测到有界的矩形对象后,如何执行camshift。我将不胜感激,因为我不知道如何计算质心并使用camshift和surf来处理代码片断。 – 2013-02-20 06:19:38

+0

我还发现了一个类似的问题http://stackoverflow.com/questions/9701276/opencv-tracking-using-optical-flow/9702540#comment13031247_9702540但我想它不使用冲浪。所以,我在考虑是否可以将冲浪与https://code.ros.org/trac/opencv/browser/trunk/opencv/samples/c/motempl.c?rev=1429结合起来,但这是在C !如果我将Mat上的冲浪图像更改为IplImage,那么在update_mhi(IplImage * img,IplImage * dst,int diff_threshold)函数调用中应该怎么做以及我应该在冲浪模块中调用update_mhi()的位置。请帮忙。 – 2013-02-20 06:38:59

+0

主要目标是我需要找到检测到的物体的坐标,我认为这可以通过使用时刻完成。我不知道如何用冲浪特征检测来增加时刻,以便可以获得预测的运动。 – 2013-02-20 06:59:06