CAMsearch.pro
QT += core
QT -= gui
TARGET = test
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
INCLUDEPATH +=/usr/local/include \
/usr/local/include/opencv \
/usr/local/include/opencv2
LIBS +=/usr/local/lib/libopencv_highgui.so \
/usr/local/lib/libopencv_core.so \
/usr/local/lib/libopencv_imgproc.so \
/usr/local/lib/libopencv_imgcodecs.so\
/usr/local/lib/libopencv_videoio.so \
/usr/local/lib/libopencv_video.so \
/usr/local/lib/libopencv_videostab.so \
/usr/local/lib/libopencv_calib3d.so \
/usr/local/lib/libopencv_features2d.so\
/usr/local/lib/libopencv_flann.so \
/usr/local/lib/libopencv_ml.so \
/usr/local/lib/libopencv_objdetect.so \
/usr/local/lib/libopencv_photo.so \
/usr/local/lib/libopencv_shape.so \
/usr/local/lib/libopencv_stitching.so \
/usr/local/lib/libopencv_superres.so
LIBS +=-lwiringPi
main.cpp
#include "opencv2/opencv.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <wiringPi.h>
#include <wiringSerial.h>
#include <iostream>
#include<sys/stat.h>
#include<unistd.h>
using namespace std;
using namespace cv;
int main(void)
{
sleep(1);//延时1秒
/*-------------初始化变量--------------*/
Mat frame;
RNG rng(12345);
vector<vector<Point> > contours; //所有轮廓
vector<Vec4i> hierarchy;
int fd,xxx,yyy,dx,dy;
char string[4],str[6],str1[6];
/*-------------初始化环境--------------*/
if(wiringPiSetupSys()<0)return 1;//初始化wiringPi
VideoCapture capture(0);//打开摄像头
if (!capture.isOpened()) { printf("--(!)Error opening video capture\n"); return -1; }
/*-------------主循环--------------*/
while (capture.read(frame))
{
if (frame.empty())
{
printf(" --(!) No captured frame -- Break!");
break;
}
capture >> frame; //从摄像头取一帧缓存到frame
/*-------------图像处理部分-------------*/
Mat proimage = frame;
cvtColor(proimage, proimage, CV_BGRA2GRAY);
blur(proimage, proimage, Size(5, 5));
Canny(proimage, proimage, 50, 100); //canny边缘检测
adaptiveThreshold(proimage, proimage, 255, ADAPTIVE_THRESH_GAUSSIAN_C,
THRESH_BINARY_INV, 7, 7); //自适应二值化
/*-------------图像识别部分--------------*/
Mat Findallcontours = proimage;
findContours(Findallcontours, contours,CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE); //提取所有的轮廓存到contours
vector<RotatedRect> possibleObj; //可能的目标
vector<RotatedRect> target;//最终目标
for (size_t i = 0; i < contours.size(); i++)
{
size_t count = contours[i].size(); //所有的轮廓数量
if (count < 50)continue;//排除过小的轮廓
if (count > 1640)continue;//排除过大的轮廓
Mat pointsf;
Mat(contours[i]).convertTo(pointsf, CV_32F);
RotatedRect box = fitEllipse(pointsf);// 椭圆拟合
if (MAX(box.size.width, box.size.height) >
MIN(box.size.width, box.size.height)*1.2)continue;//选出接近园的轮廓
possibleObj.push_back(box); //可能的目标放到possibleObj
/*当前box与之前所有的possibleObj作比较*/
for (int p = 0; p < possibleObj.size(); p++)
{
float d = powf((possibleObj[p].center.x - box.center.x), 2) + powf((possibleObj[p].center.y - box.center.y), 2);
d = sqrtf(d); //两个圆心的欧式距离
bool flag = true;
if(possibleObj[p].size == box.size){flag = false;} //排除自身
if (d <20&&flag)
{
/*半径两倍*/
if(((1.7<possibleObj[p].size.width/box.size.width)
&& (possibleObj[p].size.width / box.size.width<2.4))
|| ((1.7<box.size.height / possibleObj[p].size.height)
&& (box.size.height / possibleObj[p].size.height<2.4)))
{
target.push_back(possibleObj[p]);
target.push_back(box); //符合条件的轮廓放入target
}
}
}
}
/*-------------轮廓绘制--------------*/
Mat drawing = Mat::zeros(frame.size(), CV_8UC3);
for (int p = 0; p < possibleObj.size(); p++)
{
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
ellipse(drawing, possibleObj[p], color, 2, 8);
}
for (int t = 0; t < target.size()/2; t++)
{
Scalar color = Scalar(0, 0, 255);
ellipse(frame, target[t], color, 2, 8);
/*以摄像头为原点,输出xy二轴坐标
在opencv,图像坐标是以左上角为原点的*/
xxx=int(target[t].center.x);dx=xxx-proimage.cols/2;
yyy=int(target[t].center.y);dy=proimage.rows/2-yyy;
sprintf(str,"%s%d%s","X",dx,"R");
sprintf(str1,"%s%d%s","Y",dy,"R");//字符串拼接,传输协议x轴X***R,y轴Y***R
printf(":%s,%s\n", str, str1);
/*打开串口设备,发送坐标字符串,波特率9600*/
if ((fd = serialOpen("/dev/ttyS0", 9600)) < 0)
{
printf("serial doesn't open,return %d", fd);
}
serialPrintf(fd,str);
delay(10);
serialPrintf(fd,str1);
serialClose(fd);//清缓存
}
int c = waitKey(10);
if ((char)c == 27) { break; } // escape
}
capture.release();
return 0;
}
测试