2013-04-13 61 views
3

從一個SO答案中,使用光流分割需要密集光流。我修改了this code。它使用calcOpticalFlowFarneback函數計算兩個連續幀之間的密集流場。OpenCV C++基於光流的分割代碼拋出異常

根據該SO答案herehere,我試圖使用

SQRT來計算位移的大小(displacement_in_x^2 + displacement_in_y^2)

該函數返回位移CV_32FC2

這是我的代碼: -

#include "stdafx.h" 

#include "cv.h" 
#include "highgui.h" 
#include <iostream> 


using namespace cv; 
using namespace std; 

void drawOptFlowMap(const Mat& flow, Mat& cflowmap, int step, 
        double scale, const Scalar& color) 
{ 
    for(int y = 0; y < cflowmap.rows; y += step) 
     for(int x = 0; x < cflowmap.cols; x += step) 
     { 
      const Point2f& fxy = flow.at<Point2f>(y, x); 
      line(cflowmap, Point(x,y), Point(cvRound(x+fxy.x), cvRound(y+fxy.y)), 
       color); 
      circle(cflowmap, Point(x,y), 2, color, -1); 
     } 
} 

int main() 
{ 
    VideoCapture cap("vip.avi"); 


    if(!cap.isOpened()) 
     return -1; 

    Mat prevgray, gray, flow, cflow, frame; 
    double col = cap.get(CV_CAP_PROP_FRAME_WIDTH); 
    double row = cap.get(CV_CAP_PROP_FRAME_HEIGHT); 
    Mat flow_img = Mat::zeros(row,col,CV_8UC1); 

    namedWindow("flow", 1); 
    namedWindow("segmented",1); 

    for(;;) 
    { 
     cap >> frame; 
     cvtColor(frame, gray, CV_BGR2GRAY); 

     if(prevgray.data) 
     { 
      calcOpticalFlowFarneback(prevgray, gray, flow, 0.5, 3, 15, 15, 5, 1.2, 0); 
      cvtColor(prevgray, cflow, CV_GRAY2BGR); 
      drawOptFlowMap(flow, cflow, 8, 1.5, CV_RGB(0, 255, 0)); 
      imshow("flow", cflow); 
     } 

     //This part I added to compute Magnitude of flow 
for(int i=0;i<gray.rows;i++) 
    for(int j=0;j<gray.cols;j++) 
     flow_img.at<uchar>(i,j)= cvRound( sqrt (pow (flow.at<Vec2f>(i,j)[0] ,2)+ pow (flow.at<Vec2f>(i,j)[1],2))); 

//threshold image 
threshold(flow_img,flow_img,10,255,THRESH_BINARY); //some arbitrary thresh value 10 

     imshow("segmented",flow_img); 

     if(waitKey(30)>=0) 
      break; 

     std::swap(prevgray, gray); 
    } 
    return 0; 
} 

我正在使用Microsoft Visual C++ 2010,並且沒有生成錯誤。但是,該方案不會運行,並拋出了以下內容:

build error

在控制檯窗口中,我得到:

c0nsole

我不明白,我所犯的錯誤。任何人都可以請幫助我。有類似的SO問題here,答案是我使用的代碼。儘管如此,我得到上述

你可以找到我的輸入視頻中提到的問題herehere

+0

哪一行導致異常? Visual Studio應該通過標記來顯示它,如果沒有通過調試代碼檢查它。 – cyriel

+0

它沒有標記任何東西...一個窗口彈出顯示圖像(更新在我的qn)...當我調試它並沒有顯示任何問題...代碼運行顯示流向量的輸出幾秒鐘,然後退出顯示上面.. –

+0

上傳某處thie AVI文件 - 我會檢查,所以我可以自己檢查。 – cyriel

回答

0

您確保line`

const Point2f& fxy = flow.at<Point2f>(y, x); 

被允許? Point2f不是cv::Mat類文檔中描述的類型之一。 改爲使用cv::Vec2f作爲模板參數。然後,您可以填寫結果Point2f變量。

下一個問題是:在你計算流量的8位幅度線,這將是更安全的使用saturate_cast操作:

flow_img.at<uchar>(i,j)= cv::saturate_cast<uchar>(cvRound( sqrt (pow (flow.at<Vec2f>(i,j)[0] ,2)+ pow (flow.at<Vec2f>(i,j)[1],2)))); 

還不確定,這是造成你的程序不幸崩潰。

錯誤告訴你的是你正在調用一個OpenCV函數的參數錯誤。在調試模式下,在程序中逐步執行,以便我們知道哪一個。

+0

我嘗試了** const Point2f&fxy = flow.at (y,x); **但仍然在幾秒鐘後退出代碼... –

+0

對不起,我用另一個問題完成了我的答案,但我認爲我沒有發現錯誤。請參閱我的回答結束提示。 – sansuiso

0

的代碼行

std::swap(prevgray, gray); 

可能導致問題,因爲化std :: swap的行爲是

c(a); a=b; b=c; 

,並以這種方式=運算符時,不應用深您的輸入圖像的副本。更好地使用

gray.copyTo(prevgray); 

爲prevgray分配自己的內存。否則prevgray的數據指針指向灰色的內容。