2013-04-13 6 views
3

광학 흐름을 사용하는 세분화를 위해 SO 응답 중 하나에서 밀도가 높은 광학 흐름이 필요합니다. 나는 this code을 수정했다. 그것은 연속적인 두 프레임 사이의 조밀 한 유동장을 계산하기 위해 calcOpticalFlowFarneback 함수를 사용합니다.OpenCV C++ 옵티컬 플로를 기반으로하는 분할 코드에서 예외가 발생합니다.

가 너무 herehere 답변에 따르면, I는

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

나는 내가 실수를 한 곳 이해 해달라고. 아무도 나를 도와주세요. 비슷한 질문이 here 있었고 대답은 제가 사용한 코드입니다. 아직도 내가 문제가

내 입력 비디오 찾을 수 있습니다 위에서 언급 얻을here 또는

+0

어떤 줄에서 예외가 발생합니까? Visual Studio는 코드를 디버깅하여 검사하지 않으면이를 표시하여 표시해야합니다. – cyriel

+0

그것은 아무것도 표시하지 않습니다 ... 창 (내 qn에서 업데이트 된) 이미지를 보여주는 팝업 ... 내가 그것을 디버깅 할 때 어떤 문제가 표시되지 않습니다 ... 코드는 몇 초 동안 흐름 벡터의 출력을 표시하고 표시 종료 위 .. –

+0

어딘가에 thie avi 파일 업로드 - 내가 확인합니다, 그래서 나는 그것을 스스로 확인할 수 있습니다. – cyriel

답변

0

here 당신은 line`

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

이 허용되어 있는지 확인 있습니까? Point2fcv::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

** point2f & fxy = flow.at (y, x); **로 시도했지만 몇 초 후에 코드가 종료됩니다 ... –

+0

죄송합니다 , 다른 답변으로 내 대답을 완료했지만 오류를 발견했다고 생각하지 않습니다. 힌트에 대한 내 대답의 끝을 참조하십시오. – sansuiso

0

표준 : 스왑의 동작 이후

std::swap(prevgray, gray); 

문제가 발생할 수있는 코드 라인은

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

하고 그런 식으로 = 연산자는 깊은을 적용하지 않는, 사용 입력 이미지의 사본.더 나은 사용

gray.copyTo(prevgray); 

prevgray에 대한 자신의 메모리를 할당 할 수 있습니다. 그렇지 않으면 prevgray의 데이터 포인터가 회색의 내용을 가리 킵니다.