利用opencv霍夫变检测中国象棋的外形——圆

今天将opencv的霍夫变换修改并优化了一下,就是先预处理,切割、二值化、去噪之后进行霍夫变换,效果还不错,从识别70多个圆,慢慢修改到识别32个圆。
效果如下:
这里写图片描述
原理毛星云写的就很好,他的文章链接:https://blog.csdn.net/poem_qianmo/article/details/26977557
下面附上代码:

#include "stdafx.h"
#include "core/core.hpp"  
#include <opencv2/imgproc/imgproc.hpp>  
#include <opencv2/highgui/highgui.hpp>  
#include <iostream>  
#include <set>
#include<stdio.h>

#include <opencv2/core.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/videoio.hpp>//for camera
#include <opencv2/video.hpp>
#include <opencv2/ml/ml.hpp>
#include "opencv2/ml/ml.hpp"
#include <time.h>
#include <ctime>
#include <string>
using namespace std;
using namespace cv;
//-----------------------------------【命名空间声明部分】---------------------------------------  
//      描述:包含程序所使用的命名空间  
//-----------------------------------------------------------------------------------------------   

//-----------------------------------【main( )函数】--------------------------------------------  
//      描述:控制台应用程序的入口函数,我们的程序从这里开始  
//-----------------------------------------------------------------------------------------------  
int main()
{
    //【1】载入原始图和Mat变量定义     
    Mat srcImage = imread("3.jpg");  //工程目录下应该有一张名为1.jpg的素材图  
    Mat midImage, dstImage;//临时变量和目标图的定义  

                           //【2】显示原始图  
    namedWindow("【原始图】", 0);//参数为零,则可以自由拖动
    imshow("【原始图】", srcImage);

    Rect rect(600, 0, 1205, 1035);   //创建一个Rect框,属于cv中的类,四个参数代表x,y,width,height  
    Mat image_cut = Mat(srcImage, rect);      //从img中按照rect进行切割,此时修改image_cut时image中对应部分也会修改,因此需要copy  
    Mat image_copy = image_cut.clone();   //clone函数创建新的图片  

    namedWindow("分割后的图片", 0);//参数为零,则可以自由拖动
    imshow("分割后的图片", image_copy);


    //【3】转为灰度图,进行图像平滑  
       cvtColor(image_copy, midImage, CV_BGR2GRAY);//灰度化

        //二值化
        threshold(midImage, midImage, 128, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);

        //使用3*3内核来降噪
        blur(midImage, midImage, Size(3, 3));//进行模糊
    //GaussianBlur(midImage, midImage, Size(9, 9), 2, 2);


    //Rect rect(600,0, 1205, 1035);   //创建一个Rect框,属于cv中的类,四个参数代表x,y,width,height  
    //Mat image_cut = Mat(midImage, rect);      //从img中按照rect进行切割,此时修改image_cut时image中对应部分也会修改,因此需要copy  
    //Mat image_copy = image_cut.clone();   //clone函数创建新的图片  

    //namedWindow("分割后的图片", 0);//参数为零,则可以自由拖动
    //imshow("分割后的图片", image_copy);







    //【4】进行霍夫圆变换  
    vector<Vec3f> circles;
//  HoughCircles(midImage, circles, CV_HOUGH_GRADIENT, 1.5, 10, 200, 100, 0, 0);

    //      第五个参数   圆的圆心之间的最小距离
    HoughCircles(midImage, circles, CV_HOUGH_GRADIENT, 1.5, 35, 100, 25, 36, 43);

    //【5】依次在图中绘制出圆  
    for (size_t i = 0; i < circles.size(); i++)
    {
        Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
        int radius = cvRound(circles[i][2]);
        cout << "圆心  " << i << "= " << center << ";\n" << endl;
        cout << "半径= " << i << "= " << radius << ";\n" << endl;

        //绘制圆心  
        circle(midImage, center, 3, Scalar(0, 255, 0), -1, 8, 0);
        //绘制圆轮廓  
        circle(midImage, center, radius, Scalar(155, 50, 255), 3, 8, 0);
        //绘制圆心  
        circle(image_copy, center, 3, Scalar(0, 255, 0), -1, 8, 0);
        //绘制圆轮廓  
        circle(image_copy, center, radius, Scalar(155, 50, 255), 3, 8, 0);
    }
    cout << "共检测到圆" << circles.size() << " 个圆" << ";\n" << endl;

    //【6】显示效果图    
    namedWindow("【二值化后效果图】", 0);//参数为零,则可以自由拖动
    imshow("【二值化后效果图】", midImage);

    namedWindow("【彩色效果图】", 0);//参数为零,则可以自由拖动
    imshow("【彩色效果图】", image_copy);
    waitKey(0);

    return 0;
}


猜你喜欢

转载自blog.csdn.net/mao_hui_fei/article/details/80008197