/*****************Team_game.h******************************/
#include <iostream>
#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
/*****************串口头文件******************************/
#include <stdio.h> /*标准输入输出定义*/
#include <stdlib.h> /*标准函数库定义*/
#include <unistd.h> /*Unix 标准函数定义*/
#include <sys/types.h>
#include <sys/stat.h>
//配置所需的头文件
#include <fcntl.h> /*文件控制定义*/
#include <termios.h> /*PPSIX 终端控制定义*/
#include <errno.h> /*错误号定义*/
/***********************************************************/
using namespace std;
using namespace cv;
#define t_min 37
#define t_max 255
Mat frame,gray_image,threshold_image;
Mat dst_image=frame.clone();
//Mat reduction_image=frame.clone();
Mat ployPic;
Mat fix;
bool chage=false;
#define WIND37_NAME "threshold_image2"
//寻找凸点定义
vector<int> hull;
/******************图像预处理部分*******************************/
void prepossing_image(Mat &frame)
{
resize(frame,frame,Size(640,480));
cvtColor(frame,gray_image,COLOR_RGB2GRAY);
// medianBlur(gray_image,gray_image,7);
blur(gray_image,threshold_image,Size(5,5));
threshold(gray_image,threshold_image, t_min,t_max,THRESH_BINARY);
// imshow("threshol_image",threshold_image);
// namedWindow("threshold",WINDOW_AUTOSIZE);
Mat sobel_x,sobel_y;
Sobel(threshold_image,sobel_x,CV_16S,0,1,3);
Sobel(threshold_image,sobel_y,CV_16S,1,0,3);
convertScaleAbs(sobel_x,sobel_x);
convertScaleAbs(sobel_y,sobel_y);
addWeighted(sobel_x,1.5,sobel_y,1.5,0,dst_image);
// imshow("canny",dst_image);
//canny算子
// Canny(threshold_image,dst_image,100,255);
}
/****************图像处理**************************************/
void port_making(Mat &dst_image1)
{
//提取轮廓
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
//寻找轮廓
findContours(dst_image1,contours,hierarchy,RETR_CCOMP,CHAIN_APPROX_SIMPLE,Point(0,0));
vector<vector<Point>> aploycontours(contours.size());
ployPic=frame.clone();
double maxArea=0;
for (unsigned int i=0;i<contours.size();i++) {
if(contourArea(contours[i])>contourArea(contours[maxArea]))
{
maxArea=i;
approxPolyDP((Mat)contours[i],aploycontours[i],50,true);
drawContours(ployPic,aploycontours,i,Scalar(255,255,255),2,8);
}
}
// cout<<"maxArea="<<maxArea<<endl;
// imshow("approxPolyDp",ployPic);
//寻找凸点
// vector<int> hull;
Mat reduction_image=frame.clone();
if(maxArea>0&&aploycontours.size()>0)
{
convexHull(aploycontours[maxArea],hull,false);
if(hull.size()!=0)
{
for (int i=0;i<hull.size();i++)
{
circle(reduction_image,aploycontours[maxArea][i],10,Scalar(255,255,255),3);
putText(reduction_image,"1",aploycontours[maxArea][0],FONT_HERSHEY_SIMPLEX,1,Scalar(255,255,255),3,8);
putText(reduction_image,"2",aploycontours[maxArea][1],FONT_HERSHEY_SIMPLEX,1,Scalar(255,255,255),3,8);
putText(reduction_image,"3",aploycontours[maxArea][2],FONT_HERSHEY_SIMPLEX,1,Scalar(255,255,255),3,8);
putText(reduction_image,"4",aploycontours[maxArea][3],FONT_HERSHEY_SIMPLEX,1,Scalar(255,255,255),3,8);
}
}
// cout<<"hull="<<hull.size()<<endl;
}
// imshow("drawing",reduction_image);
// Mat fix=Mat::zeros(640,480,frame.type()); //处理roi过后的图片
if(hull.size()==4&&aploycontours[maxArea][0].x<aploycontours[maxArea][2].x&&aploycontours[maxArea][0].y<aploycontours[maxArea][2].y
&&aploycontours[maxArea][0].y<aploycontours[maxArea][1].y&&aploycontours[maxArea][1].x<aploycontours[maxArea][3].x
&&aploycontours[maxArea][3].y<aploycontours[maxArea][2].y&&aploycontours[maxArea][1].x<aploycontours[maxArea][2].x
&&(fabs(aploycontours[maxArea][2].x-aploycontours[maxArea][3].x))<=25&&(fabs(aploycontours[maxArea][0].x-aploycontours[maxArea][1].x))<=25
&&(fabs(aploycontours[maxArea][0].y-aploycontours[maxArea][3].y))<25&&(fabs(aploycontours[maxArea][1].y-aploycontours[maxArea][2].y))<=25)
{
Rect rect1(Point(aploycontours[maxArea][0].x,aploycontours[maxArea][0].y+10),Point(aploycontours[maxArea][2].x,aploycontours[maxArea][2].y));
fix=frame(rect1);
chage=true;
// imshow("roi",fix);
}
if(hull.size()==4&&aploycontours[maxArea][1].x<aploycontours[maxArea][0].x&&aploycontours[maxArea][1].y<aploycontours[maxArea][2].y
&&aploycontours[maxArea][3].x>aploycontours[maxArea][2].x&&aploycontours[maxArea][3].y>aploycontours[maxArea][0].y
&&aploycontours[maxArea][3].y>aploycontours[maxArea][1].y&&aploycontours[maxArea][3].x>aploycontours[maxArea][1].x
&&(fabs(aploycontours[maxArea][3].y-aploycontours[maxArea][0].y))<25&&(fabs(aploycontours[maxArea][2].y-aploycontours[maxArea][1].y))<25
&&(fabs(aploycontours[maxArea][0].x-aploycontours[maxArea][1].x))<25&&(fabs(aploycontours[maxArea][3].x-aploycontours[maxArea][2].x))<25)
{
Rect rect2(Point(aploycontours[maxArea][1].x,aploycontours[maxArea][1].y+10),Point(aploycontours[maxArea][3].x,aploycontours[maxArea][3].y));
fix=frame(rect2);
chage=true;
// imshow("roi",fix);
}
waitKey(2);
}
/**********************************条件筛选*******************************************************/
void screen_image(Mat &fix1)
{
Mat red_image,green_image,black_image,white_image,blue_image;
double red_area=0,green_area=0,white_area=0,black_area=0,blue_area=0;
for ( int i=0;i<5;i++)
{
switch (i)
{
case 0:
{
Mat src=fix1.clone();
// cvtColor(src,src,COLOR_RGB2Lab);
// inRange(src,Scalar(0,0,175),Scalar(180,255,255),red_image);
// inRange(src,Scalar(0,141,20),Scalar(130,205,101),red_image);
vector<Mat>channelred;
split(src,channelred);
red_image=channelred.at(2)-channelred.at(0);
threshold(red_image,red_image,70,255,THRESH_BINARY);
// imshow("red_image",red_image);
vector<vector<Point>> contours_red;
vector<Vec4i> hierachy_red;
findContours(red_image,contours_red,hierachy_red,RETR_EXTERNAL,CHAIN_APPROX_TC89_L1);
for(unsigned int r=0;r<contours_red.size();r++)
{
red_area+=fabs(contourArea(contours_red[r]));
}
// cout<<"红色的面是"<<red_area<<endl;
}
continue;
case 1:
{
// inRange(src_image,Scalar(0,79,0),Scalar(54,255,255),green_image);
Mat src1=fix1.clone();
// cvtColor(src1,src1,COLOR_RGB2BGR);
// // inRange(src,Scalar(0,230,88),Scalar(180,255,255),green_image);
// inRange(src1,Scalar(0,115,0),Scalar(16,255,255),green_image);
vector<Mat> channelg;
split(src1,channelg);
green_image=channelg.at(1)-channelg.at(0);
threshold(green_image,green_image,107,255,THRESH_BINARY);
// imshow("green_image",green_image);
vector<vector<Point>> contours_green;
vector<Vec4i> hierachy_green;
findContours(green_image,contours_green,hierachy_green,RETR_EXTERNAL,CHAIN_APPROX_TC89_L1);
for(unsigned int g=0;g<contours_green.size();g++)
{
green_area+=fabs(contourArea(contours_green[g]));
}
}
continue;
case 2:
{
Mat src2=fix1.clone();
// cvtColor(src2,src2,COLOR_RGB2HSV);
// inRange(src2,Scalar(0,0,180),Scalar(186,23,255),white_image);
// imshow("white",white_image);
cvtColor(src2,src2,COLOR_RGB2BGR);
vector<Mat> channelwhite;
split(src2,channelwhite);
white_image=channelwhite.at(0)*0.5+channelwhite.at(2)*0.5;
threshold(white_image,white_image,120,255,THRESH_BINARY);
// imshow("white",white_image);
vector<vector<Point>> contours_white;
vector<Vec4i> hierachy_white;
findContours(white_image,contours_white,hierachy_white,RETR_EXTERNAL,CHAIN_APPROX_TC89_L1);
for(unsigned int w=0;w<contours_white.size();w++)
{
white_area+=fabs(contourArea(contours_white[w]));
}
// cout<<"白色的面是"<<white_area<<endl;
}
continue;
case 3:
{
vector<Mat> hsvSplit;
Mat src3=fix1.clone();
// split(src3, hsvSplit);
// equalizeHist(hsvSplit[2],hsvSplit[2]);
// merge(hsvSplit,src3);
// inRange(src3,Scalar(0,0,0),Scalar(85,21,0),black_image);
cvtColor(src3,src3,COLOR_BGR2Lab);
vector<Mat> channelblack;
split(src3,channelblack);
black_image=channelblack.at(0);
threshold(black_image,black_image,50,255,THRESH_BINARY_INV);
// imshow("black_image",black_image);
vector<vector<Point>> controus_black;
vector<Vec4i> hierarchy_black;
findContours(black_image,controus_black,hierarchy_black,RETR_EXTERNAL,CHAIN_APPROX_TC89_L1);
for(unsigned int b=0;b<controus_black.size();b++)
{
black_area+=fabs(contourArea(controus_black[b]));
}
// cout<<"黑色的面积是"<<black_area<<endl;
}
continue;
case 4:
{
Mat src4,hsv;
src4=fix1.clone();
// cvtColor(src4,src4,COLOR_BGR2RGB);
// inRange(src4,Scalar(0,0,190),Scalar(0,255,255),blue_image);
vector<Mat> channelg;
split(src4,channelg);
blue_image=channelg.at(0)-channelg.at(2);
threshold(blue_image,blue_image,107,255,THRESH_BINARY);
// imshow("blue_image",blue_image);
vector<vector<Point>> contours_blue;
vector<Vec4i> hierarchy_blue;
findContours(blue_image,contours_blue,hierarchy_blue,RETR_EXTERNAL,CHAIN_APPROX_TC89_L1);
for (unsigned int i=0;i<contours_blue.size();i++)
{
blue_area+=fabs(contourArea(contours_blue[i]));
}
// cout<<"蓝色的面积是"<<blue_area<<endl;
}
}
}
int fd;
int wr_num=0;
struct termios options, newstate;
char * buf = new char[8];//分配内存空间
fd = open("/dev/ttyUSB0", O_RDWR|O_NONBLOCK|O_NOCTTY|O_NDELAY); //打开串口读、写打开|非阻塞方式|不作为控制终端|防低电平睡眠
if(fd==-1)//串口未打开
perror("未打开串口");
else//正常打开
cout<<"正常打开!"<<endl;
//检测是否为终端
if(fcntl(fd, F_SETFL, 0) < 0 ) //改为阻塞模式
{
cout<<"fcntl error"<<endl;
}
else
{
cout<<"fcntl = "<<fcntl(fd, F_SETFL, 0)<<endl;
}
//获取串口
tcgetattr(fd, &options);
//设置波特率
//WARNING: B9600
cfsetispeed(&options, B9600);
cfsetospeed(&options, B9600);
//获取波特率
tcgetattr(fd, &newstate);
//串口设置
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~PARENB; //设置无奇偶校验位
options.c_cflag &= ~CSTOPB; //设置停止位1
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8; //设置数据位
options.c_cc[VTIME] = 0; //阻塞模式的设置
options.c_cc[VMIN] = 0;
//激活新配置
tcsetattr(fd, TCSANOW, &options);//初始化
double find_big_area[5]={
red_area,white_area,green_area,blue_area,black_area};
double max_area=0;
int length=sizeof (find_big_area)/sizeof (int);
max_area=*max_element(find_big_area,find_big_area+length);
if(max_area==find_big_area[0])
{
cout<<"最大的面积是红色"<<max_area<<endl;
uint car =5;
sprintf(buf,"%c",car);
cout<<"输出的字符是"<<car<<endl;
write(fd,buf,sizeof (buf));
tcflush(fd,TCIOFLUSH);
// test_number++;
sleep(0.5);
chage=false;
}
if(max_area==find_big_area[1])
{
cout<<"最大的面积是白色"<<max_area<<endl;
uint16_t car=1;
sprintf(buf,"%c",car);
cout<<"输出的字符是"<<car<<endl;
write(fd,buf,sizeof (buf));
tcflush(fd,TCIOFLUSH);
sleep(0.5);
chage=false;
}
if(max_area==find_big_area[2])
{
cout<<"最大的面积是绿色"<<max_area<<endl;
cout<<"c"<<endl;
uint16_t car= 3;
sprintf(buf,"%c",car);
cout<<"输出的字符是"<<car<<endl;
write(fd,buf,sizeof (buf));
tcflush(fd,TCIOFLUSH);
// test_number++;
sleep(0.5);
chage=false;
}
if(max_area==find_big_area[3])
{
cout<<"最大的面积是蓝色"<<max_area<<endl;
uint16_t car =4;
sprintf(buf,"%c",car);
cout<<"输出的字符是"<<car<<endl;
write(fd,buf,sizeof (buf));
// sleep(1);
tcflush(fd,TCIOFLUSH);
sleep(0.5);
chage=false;
}
if(max_area==find_big_area[4])
{
cout<<"最大的面积是黑色"<<max_area<<endl;
uint16_t car = 2;
sprintf(buf,"%c",car);
cout<<"输出的字符是"<<car<<endl;
write(fd,buf,sizeof (buf));
//test_number++;
sleep(0.5);
chage=false;
}
}
/*******************判断识别输出********************************************************/
//void message_out(double red,double white,double green ,double black,double blue )
//{
//}
int main()
{
char spring[50];
VideoCapture capture(2);
for (;;) {
capture.set(CAP_PROP_BRIGHTNESS,55);
double t = (double)getTickCount();//开始计时
capture>>frame;
prepossing_image(frame);
port_making(dst_image);
if(chage==true&&hull.size()==4)
{
screen_image(fix);
// message_out(red_area,white_area,green_area,black_area,blue_area);
}
t = ((double)getTickCount() - t) / getTickFrequency();//结束计时
double fps =1.0 / t;//转换为帧率
sprintf(spring,"%0.2f",fps);
String fpsspring("FPS:");
fpsspring+=spring;
putText(ployPic,fpsspring,Point(25,25),FONT_HERSHEY_DUPLEX,0.5,Scalar(255,255,180));
imshow("fps",ployPic);
cout << "FPS= " << fps<<endl;//输出帧率
}
}
颜色识别模块
猜你喜欢
转载自blog.csdn.net/Msyusheng/article/details/109430278
今日推荐
周排行