|
在小车平台上放一个路由器,刷上openwrt装好uvc驱动,挂载摄像头用电脑接收 图像,进行处理,主要是霍夫圆检测,然后把小球的位置坐标通过蓝牙串口下发给小车,小车根据坐标运动,就可以一直跟着乒乓球了~
上位机用C++编写,代码如下:
- #include "opencv2/highgui/highgui.hpp"
- #include "opencv2/imgproc/imgproc.hpp"
- #include <iostream>
- #include <stdio.h>
- #include "Windows.h"
- #include "string"
- using namespace std;
- using namespace cv;
- #define input_sources 3
- //cam = 0; img = 1; stream = 3
- #define standby 998
- #define noball 990
- using namespace cv;
- /** @function main */
- int main(int argc, char** argv)
- {
- Mat src, src_gray;
- #if input_sources == 1
- char* filename = "I:\\OpenCV\\1.jpg";
- #endif
- #if input_sources == 0;
- VideoCapture vcap(0);
- if (!vcap.isOpened())
- return -1;
- #endif
- #if input_sources == 3
- cv::VideoCapture vcap;
- const string address = "http://192.168.11.1:8080/?action=stream?dummy=param.mjpg";
- if (!vcap.open(address))
- {
- cout << "Error opening video stream" << endl;
- return -1;
- }
- cout << "Stream opened" << endl;
- #endif
- ////////////////////////////////////////////////////////////////////////////////////////////
- //serial init
- HANDLE hCom;
- hCom = CreateFile(TEXT("\\\\.\\COM14"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- char Out_Buffer[10];
- DWORD byteswritten = 0;
- int x = 640;
- int y = 480;
- DCB dcb;
- GetCommState(hCom, &dcb);
- dcb.BaudRate = 9600; //波特率为9600
- dcb.ByteSize = 8; //每个字节有8位
- dcb.Parity = NOPARITY; //无奇偶校验位
- dcb.StopBits = 0; //yi个停止位
- SetCommState(hCom, &dcb);
- /////////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////
- //serial
- string strx = to_string(standby);
- string stry = to_string(standby);
- string str_temp = strx + ',' + stry + '\r'+'\n';
- strcpy(Out_Buffer, str_temp.c_str());
- int temp = 0;
- DWORD byteswrite = str_temp.length();
- WriteFile(hCom, Out_Buffer, byteswrite, &byteswritten, NULL);
- WriteFile(hCom, Out_Buffer, byteswrite, &byteswritten, NULL);
- ////////////////////////////////////////////////////////////////////////////////////////////////
- namedWindow("Hough Circle Transform Demo", CV_WINDOW_AUTOSIZE);
- namedWindow("scanny", 1);
- while (1)
- {
- #if (input_sources == 0 || input_sources ==3)
- vcap >> src;
- #endif
- /// Read the image
- #if input_sources == 1
- src = imread(filename);
- if (!src.data)
- {
- return -1;
- }
- #endif
- /// Convert it to gray
- //cvtColor(src, src_gray, CV_BGR2GRAY);
- Mat src_gray = Mat::zeros(src.size(), CV_8UC1);
- Mat scanny = Mat::zeros(src.size(), CV_8UC1);
-
-
- //printf("cols=%d\nrows=%d\n\n", src.cols, src.rows);
- for (int y = 0; y < src.rows; y++)
- {
- for (int x = 0; x < src.cols; x++)
- {
- src_gray.at<uchar>(y, x) = abs(src.at<Vec3b>(y, x)[2] - src.at<Vec3b>(y, x)[1]);
- }
- }
- //printf("cols=%d\nrows=%d\n\n", src.cols, src.rows);
- /// Reduce the noise so we avoid false circle detection
- GaussianBlur(src_gray, src_gray, Size(5,5), 2, 2);
- namedWindow("rc", CV_WINDOW_AUTOSIZE);
- imshow("rc", src_gray);
- vector<Vec3f> circles;
- /// Apply the Hough Transform to find the circles
- Canny(src_gray, scanny, 0, 70, 3);
- HoughCircles(src_gray, circles, CV_HOUGH_GRADIENT, 1, src_gray.rows / 8, 80, 20, 0, 150); //80 scanny阈值 20 圆心检测阈值 0 150 最小最大圆半径
- //int i = 1;
- /// Draw the circles detected
- for (size_t i = 0; i < circles.size(); i++)
- {
- //i = 0;
-
-
- printf("\ncircle.size = %d\n", circles.size());
- Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
- printf("x=%d\ny=%d\n\n", cvRound(circles[i][0]), cvRound(circles[i][1]));
- x = cvRound(circles[i][0]);
- y = cvRound(circles[i][1]);
-
- int radius = cvRound(circles[i][2]);
- // circle center
- circle(src, center, 3, Scalar(0, 255, 0), -1, 8, 0);
- // circle outline
- circle(src, center, radius, Scalar(0, 0, 255), 3, 8, 0);
- Point text_center(cvRound(circles[i][0]) - cvRound(circles[i][2]), cvRound(circles[i][1]) - cvRound(circles[i][2]));
- if (circles[i][2]>2)
- putText(src, "Object Detected !", text_center, 0, 0.7, (0, 255, 255), 2);
- }
-
- /////////////////////////////////////////////////////////////////////////////////////
- //serial
- string strx = to_string(x);
- string stry = to_string(y);
- int x_old, y_old;
-
- string str_temp = strx + ',' + stry +'\r'+ '\n';
- //if (str_temp[str_temp.length() - 1] == '\n')
- {
- strcpy(Out_Buffer, str_temp.c_str());
- DWORD byteswrite = str_temp.length();
- if ((x_old != x) || (y_old != y))
- WriteFile(hCom, Out_Buffer, byteswrite, &byteswritten, NULL);
- else
- {
- /////////////////////////////////////////////////////////////////////////////////////
- //serial
- temp++;
- if (temp == 30)
- {
- temp = 0;
- strx = to_string(noball);
- stry = to_string(noball);
- str_temp = strx + ',' + stry + '\r' + '\n';
- strcpy(Out_Buffer, str_temp.c_str());
- byteswrite = str_temp.length();
- WriteFile(hCom, Out_Buffer, byteswrite, &byteswritten, NULL);
- WriteFile(hCom, Out_Buffer, byteswrite, &byteswritten, NULL);
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- }
- x_old = x;
- y_old = y;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
-
- /// Show your results
- imshow("Hough Circle Transform Demo", src);
- imshow("scanny", scanny);
- if (waitKey(2) == 27)
- break;
- }
- destroyAllWindows();
- //CloseHandle(hCom);
- // waitKey(0);
- return 0;
- }
复制代码
最终实现效果是这样的:
|
|