2

我想使用 meanshift 算法跟踪任何移动的物体。为此,我首先从背景中减去帧。然后应用腐蚀、膨胀和平滑。为了检测运动物体并找到它的坐标,我使用角点检测。

然后我计算角点的平均值,并将这些点传递给 meanshift 搜索窗口。现在当物体出现在屏幕上时,程序离开角点检测并进入meanshift跟踪。它一直在平均运行,直到对象离开屏幕。

现在如果物体离开屏幕,我想再次激活角点检测。为此,我将程序从 meanshift 中取出并跳回角点检测。该程序运行良好,但问题是当它离开 meanshift 并再次进入角点检测时,它会卡住几秒钟

之后,它运行顺利。该问题仅在从均值偏移到角点检测的过渡期间出现。我不知道可能是什么原因。请告诉我一些解决方案。

这是我的代码:

#include "highgui.h"
#include "cv.h"
#include "cxcore.h"
#include "cvaux.h"
#include <iostream>
using namespace std;
const int MAX_CORNERS = 500;

inline static void allocateOnDemand(IplImage** img, CvSize size, int depth, int channels) {
    if (*img != NULL) 
        return;

    *img = cvCreateImage(size, depth, channels);

    if (*img == NULL) {
        fprintf(stderr, "Error: Couldn't allocate image.  Out of memory?\n");
        exit(-1);
    }
}

int main() {
    CvCapture* capture = cvCaptureFromCAM(CV_CAP_V4L2);
    IplImage* pFrame[10];
    IplImage* bg;
    IplImage* img_A;
    IplImage* img_B;
    IplImage* eig_image;
    IplImage* tmp_image;
    img_A = cvQueryFrame(capture);
    CvSize img_sz = cvGetSize(img_A);
    int c1 = 0, c2 = 0;
    int xarr[40];
    //A temporary replacement for background averaging
    int j = 0;

    for (j = 0; j < 10; j++) {
        pFrame[j] = cvQueryFrame(capture);
        cvWaitKey(200);
    }

    cvSaveImage("10.jpg", pFrame[9], 0); //saving the background
    IplImage* imgA = cvCreateImage(cvGetSize(img_A), 8, 1);
    IplImage* imgB = cvCreateImage(cvGetSize(img_A), 8, 1);
    IplImage* imgB1 = cvCreateImage(cvGetSize(img_A), 8, 1);
    IplImage* imgb = cvCreateImage(cvGetSize(img_A), 8, 1);
    cvNamedWindow("LKpyr_OpticalFlow", CV_WINDOW_AUTOSIZE);
    bg = cvLoadImage("10.jpg", CV_LOAD_IMAGE_GRAYSCALE); //loading the saved background

    int flag = 0;
    int index = 0;
    char keypress;
    bool quit = false;
    CvConnectedComp*out = new CvConnectedComp(); //output window for meanshift
    int win_size = 25; //window size for corner point detection
    int x1 = 0;
    int y1 = 0;
    int x;
    int y;
    int cc;

line3: 
    while (quit == false) { //line3:
        IplImage* imgC = cvCreateImage(cvGetSize(img_A), 8, 1); //creating output image
        cvZero(imgC);
        img_B = cvQueryFrame(capture);
        imgC = cvQueryFrame(capture);
        // line3:
        int corner_count = MAX_CORNERS; //total no of corners found in frame
        cvCvtColor(img_B, imgb, CV_BGR2GRAY);
        //line3:
        CvPoint2D32f* cornersA = new CvPoint2D32f[MAX_CORNERS];
        CvPoint2D32f* cornersB = new CvPoint2D32f[MAX_CORNERS];

        if (index % 2 == 0) {
            cvSub(imgb, bg, imgB, NULL); //background subtraction and stuff
            cvErode(imgB, imgB, NULL, 4);
            cvDilate(imgB, imgB, 0, 2);
            cvSmooth(imgB, imgB, 0, 1);
            cvThreshold(imgB, imgB, 50, 255, CV_THRESH_BINARY);
            //line3:
            if (flag == 1) goto line1; //Go to Meanshift
            allocateOnDemand(&eig_image, img_sz, IPL_DEPTH_32F, 1);
            allocateOnDemand(&tmp_image, img_sz, IPL_DEPTH_32F, 1);
            cvCvtColor(img_A, imgA, CV_BGR2GRAY);
            //line3:
            cvGoodFeaturesToTrack(imgB, eig_image, tmp_image, cornersA, &
                corner_count, 0.05, 5.0, 0, 3, 0, 0.04); //detects corners and no of corners stored in corner_count
            cvFindCornerSubPix(imgB, cornersA, corner_count, cvSize(12, 12),
                cvSize(-1, -1), cvTermCriteria(CV_TERMCRIT_ITER |
                CV_TERMCRIT_EPS, 20, 0.03));
            CvPoint p0;
            CvPoint p1;
            CvPoint acc;
            cc = corner_count + 20;
            acc.x = 0;
            acc.y = 0;
            for (int i = 0; i < corner_count; i++) {
                p0 = cvPoint(cvRound(cornersA[i].x), cvRound(cornersA[i].y));
                p1 = cvPoint(cvRound(cornersB[i].x), cvRound(cornersB[i].y));
                acc.x = acc.x + p0.x; //calculating mean of corner points
                acc.y = acc.y + p0.y;
            }
            delete[] cornersA;
            delete[] cornersB;
            cout << "Corner Count is" << corner_count << endl;
            cout << "Flag status: " << flag << endl;

            if (corner_count > 0) {
                flag = 1;
                cvWaitKey(20);
            }

            x1 = cvRound(acc.x / (corner_count + 1));
            y1 = cvRound(acc.y / (corner_count + 1));
            cout << "x is " << x1 << " y is " << y1 << endl;
            cout << "Flag status: " << flag << endl;
            x = x1;
            y = y1;
            if (flag == 0) goto line2; //Go back to Corner Point detection
            line1: CvRect window = cvRect(x, y, 80, 90); //Creates window for meanshift algo
            cvMeanShift(imgB, window, cvTermCriteria(CV_TERMCRIT_EPS |
                CV_TERMCRIT_ITER, 200, 1), out);
            window = out->rect;
            x = out->rect.x;
            y = out->rect.y;
            cout << "Now x is " << x << " y is " << y << endl;
            cout << "Flag status: " << flag << endl;

            if (out->area > 200) {
                cvRectangle(imgC, cvPoint(x + 50, y + 100), cvPoint(x - 20, y -
                    90), cvScalar(0, 0, 255), 3, 8, 0);
            } else {}

            xarr[c1] = x;
            c1++;

            if (c1 > 39) c1 = 0;
            if (xarr[0] == xarr[39]) {
                c2 = 1;
                cout << "c2 is now " << c2 << endl;
            }
        }

        if (x == 0 || y == 0 || x < 7 || x > 572 || c2 == 1) {
            flag = 0;
            c2 = 0;
            goto line3;
            break;
        }

        line2: cvShowImage("LKpyr_OpticalFlow", imgC);
        keypress = cvWaitKey(20);
        // Set the flag to quit if escape was pressed

        if (keypress == 27) {
            quit = true;
        }
        //index++;
    } //end of while

    return 0;
}
4

0 回答 0