My project is tracking object using opencv and send the coordinate to arduino as tx and read the data using another arduino (rx) with 'SoftwareSerial'. There are no problem with object tracking, knowing the coordinate, and communication between 2 arduino. The problem is i can not send the coordinate while 'tracker' running, but when I close the 'tracker', the data start appearing on serial com.
opencv code
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);
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
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);
// 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;
}
}
}
what should I do to write coordinate countinously while the tracker is running?