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;
}
測試