2016-05-08 8 views
0

私は、追跡中のオブジェクトの位置(x、y)をテキストファイルに記録しようとしています。 私はopencvとC++ visual 2010を使用しています。これまではデータを保存することができましたが、このデータは最初の位置ですが繰り返しました。私はすべてのフレームで実際の位置を保存したい。要するに、画面上でPutText()によって書き込まれた正確なデータをファイルに書き込むにはどうすればよいですか?追跡中のオブジェクトの位置(x、y)をテキストファイルに書き込む方法は?

//save position 
ofstream file_; 
file_.open("position.txt"); 
file_ <<"these are the position pattern made by the foreground object \n"; 
for(int count = -1; count < 10000; count++) 
{ 
    file_ <<"X:"<<intToString(x)<<" "<<"Y:"<<intToString(y)<<"\n"; 


} 
file_.close(); 

完全なコードはこれです:

#include < opencv2/opencv.hpp> 
#include < opencv2/core/core.hpp> 
#include < opencv2/highgui/highgui.hpp> 
#include < opencv2/video/background_segm.hpp> 
#include < opencv2/imgproc/imgproc.hpp> 
#include < opencv2/video/video.hpp> 
//#include < opencv2/videoio.hpp> 
//#include < opencv2/imgcodecs.hpp> 
//C 
#include <stdio.h> 
//C++ 
#include <iostream> 
#include <sstream> 
#include <fstream> 

using namespace cv; 
using namespace std; 

//global variables 
cv::Mat fg_mask; 
cv::Mat frame; 
cv::Mat binaryImage; 
cv::Mat ContourImg; 
Ptr<BackgroundSubtractor> pMOG; //MOG Background subtractor 
int keyboard; //input from keyboard 
//we'll have just one object to search for 
//and keep track of its position. 
int theObject[2] = {0,0}; 
//bounding rectangle of the object, we will use the center of this as its position. 
Rect objectBoundingRectangle = Rect(0,0,0,0); 
//our sensitivity value to be used 
const static int SENSITIVITY_VALUE = 50; 

string intToString(int number){ 

//this function has a number input and string output 
std::stringstream ss; 
ss << number; 
return ss.str(); 
} 
void searchForMovement(Mat binaryImage, Mat &framein){ 
//notice how we use the '&' operator for objectDetected and cameraFeed. This is because we wish 
//to take the values passed into the function and manipulate them, rather t han just working with a copy. 
//eg. we draw to the cameraFeed to be displayed in the main() function. 
bool objectDetected = false; 
Mat temp; 
binaryImage.copyTo(temp); 
//these two vectors needed for output of findContours 
vector< vector<Point> > contours; 
vector<Vec4i> hierarchy; 
//find contours of filtered image using openCV findContours function 
//findContours(temp,contours,hierarchy,CV_RETR_CCOMP,CV_CHAIN_APPROX_SIMPLE);// retrieves all contours 
findContours(temp,contours,hierarchy,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE);// retrieves external contours 

//if contours vector is not empty, we have found some objects 
if(contours.size()>0)objectDetected=true; 
else objectDetected = false; 

if(objectDetected){ 
    //the largest contour is found at the end of the contours vector 
    //we will simply assume that the biggest contour is the object we are looking for. 
    vector< vector<Point> > largestContourVec; 
    largestContourVec.push_back(contours.at(contours.size()-1)); 
    //make a bounding rectangle around the largest contour then find its centroid 
    //this will be the object's final estimated position. 
    objectBoundingRectangle = boundingRect(largestContourVec.at(0)); 
    int xpos = objectBoundingRectangle.x+objectBoundingRectangle.width/2; 
    int ypos = objectBoundingRectangle.y+objectBoundingRectangle.height/2; 

    //update the objects positions by changing the 'theObject' array values 
    theObject[0] = xpos , theObject[1] = ypos; 
} 
//make some temp x and y variables so we dont have to type out so much 
int x = theObject[0]; 
int y = theObject[1]; 

//draw some crosshairs around the object 
circle(framein,Point(x,y),20,Scalar(0,255,0),2); 
line(framein,Point(x,y),Point(x,y-25),Scalar(0,255,0),2); 
line(framein,Point(x,y),Point(x,y+25),Scalar(0,255,0),2); 
line(framein,Point(x,y),Point(x-25,y),Scalar(0,255,0),2); 
line(framein,Point(x,y),Point(x+25,y),Scalar(0,255,0),2); 

//write the position of the object to the screen 
putText(framein,"Tracking object at (" + intToString(x)+","+intToString(y)+")",Point(x,y),1,1,Scalar(255,0,0),2); 

//save position 
ofstream file_; 
file_.open("position.txt"); 
file_ <<"these are the position pattern made by the foreground object \n"; 
for(int count = -1; count < 10000; count++) 
{ 
    file_ <<"X:"<<intToString(x)<<" "<<"Y:"<<intToString(y)<<"\n"; 


} 
file_.close(); 
//std::cin.get(); 


    } 

    void morphOps(Mat &thresh){ 

    //create structuring element that will be used to "dilate" and "erode" image. 
    //the element chosen here is a 3px by 3px rectangle 

    Mat erodeElement = getStructuringElement(MORPH_RECT,Size(2,2)); //3x3 
    //dilate with larger element so make sure object is nicely visible 
    Mat dilateElement = getStructuringElement(MORPH_RECT,Size(1,1)); //8x8 

    erode(thresh,thresh,erodeElement); 
    erode(thresh,thresh,erodeElement); 


    dilate(thresh,thresh,dilateElement); 
    dilate(thresh,thresh,dilateElement); 

    } 
int main(int, char**) 
{ 
//some boolean variables for added functionality 
bool objectDetected = false; 
//these two can be toggled by pressing 'd' or 't' 
bool debugMode = true; 
bool trackingEnabled = true; 
//pause and resume code 
bool pause = false; 
//video capture object. 
VideoCapture capture; 
while(1){ 

    //we can loop the video by re-opening the capture every time the video reaches its last frame 

    capture.open("Video_003.avi"); 
    //capture.open(0); 

    if(!capture.isOpened()){ 
     cout<<"ERROR ACQUIRING VIDEO FEED\n"; 
     getchar(); 
     return -1; 
    } 
    double fps = capture.get(CV_CAP_PROP_FPS); //get the frames per seconds of the video 
    cout << "Frame per seconds : " << fps << endl; 

pMOG = new BackgroundSubtractorMOG(); 

//morphology element 
Mat element = getStructuringElement(MORPH_RECT, Size(7, 7), Point(3,3)); 

int count = -1; 

//check if the video has reach its last frame. 
    //we add '-1' because we are reading two frames from the video at a time. 
    //if this is not included, we get a memory error! 
    while(capture.get(CV_CAP_PROP_POS_FRAMES) <capture.get(CV_CAP_PROP_FRAME_COUNT)-1){ 
    // Get frame from camera 
     capture.read(frame); 
    // Update counter 
    ++count; 
    //Resize 
resize(frame, frame, Size(frame.size().width/2, frame.size().height/2)); 
    //Blur 
    blur(frame, frame, Size(5,5)); 

    // Background subtraction 
    pMOG->operator()(frame, fg_mask,0.05); 

    //////// 
    //pre procesing 
    //1 point delete  
    morphologyEx(fg_mask, binaryImage, CV_MOP_CLOSE, element); 

    // threshold 
    //threshold intensity image at a given sensitivity value 
      cv::threshold(binaryImage,binaryImage,SENSITIVITY_VALUE,255,THRESH_BINARY); 
     morphOps(binaryImage); 

    if(debugMode==true){ 

    imshow("frame", frame); 
    imshow("fg_mask", fg_mask); 
    imshow("final", binaryImage); 
    }else{ 
      //if not in debug mode, destroy the windows so we don't see them anymore 
      cv::destroyWindow("frame"); 
      cv::destroyWindow("fg_mask"); 
      cv::destroyWindow("final"); 
    } 

    //if tracking enabled, search for contours in our thresholded image 
     if(trackingEnabled){ 

      searchForMovement(binaryImage,frame); 

    //Find contour 
    ContourImg = binaryImage.clone(); 
    //less blob delete 
    vector< vector< Point> > contours; 

    findContours(ContourImg, 
     contours, // a vector of contours 
     CV_RETR_EXTERNAL, // retrieve the external contours 
     CV_CHAIN_APPROX_NONE); // all pixels of each contours 


vector<Rect> output; 
    vector< vector< Point> >::iterator itc= contours.begin(); 
    while (itc!=contours.end()) { 

//Create bounding rect of object 
//rect draw on origin image 
Rect mr= boundingRect(Mat(*itc)); 
rectangle(frame, mr, CV_RGB(255,0,0)); 
++itc; 
    } 
     } 
     imshow("frame", frame); 
    // Save foreground mask 
    string name = "mask_" + std::to_string(static_cast<long long>(count)) + ".png"; 
    imwrite("D:\\SO\\temp\\" + name, fg_mask); 

    switch(waitKey(10)){ 

     case 27: //'esc' key has been pressed, exit program. 
      return 0; 
     case 116: //'t' has been pressed. this will toggle tracking 
      trackingEnabled = !trackingEnabled; 
      if(trackingEnabled == false) cout<<"Tracking disabled."<<endl; 
      else cout<<"Tracking enabled."<<endl; 
      break; 
     case 100: //'d' has been pressed. this will debug mode 
      debugMode = !debugMode; 
      if(debugMode == true) cout<<"Debug mode enabled."<<endl; 
      else cout<<"Debug mode disabled."<<endl; 
      break; 
     case 112: //'p' has been pressed. this will pause/resume the code. 
      pause = !pause; 
      if(pause == true){ cout<<"Code paused, press 'p' again to resume"<<endl; 
      while (pause == true){ 
       //stay in this loop until 
       switch (waitKey()){ 
        //a switch statement inside a switch statement? Mind blown. 
       case 112: 
        //change pause back to false 
        pause = false; 
        cout<<"Code Resumed"<<endl; 
        break; 
       } 

} 
// the camera will be deinitialized automatically in VideoCapture destructor 

      } 
    } 
    } 
    //release the capture before re-opening and looping again. 
    capture.release(); 
    } 
    return 0; 
    } 
+0

なぜあなたは二回収縮と膨張を適用していますか? – black

+0

まあ、私は、フォアグラウンドオブジェクトの外観を強化するために、ウェブからのいくつかの提案に従っています。 ちなみに、ノイズを減らす方法はありますか?まだノイズが多い – Zakarya

+0

2回連続して呼び出すと、カーネルサイズを大きくするよりもはるかに遅くなります。 ノイズを低減するには、最初にガウスぼかしを使用します。他の質問については、新しい質問を開いてください。 – black

答えて

2

OK、私はいくつか見 puttextは()画面

//write the position of the object to the screen 
putText(framein,"Tracking object at (" + intToString(x)+","+intToString(y)+")",Point(x,y),1,1,Scalar(255,0,0),2); 

に書き込むか見て私はこの問題は、この部分にあると思いますあなたのコードに奇妙なことがあります。しかし、あなたの質問に答えるには:

あなたのコードでは、あなたはxとyの10000回と閉じたファイル各フレームの同じ値を出力ファイルを開いています。代わりに、あなたがすべきことは、最初にファイルを開くことです.座標の1組だけがフレームあたりになり、最後にファイルを閉じます。

例コード:メインループの前

メインループが終了

file_ <<"X:"<<intToString(x)<<" "<<"Y:"<<intToString(y)<<"\n"; 

後、メインループで

ofstream file_; 
file_.open("position.txt"); 
file_ <<"these are the position pattern made by the foreground object \n"; 

を開始

file_.close(); 

EDIT:追加されました完全なコード、それがあるために、私は意味の方法:

#include < opencv2/opencv.hpp> 
#include < opencv2/core/core.hpp> 
#include < opencv2/highgui/highgui.hpp> 
#include < opencv2/video/background_segm.hpp> 
#include < opencv2/imgproc/imgproc.hpp> 
#include < opencv2/video/video.hpp> 
//#include < opencv2/videoio.hpp> 
//#include < opencv2/imgcodecs.hpp> 
//C 
#include <stdio.h> 
//C++ 
#include <iostream> 
#include <sstream> 
#include <fstream> 

using namespace cv; 
using namespace std; 

ofstream file_; 

//global variables 
cv::Mat fg_mask; 
cv::Mat frame; 
cv::Mat binaryImage; 
cv::Mat ContourImg; 
Ptr<BackgroundSubtractor> pMOG; //MOG Background subtractor 
int keyboard; //input from keyboard 
//we'll have just one object to search for 
//and keep track of its position. 
int theObject[2] = {0,0}; 
//bounding rectangle of the object, we will use the center of this as its position. 
Rect objectBoundingRectangle = Rect(0,0,0,0); 
//our sensitivity value to be used 
const static int SENSITIVITY_VALUE = 50; 

string intToString(int number){ 

    //this function has a number input and string output 
    std::stringstream ss; 
    ss << number; 
    return ss.str(); 
} 
void searchForMovement(Mat binaryImage, Mat &framein){ 
    //notice how we use the '&' operator for objectDetected and cameraFeed. This is because we wish 
    //to take the values passed into the function and manipulate them, rather t han just working with a copy. 
    //eg. we draw to the cameraFeed to be displayed in the main() function. 
    bool objectDetected = false; 
    Mat temp; 
    binaryImage.copyTo(temp); 
    //these two vectors needed for output of findContours 
    vector< vector<Point> > contours; 
    vector<Vec4i> hierarchy; 
    //find contours of filtered image using openCV findContours function 
    //findContours(temp,contours,hierarchy,CV_RETR_CCOMP,CV_CHAIN_APPROX_SIMPLE);// retrieves all contours 
    findContours(temp,contours,hierarchy,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE);// retrieves external contours 

    //if contours vector is not empty, we have found some objects 
    if(contours.size()>0)objectDetected=true; 
    else objectDetected = false; 

    if(objectDetected){ 
     //the largest contour is found at the end of the contours vector 
     //we will simply assume that the biggest contour is the object we are looking for. 
     vector< vector<Point> > largestContourVec; 
     largestContourVec.push_back(contours.at(contours.size()-1)); 
     //make a bounding rectangle around the largest contour then find its centroid 
     //this will be the object's final estimated position. 
     objectBoundingRectangle = boundingRect(largestContourVec.at(0)); 
     int xpos = objectBoundingRectangle.x+objectBoundingRectangle.width/2; 
     int ypos = objectBoundingRectangle.y+objectBoundingRectangle.height/2; 

     //update the objects positions by changing the 'theObject' array values 
     theObject[0] = xpos , theObject[1] = ypos; 
    } 
    //make some temp x and y variables so we dont have to type out so much 
    int x = theObject[0]; 
    int y = theObject[1]; 

    //draw some crosshairs around the object 
    circle(framein,Point(x,y),20,Scalar(0,255,0),2); 
    line(framein,Point(x,y),Point(x,y-25),Scalar(0,255,0),2); 
    line(framein,Point(x,y),Point(x,y+25),Scalar(0,255,0),2); 
    line(framein,Point(x,y),Point(x-25,y),Scalar(0,255,0),2); 
    line(framein,Point(x,y),Point(x+25,y),Scalar(0,255,0),2); 

    //write the position of the object to the screen 
    putText(framein,"Tracking object at (" + intToString(x)+","+intToString(y)+")",Point(x,y),1,1,Scalar(255,0,0),2); 

    //save position 
    file_ <<"X:"<<intToString(x)<<" "<<"Y:"<<intToString(y)<<"\n"; 

    //std::cin.get(); 


} 

void morphOps(Mat &thresh){ 

    //create structuring element that will be used to "dilate" and "erode" image. 
    //the element chosen here is a 3px by 3px rectangle 

    Mat erodeElement = getStructuringElement(MORPH_RECT,Size(2,2)); //3x3 
    //dilate with larger element so make sure object is nicely visible 
    Mat dilateElement = getStructuringElement(MORPH_RECT,Size(1,1)); //8x8 

    erode(thresh,thresh,erodeElement); 
    erode(thresh,thresh,erodeElement); 


    dilate(thresh,thresh,dilateElement); 
    dilate(thresh,thresh,dilateElement); 

} 
int main(int, char**) 
{ 

    file_.open("position.txt"); 
    file_ <<"these are the position pattern made by the foreground object \n"; 

    //some boolean variables for added functionality 
    bool objectDetected = false; 
    //these two can be toggled by pressing 'd' or 't' 
    bool debugMode = true; 
    bool trackingEnabled = true; 
    //pause and resume code 
    bool pause = false; 
    //video capture object. 
    VideoCapture capture; 

    while(1){ 

     //we can loop the video by re-opening the capture every time the video reaches its last frame 

     capture.open("Video_003.avi"); 
     //capture.open(0); 

     if(!capture.isOpened()){ 
      cout<<"ERROR ACQUIRING VIDEO FEED\n"; 
      getchar(); 
      return -1; 
     } 
     double fps = capture.get(CV_CAP_PROP_FPS); //get the frames per seconds of the video 
     cout << "Frame per seconds : " << fps << endl; 

     pMOG = new BackgroundSubtractorMOG(); 

     //morphology element 
     Mat element = getStructuringElement(MORPH_RECT, Size(7, 7), Point(3,3)); 

     int count = -1; 

     //check if the video has reach its last frame. 
     //we add '-1' because we are reading two frames from the video at a time. 
     //if this is not included, we get a memory error! 
     while(capture.get(CV_CAP_PROP_POS_FRAMES) <capture.get(CV_CAP_PROP_FRAME_COUNT)-1){ 
      // Get frame from camera 
      capture.read(frame); 
      // Update counter 
      ++count; 
      //Resize 
      resize(frame, frame, Size(frame.size().width/2, frame.size().height/2)); 
      //Blur 
      blur(frame, frame, Size(5,5)); 

      // Background subtraction 
      pMOG->operator()(frame, fg_mask,0.05); 

      //////// 
      //pre procesing 
      //1 point delete 
      morphologyEx(fg_mask, binaryImage, CV_MOP_CLOSE, element); 

      // threshold 
      //threshold intensity image at a given sensitivity value 
      cv::threshold(binaryImage,binaryImage,SENSITIVITY_VALUE,255,THRESH_BINARY); 
      morphOps(binaryImage); 

      if(debugMode==true){ 

       imshow("frame", frame); 
       imshow("fg_mask", fg_mask); 
       imshow("final", binaryImage); 
      }else{ 
       //if not in debug mode, destroy the windows so we don't see them anymore 
       cv::destroyWindow("frame"); 
       cv::destroyWindow("fg_mask"); 
       cv::destroyWindow("final"); 
      } 

      //if tracking enabled, search for contours in our thresholded image 
      if(trackingEnabled){ 

       searchForMovement(binaryImage,frame); 

       //Find contour 
       ContourImg = binaryImage.clone(); 
       //less blob delete 
       vector< vector< Point> > contours; 

       findContours(ContourImg, 
          contours, // a vector of contours 
          CV_RETR_EXTERNAL, // retrieve the external contours 
          CV_CHAIN_APPROX_NONE); // all pixels of each contours 


       vector<Rect> output; 
       vector< vector< Point> >::iterator itc= contours.begin(); 
       while (itc!=contours.end()) { 

        //Create bounding rect of object 
        //rect draw on origin image 
        Rect mr= boundingRect(Mat(*itc)); 
        rectangle(frame, mr, CV_RGB(255,0,0)); 
        ++itc; 
       } 
      } 
      imshow("frame", frame); 
      // Save foreground mask 
      string name = "mask_" + std::to_string(static_cast<long long>(count)) + ".png"; 
      imwrite("D:\\SO\\temp\\" + name, fg_mask); 

      switch(waitKey(10)){ 

       case 27: //'esc' key has been pressed, exit program. 
        return 0; 
       case 116: //'t' has been pressed. this will toggle tracking 
        trackingEnabled = !trackingEnabled; 
        if(trackingEnabled == false) cout<<"Tracking disabled."<<endl; 
        else cout<<"Tracking enabled."<<endl; 
        break; 
       case 100: //'d' has been pressed. this will debug mode 
        debugMode = !debugMode; 
        if(debugMode == true) cout<<"Debug mode enabled."<<endl; 
        else cout<<"Debug mode disabled."<<endl; 
        break; 
       case 112: //'p' has been pressed. this will pause/resume the code. 
        pause = !pause; 
        if(pause == true){ cout<<"Code paused, press 'p' again to resume"<<endl; 
         while (pause == true){ 
          //stay in this loop until 
          switch (waitKey()){ 
           //a switch statement inside a switch statement? Mind blown. 
           case 112: 
            //change pause back to false 
            pause = false; 
            cout<<"Code Resumed"<<endl; 
            break; 
          } 

         } 
         // the camera will be deinitialized automatically in VideoCapture destructor 

        } 
      } 
     } 
     //release the capture before re-opening and looping again. 
     capture.release(); 
     //Close position log 
     file_.close(); 
    } 
    return 0; 
} 
+0

そうだ、私はエラーが "この宣言は、ストレージクラスまたは型指定子を開始と終了の部分がありません" – Zakarya

+0

"ofstream file_;" "using namespace std;"の行のすぐ下の部分です。これをグローバル変数にします。そうすればどこからでも参照できます。これは実際には実用的ではありませんが、少なくともあなたの例では、それは後で良いpraticesに焦点を当てることができます:-) –

+0

まだ動作していない、私は以前のコメントを編集しました – Zakarya

関連する問題