颜色识别模块

/*****************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
今日推荐