树莓派+Qt+图像识别+串口传输

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

测试

这里写图片描述
这里写图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章