2017-02-20 77 views
1

我已經寫了一個代碼來創建邊界框並在裏面繪製Farneback光流。手動計算光流量,然後分別繪製每個ROI框。OpenCV繪製ROI中的Farneback光流。

當我繪製流程時,問題就出現了。流出來看起來很正常,但向下和向右移動。這是輸出結果,請注意右下方是流動人員的流動。

person is moving but flow drawn in wrong place

這裏是處處繪製的流,示出了流應繪製的幀。

Flow drawn everywhere to show where it should be

連接的代碼精簡爲簡單起見,所以原諒我,如果有幾個未申報矩陣或東西。

#include ... 

using namespace cv; 
using namespace std; 

Mat currentImage, img, printr, gray ,prevgray, flow; 

void getRectanglesandROI(Mat &Mask, Mat &imgTmp, Mat &imgOut, vector<Rect> &outBoxes); 

void DrawFlowMap(Mat Image, Mat ROI, Rect Box, Point centre); 

int main (int argc, char *argv[]) { 

    VideoCapture inVid("input.avi"); 

    if (!inVid.isOpened()) { 
     cout << "Failed to open the input video" << endl; 
     exit(5);} 

    int loop=0, count =0, MaxTargets=0; 
bool test=true; 

    namedWindow("Detected"); 

    int ex = inVid.get(CV_CAP_PROP_FOURCC); 
    double fps = inVid.get(CV_CAP_PROP_FPS); 
    int wait=1000/fps; 
    Size S = Size( (int) inVid.get(CV_CAP_PROP_FRAME_WIDTH), (int) inVid.get(CV_CAP_PROP_FRAME_HEIGHT)); 
    int fr =inVid.get(CV_CAP_PROP_FRAME_COUNT); 

    VideoWriter output;          // Open the output 
    output.open("output.avi", ex, fps, S, true); 
    if (!output.isOpened()) 
     { 
      cout << "Could not open the output video for write: " << endl; 
      return -1; 
     } 
//=============4EVR================= 
    while(test){ 

    inVid>>currentImage; 
     if (currentImage.empty()) 
     { 
      count++; 
      //if (count==1){if (waitKey(0)==27){waitKey(2);}} 
      if (count==1){fs.release(); break;} 
      cout <<"Max Targets=" <<MaxTargets<< endl<< "End of video, looping" << endl<<endl; 
      inVid.set(CV_CAP_PROP_POS_AVI_RATIO, 0); 
      loop=0; 
     } 

     cvtColor(currentImage, gray,CV_RGB2GRAY); 
     if (prevgray.empty()){gray.copyTo(prevgray);} 

     currentImage.copyTo(img); 

     calcOpticalFlowFarneback(prevgray,gray,flow,0.5,3,21,20,5,1.2,0); 

     vector<Rect> outputBoxes; 
     getRectanglesandROI(fgMaskMOG2, img, currentImage, outputBoxes); 
     gray.copyTo(prevgray); 

     imshow("Detected", currentImage); 
     waitKey(wait); 
    } 
    return 0; 
} 
//============END=========================================================== 

void getRectanglesandROI(Mat &Mask, Mat &imgTmp, Mat &imgOut, vector<Rect> &outBoxes){ 

    vector<vector<Point> > v; 
vector<int> targets; 
int tarArea=1; 

    findContours(Mask, v, CV_RETR_EXTERNAL/*CV_RETR_LIST*/, CV_CHAIN_APPROX_SIMPLE); 

    for (int j = 0; j < v.size(); j++) { 
      if (tarArea < v[j].size()) { // excluding tiny contours 
        targets.push_back(j); 
      } 
    } 
     for (int j = 0; j < targets.size(); j++) { 
      drawContours(imgTmp, v, targets[j], Scalar(255, 0, 255), 1, 8); 
      Rect rect = boundingRect(v[targets[j]]); 

      roi=currentImage(rect); 
      DrawFlowMap(currentImage, roi, rect); 
      } 
} 

void DrawFlowMap(Mat Image, Mat ROI, Rect Box){ 

Point pt1 = Point(Box.x, Box.y); 

for(int y=0; y<roi.rows; y+=5){  //this is the issue area, probably. 
    for (int x=0;x<roi.cols;x+=5){ 
     const Point2f& flowatxy=flow.at<Point2f>(y,x); 

      line(Image, Point(cvRound(pt1.x+x),    cvRound(pt1.y+y)), 
         Point(cvRound(pt1.x+x+flowatxy.x), cvRound(pt1.y+y+flowatxy.y)), Scalar(0,255,0)); ///FLOW LINES 
    } 
} 
} 

回答

0

易peasy,在圖像尋找了一段時間後(哭)我注意到,它是繪製在正確的地方流動,但在那個地方flowatxy是錯誤的。所以我將flowatxy聲明更改爲以下內容:

const Point2f& flowatxy=flow.at<Point2f>(pt1.y+y , pt1.x+x);