我的项目是使用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;
}
}
}
在跟踪器运行时,我应该怎么做才能写入坐标?