zoukankan      html  css  js  c++  java
  • 基于ubuntu14视觉识别乒乓球_1

    串口通信,opencv3.0
    窗口大小可调

    编译
    cmake ../
    make
    ./color
    正常光线下运行比较稳定,找圆比较准确。程序设置了圆的半径区间以及圆心最小间距,以满足产品的需求,可自行修改调试。

    历程如下

    #define USE_SERIAL 0 // 1:use serial  0:not use serial    //用串口调试时置1,不用串口时一定要置0,否则会报错

    #include <iostream>
    #include "opencv2/highgui/highgui.hpp"
    #include "opencv2/imgproc/imgproc.hpp"

    #include <opencv2/core/core.hpp>  
    #include <opencv2/opencv.hpp>


    #if USE_SERIAL
    #include <boost/asio.hpp>
    #include <boost/bind.hpp>
    using namespace boost::asio;

    #endif


    using namespace cv;
    using namespace std;

    int g_nThresh = 135;
    Mat canny_output;
    Mat imgOriginal;
    Mat imgHSV;
    Mat imgThresholded;//二值化后的图像数组
    Mat bf;//对灰度图像进行双边滤波
    Mat element = getStructuringElement(MORPH_RECT, Size(5, 5));
    Mat dstImage;
    int x,y,r;
    int iLowH = 9;
    int iHighH = 37;
    int iLowS = 135;
    int iHighS = 255;
    int iLowV = 175;
    int iHighV = 255;

    int main(int argc, char** argv)
    {
    size_t i = 0;
    int fd;
    #if USE_SERIAL
    char serial_buff[100]={0};
    io_service iosev;
            //节点文件
    /* fd = open("/dev/ttyUSB0",O_RDWR);
    if( -1 == fd );
    {
    cout << "Error: Cannot open the serial port" << endl;
    cout << endl;
    return -1;
    }
    close(fd);
    */
            serial_port serial(iosev, "/dev/ttyUSB0");

            // 设置参数
            serial.set_option(serial_port::baud_rate(115200));
            serial.set_option(serial_port::flow_control(serial_port::flow_control::none));
            serial.set_option(serial_port::parity(serial_port::parity::none));
            serial.set_option(serial_port::stop_bits(serial_port::stop_bits::one));
            serial.set_option(serial_port::character_size(8));
    //write(serial, buffer("Test! ", sizeof("Test! ")));
    #endif

    VideoCapture cap(-1); //capture the video from web cam

    if (!cap.isOpened())  // if not success, exit program
    {
    cout << "Error: Cannot open the web cam" << endl;
    cout << endl;
    return -1;
    }
    #if USE_SERIAL
    write(serial, buffer("Test! ", sizeof("Test! ")));
    #endif

    // namedWindow("imgThresholded", 0);    //Image can adjust size

    while (true)
    {

    bool bSuccess = cap.read(imgOriginal); // read a new frame from video

    if (!bSuccess) //if not success, break loop
    {
    cout << "Cannot read a frame from video stream" << endl;
    break;
    }
    //区分颜色*****************************************************************************************************
    vector<Mat> hsvSplit;//cevtor 容器
    cvtColor(imgOriginal, imgHSV, COLOR_BGR2HSV); //Convert the captured frame from BGR to HSV

     //因为我们读取的是彩色图,直方图均衡化需要在HSV空间做
    split(imgHSV, hsvSplit);//(多通道数组-》容器)
    equalizeHist(hsvSplit[2], hsvSplit[2]);
    merge(hsvSplit, imgHSV);

    inRange(imgHSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), imgThresholded); //Threshold the image

     //开操作 (去除一些噪点)
    morphologyEx(imgThresholded, imgThresholded, MORPH_OPEN, element);

    //闭操作 (连接一些连通域)
    morphologyEx(imgThresholded, imgThresholded, MORPH_CLOSE, element);

    //addWeighted(imgThresholded, 1, canny_output, 1, 0., dstImage);
    //morphologyEx(dstImage, dstImage, MORPH_CLOSE, element);

    //找圆************************************************************************************************************

    blur(imgThresholded, bf, Size(3, 3));
    //用Canny算子检测边缘
    Canny(bf, canny_output, g_nThresh, g_nThresh * 2, 3);

    vector<Vec3f> circles;//声明一个向量,保存检测出的圆的圆心坐标和半径
    HoughCircles(canny_output, circles, CV_HOUGH_GRADIENT, 1, 70, 250, 10, 5, 70);//霍夫变换检测圆1.5, 5, 150, 80, 1, 50

    for ( i = 0; i < circles.size(); i++)//把霍夫变换检测出的圆画出来
    {
    Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
    int radius = cvRound(circles[i][2]);

    circle(imgOriginal, center, radius, Scalar(255, 255, 255), 3,8, 0);

    // cout << "x="<<cvRound(circles[i][0]) << " " << "y="<< cvRound(circles[i][1]) << " "
    // << "z="<< cvRound(circles[i][2]) << endl;//在控制台输出圆心坐标和半径
    x=cvRound(circles[i][0]);
    y=cvRound(circles[i][1]);
    r=cvRound(circles[i][2]);
    #if USE_SERIAL
    sprintf( serial_buff,"A%03d%03d%03d%03dB",i,cvRound(circles[i][0])/8,cvRound(circles[i][1])/8,cvRound(circles[i][2]));
    write(serial, buffer(serial_buff, 14 ));
    //write(serial, buffer("AB", 2));

    #endif
    }
    #if USE_SERIAL
    if( i!=0 )
    write(serial, buffer(" ", strlen(" ")));
    #endif

    //~~~~~~~~~~~~~~~~~~~~~~~~
    imshow("imgThresholded", imgThresholded);//滤过颜色
    cvResizeWindow("imgThresholded",640,480);//Image can adjust size
    imshow("imgOriginal", imgOriginal);//寻找边沿
    cvResizeWindow("imgOriginal",640,480);//Image can adjust size
    //imshow("canny_output", canny_output);//原图显示找出的圆

    char key = (char)waitKey(20);
    if (key == 27)
    break;
    }

    return 0;

    }

  • 相关阅读:
    菜根谭#69
    菜根谭#68
    菜根谭#67
    菜根谭#66
    菜根谭#65
    菜根谭#64
    菜根谭#63
    更新centos本地仓库(换源)
    docker初探
    centos python版本升级到3.x
  • 原文地址:https://www.cnblogs.com/yueqiuchen/p/6641999.html
Copyright © 2011-2022 走看看