簡體   English   中英

如何在Android中使用Opencv檢測非靜止背景中物體的存在?

[英]How to detect the presence of an object in a non-stationary background using Opencv in Android?

我正在開發一個應用程序來處理幀,並在 Android 中使用 Opencv 實時進行分割和圖像匹配。

主要問題是,只有當要處理的對象在相機幀中可用並且背景不穩定時,我才需要開始此圖像處理,這使我的任務更加困難。

我嘗試了許多解決方案,例如使用absdiff運動檢測,這是代碼

    imgSource = inputFrame.rgba().t();
    Core.transpose(imgSource, imgSource);

    //imgSource.convertTo(enhancedMat, imgSource.type(), 1.3);



    gray = imgSource;
    Imgproc.cvtColor(imgSource, gray, Imgproc.COLOR_BGR2GRAY);
    Imgproc.GaussianBlur(gray, gray, new Size(25, 25), 5);
    if (firstframe == null) {
        firstframe = gray;
    }
    Core.absdiff(firstframe, gray, frameDelta);
    Imgproc.threshold(frameDelta, frameDelta, 25, 255, Imgproc.THRESH_BINARY);
    for (int i =0 ; i <2 ; i++)
        Imgproc.dilate(frameDelta, frameDelta, Imgproc.getStructuringElement(Imgproc.THRESH_BINARY, new Size(3, 3)));

    Imgproc.findContours(frameDelta, abs_contours, abs_hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
    for (int idx = 0; idx < abs_contours.size(); idx++) {

        double a = Imgproc.contourArea(abs_contours.get(idx));  //Find the area of contour

        if (a < 10000) {

            continue;
        }

        Rect rect = Imgproc.boundingRect(abs_contours.get(idx));
        Imgproc.rectangle(imgSource, rect.tl(), rect.br(), new Scalar(0, 255, 0), 2);
    }

我還嘗試使用此createBackgroundSubtractorMOG2方法createBackgroundSubtractorMOG2背景減法。

他們都沒有工作,因為背景也在移動,所以這些邏輯根本不健壯。

對於此類問題,我必須遵循任何方法或任何解決方案嗎?

我希望你們能指導我找到一個好的解決方案,並在此先感謝你們。

為了解決這個問題,我使用了光流

您可以使用calcOpticalFlowFarneback計算每個幀上的光流。

然后,您將獲得圖像的每個像素的 2 個分量矩陣(x 方向和 y 方向的梯度)。

我計算了每個點atan2(flow_y,flow_x)並將其存儲在vector<Point2f>

然后,只需使用 kmeans 和 2 個標簽進行聚類。 (將背景與序列中的前景移動對象區分開來)。

kmeans 返回的矩陣為您提供標簽。

希望能幫助到你 !

編輯 :

我一直在使用 OpenCV C++,但這是我的代碼

int calculateOptFlow(Mat prev_frame, Mat frame, Mat& output) 
{
    Mat flow;

    //the algorithm uses gray images
    cvtColor(frame,frame,CV_BGR2GRAY);
    cvtColor(prev_frame,prev_frame,CV_BGR2GRAY);

    calcOpticalFlowFarneback(prev_frame, frame, flow,0.4, 1, 12, 2, 8, 1.2, 0);

    Mat angle(flow.rows,flow.cols,CV_32FC1);
    Mat dst(flow.rows,flow.cols,CV_32FC1);
    vector<Point2f> samples(flow.rows*flow.cols);

    int n=0;
    for(int y=0;y<flow.rows;y++)
    {
        for(int x=0;x<flow.cols ; x++)
        {

            angle.at<float>(y,x) = (atan2(flow.at<Point2f>(y,x).y,flow.at<Point2f>(y,x).x));
            samples[n++] =  flow.at<Point2f>(y,x);
        }
    }

    // split into 2 clusters : background and foreground
    Mat labels,centers;
    kmeans(samples,2,labels,TermCriteria(TermCriteria::EPS+TermCriteria::COUNT,10,1.0),3,KMEANS_PP_CENTERS,centers);

    // create a B&W matrix from the labels
    for(int i=0;i<(int)samples.size();i++)
    {
        int row = static_cast<int>(i/dst.cols);
        int col = i%dst.cols;
        if(labels.at<int>(i) == 1)
        {
            dst.at<float>(row,col) = 255;
        }
        else
        {
            dst.at<float>(row,col) = 0;
        }
    }

    //conversion for the use of findContours afterwards
    dst.convertTo(output,CV_8UC1);

    return 1;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM