2

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