使用fprintf

时间:2018-04-14 12:28:32

标签: c++ opencv arduino

我的项目是使用opencv跟踪对象,并将坐标发送到arduino作为tx,并使用另一个带有' SoftwareSerial'的arduino(rx)读取数据。对象跟踪没有问题,知道坐标和2 arduino之间的通信。问题是我无法发送坐标,而跟踪器'正在运行,但当我关闭“跟踪器”时,数据开始出现在序列号中。

opencv代码

using namespace cv;
using namespace std;

//default capture width and height
int FRAME_WIDTH = 320; //640 320
int FRAME_HEIGHT = 240; //480 240

int MIN_OBJECT_AREA = 10*10;

int iLowH = 16;
int iHighH = 104;

int iLowS = 110; 
int iHighS = 164;

int iLowV = 63;
int iHighV = 255;

int centerX, centerY;
int Xg,Yg;

int Modefilter = 1;

FILE *fp;
bool kirim=false;

string intToString(int number){


    std::stringstream ss;
    ss << number;
    return ss.str();
}

void detect(){

}

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

    //open serial
    FILE* serial = fopen("\\\\.\\COM3", "w+");
    if (serial == 0) {
        printf("Failed to open serial port\n");
    }


    //capture the video from web cam
    VideoCapture cap(0);

    // if not success, exit program
    if ( !cap.isOpened() ){  
        cout << "Cannot open the web cam" << endl;
        return -1;
    }

    //set height and width of capture frame
    cap.set(CV_CAP_PROP_FRAME_WIDTH,FRAME_WIDTH);
    cap.set(CV_CAP_PROP_FRAME_HEIGHT,FRAME_HEIGHT);

    //create a window called "Control"
    namedWindow("Control", CV_WINDOW_AUTOSIZE);

    //Create trackbars in "Control" window

    cvCreateTrackbar("LowH", "Control", &iLowH, 179); //Hue (0 - 179)
    cvCreateTrackbar("HighH", "Control", &iHighH, 179);

    cvCreateTrackbar("LowS", "Control", &iLowS, 255); //Saturation (0 - 255)
    cvCreateTrackbar("HighS", "Control", &iHighS, 255);

    cvCreateTrackbar("LowV", "Control", &iLowV, 255); //Value (0 - 255)
    cvCreateTrackbar("HighV", "Control", &iHighV, 255);


    string XX,YY,parser1,parser2,result;

    while (serial!=0){

        Mat imgOriginal;

        bool bSuccess = cap.read(imgOriginal); // read a new frame from video

        if (!bSuccess){ //if not success, break loop
            cout << "Cannot read a frame from video stream" << endl;
            break;
        }

        //Convert the captured frame from BGR to HSV
        Mat imgHSV;
        cvtColor(imgOriginal, imgHSV, COLOR_BGR2HSV); 

        //find center point
        centerX = FRAME_WIDTH/2;
        centerY = FRAME_HEIGHT/2;

        putText(imgOriginal, "Tekan", Point(5,10), FONT_HERSHEY_COMPLEX, 0.35, Scalar(0, 255, 0), 0.25, 8);
        putText(imgOriginal, "a : Mulai Mengikuti Objek", Point(5,20), FONT_HERSHEY_COMPLEX, 0.35, Scalar(0, 255, 0), 0.25, 8);
        putText(imgOriginal, "b : Berhenti Mengikuti Objek", Point(5,30), FONT_HERSHEY_COMPLEX, 0.35, Scalar(0, 255, 0), 0.25, 8);

        //create cross line
        line(imgOriginal,Point(centerX, centerY-20), Point(centerX, centerY+20), Scalar(0,255,0), 1.5);
        line(imgOriginal,Point(centerX-20, centerY), Point(centerX+20, centerY), Scalar(0,255,0), 1.5);

        //Threshold the image
        Mat imgThresholded;

        inRange(imgHSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), imgThresholded);

        //morphological opening (remove small objects from the foreground)
        erode(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) );
        dilate( imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) ); 

        //morphological closing (fill small holes in the foreground)
        dilate( imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) ); 
        erode(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) );

        //these two vectors needed for output of findContours
        vector< vector<Point> > contours;
        vector<Vec4i> hierarchy;

        Mat imgContour;
        imgThresholded.copyTo(imgContour);

        //find contours of filtered image using openCV findContours function
        findContours(imgContour,contours,hierarchy,CV_RETR_CCOMP,CV_CHAIN_APPROX_SIMPLE );

        //use moments method to find our filtered object
        double refArea = 0;
        if (hierarchy.size() > 0) {
            int numObjects = hierarchy.size();
            for (int index = 0; index >= 0; index = hierarchy[index][0]) {
                Moments moment = moments((cv::Mat)contours[index]);
                double area = moment.m00;
                if(area>MIN_OBJECT_AREA){ //jika area kontur lebih besar dari minimum area object maka gambar lingkaran dan tulis koordinat
                    kirim=true;
                    double x = moment.m10/area;
                    double y = moment.m01/area;
                    double r = sqrt(area/3.14);

                    Xg=(int) x;
                    Yg=(int) y;

                    circle(imgOriginal, Point(x,y), r, Scalar(0,0,255), 1.5, 8);

                    line(imgOriginal, Point(x,y-r-5), Point(x,y+r+5), Scalar(0,0,255), 1.5, 8);
                    line(imgOriginal, Point(x-r-5,y), Point(x+r+5,y), Scalar(0,0,255), 1.5, 8);

                    putText(imgOriginal, intToString(x) + "," + intToString(y), Point(x,y+10), FONT_HERSHEY_COMPLEX, 0.25, Scalar(0, 255, 0), 0.3, 8);

                    // send x,y coordinate to arduino
                    parser1="*"; parser2="!";
                    ostringstream xxx,yyy ;
                    xxx << Xg;
                    yyy << Yg;
                    XX=xxx.str(); YY=yyy.str();
                    result=parser1+XX+parser2+YY;

                    cout << result << endl; 

                    fprintf(serial, "%s\n", result.c_str());    
                    fflush(serial);         

                }//end if
            }//end for
        }//end if


        //show the thresholded image
        Mat dstimgThresholded;
        resize(imgThresholded, dstimgThresholded, Size(), 2, 2, INTER_CUBIC);
        imshow("Thresholded Image", dstimgThresholded);

        //show the original image 
        Mat dstimgOriginal;
        resize(imgOriginal, dstimgOriginal, Size(), 2, 2, INTER_CUBIC);
        imshow("Original", dstimgOriginal);     

        ///send data        

        if (waitKey(5) == 27) {//wait for 'esc' key press for 30ms. If 'esc' key is pressed, break loop
            cout << "esc key is pressed by user" << endl;
            break; 
        }

    } //end while

    return 0;

}

tx arduino

#include <SoftwareSerial.h>
SoftwareSerial SWsend(2, 3); // (rx,tx)

String data;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  SWsend.begin(4800);
  //pinMode(12,INPUT_PULLUP);
}

void Send_SSIDandPWD_ToESP01() {
  while (!SWsend) {
    ; // wait for serial port to connect.
    Serial.println(F("wait for serial port to connect."));
  }
  while (Serial.available()) {
    data = Serial.readString();
    //data = Serial.read();
    Serial.print(F("Send:"));
    Serial.println(data);
    SWsend.print(data);
  }
}

void loop() {
  // put your main code here, to run repeatedly:
  Send_SSIDandPWD_ToESP01();
  delay(25);
}

rx arduino

#include <SoftwareSerial.h>
SoftwareSerial SWrecv(2, 3); //(rx,tx)
String strSSID = "";         // a string to hold incoming data
String strPWD = "";
bool keepSSID = false;
bool keepPWD = false;
boolean stringComplete = false;  // whether the string is complete

void setup() {
  // initialize serial:
  Serial.begin(115200);
  SWrecv.begin(4800);

  // Turn on the blacklight and print a message.

  Serial.println(F("Hello, world!"));
}

void loop() {
  // print the string when a newline arrives:
  SWrecvEvent();
  if (stringComplete) {
    Serial.println("X:" + strSSID  + ", Y:" + strPWD);
    // clear the string:
    //  inputString = "";
    if (strSSID == "")
    {
      Serial.println("SSID:not config");
    }
    strSSID = "";         // a string to hold incoming data
    strPWD = "";
    stringComplete = false;
  }
}

void SWrecvEvent() {
  while (SWrecv.available()) {
    // get the new byte:
    char inChar = (char)SWrecv.read();
    //Serial.print(inChar); ///////////////////string asli
    // add it to the inputString:
    switch (inChar ) {
      case '*':
        {
          keepSSID = true;
          keepPWD = false;
        }
        break;
      case '!':
        {
          keepSSID = false;
          keepPWD = true;
        }
        break;
      default:
        {
          if (inChar == '\n') {
            stringComplete = true;
            keepSSID = false;
            keepPWD = false;
            return;
          }
          if (keepSSID == true )
          {
            strSSID += inChar;
          }
          else if (  keepPWD == true )
          {
            strPWD += inChar;
          }
        }
        break;
    }
  }
}

在跟踪器运行时,我应该怎么做才能写入坐标?

1 个答案:

答案 0 :(得分:0)

可能是IO正在缓冲,只有在退出tx程序时才会刷新。尝试调用Flush强制发送数据。

相关问题