美文网首页
opencv的初步使用(高斯模糊、边缘检测、灰度化、二值化、闭运

opencv的初步使用(高斯模糊、边缘检测、灰度化、二值化、闭运

作者: Moonsmile | 来源:发表于2017-07-30 22:51 被阅读0次

    前提:已经配好了opencv+Qt
    这里只讲如何使用api,不怎么讲算法原理

    既然要用opencv的库,首先把相应的头文件导进去吧

    #include <opencv2/core/core.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include<cv.h>
    
    using namespace cv;
    

    我这里只导入了我用到了的头文件
    using namespace cv;是用来声明cv,类似于using namespace std;

    1、展示出一张图片
    如果已经声明了using namespace cv;前面可以不加cv::

      //【1】载入原始图
    //路径下应该有一张名为5.JPG的素材
    Mat image=imread("C:/Users/junyi.pc/Desktop/5.JPG",IMREAD_COLOR);
    cv::namedWindow("原图", WINDOW_AUTOSIZE); // 创建一个窗
    cv::imshow("原图", image);
    sleep(3000);
    cv::destroyWindow("原图");
    

    Mat是opencv中存放图片的数据结构
    imread是读入图片
    namedWindow 声明一个窗口
    imshow 将图片展示出来
    sleep 我自己写的延迟的函数,下边后展示出来
    destroyWindow 让展示的窗口消失

    void sleep(unsigned int Msec){
        QTime reachTime=QTime::currentTime().addMSecs(Msec);
        while(QTime::currentTime()<reachTime){
          QCoreApplication::processEvents(QEventLoop::AllEvents,100);
        }
    }
    

    2、高斯模糊
    作用:顾名思义,将一图片变得更模糊

           GaussianBlur(image,dst,Size(3,3),0);
            cv::namedWindow("高斯模糊图", WINDOW_AUTOSIZE); // 创建一个窗
            qImg = IplImage(dst); // cv::Mat -> IplImage
            cvSaveImage("C://Users//junyi.pc//Desktop//temp.jpg", &qImg);
            cv::imshow("高斯模糊图", dst);
            sleep(5000);
            cv::destroyWindow("高斯模糊图");
    

    GaussianBlur 中第一个参数是读入的图片,第二行dst是输出图片,也是Mat类型,Size(3,3)是矩阵内核,必须是奇数,数值越大越模糊。

    IplImage qImg = IplImage(dst); // cv::Mat -> IplImage
    cvSaveImage("C://Users//junyi.pc//Desktop//temp.jpg", &qImg);
    这两行代码是将处理后的图片另存为

    除了高斯模糊,还有均值模糊等等

    3、灰度化
    作用:将图片彩色去掉

     cvtColor( src, dst, CV_RGB2GRAY );
    //src, dst都是Mat 类型,前者是输入图片,后者是输出图片-即灰度图
    

    4、索贝尔边缘检测

    Mat src = imread("C:/Users/junyi.pc/Desktop/temp.jpg",IMREAD_COLOR);
               Sobel( src, grad_x, CV_16S, 1, 0, 3, 1, 1, BORDER_DEFAULT );
               convertScaleAbs( grad_x, abs_grad_x );
               Sobel( src, grad_y, CV_16S, 0, 1, 3, 1, 1, BORDER_DEFAULT );
               convertScaleAbs( grad_y, abs_grad_y );
               addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.5, 0, dst );
               qImg = IplImage(dst); // cv::Mat -> IplImage
               cvSaveImage("C://Users//junyi.pc//Desktop//temp.jpg", &qImg);
               cv::namedWindow("索贝尔算子边缘检测图");
               cv::imshow("索贝尔算子边缘检测图",dst);
               sleep(5000);
               cv::destroyWindow("索贝尔算子边缘检测图");
        第一个参数,InputArray 类型的src,为输入图像,填Mat类型即可。
        第二个参数,OutputArray类型的dst,即目标图像,函数的输出参数,需要和源图片有一样的尺寸和类型。
        第三个参数,int类型的ddepth,输出图像的深度,支持如下src.depth()和ddepth的组合:
    
            若src.depth() = CV_8U, 取ddepth =-1/CV_16S/CV_32F/CV_64F
            若src.depth() = CV_16U/CV_16S, 取ddepth =-1/CV_32F/CV_64F
            若src.depth() = CV_32F, 取ddepth =-1/CV_32F/CV_64F
            若src.depth() = CV_64F, 取ddepth = -1/CV_64F
    
        第四个参数,int类型dx,x 方向上的差分阶数。
        第五个参数,int类型dy,y方向上的差分阶数。
        第六个参数,int类型ksize,有默认值3,表示Sobel核的大小;必须取1,3,5或7。
        第七个参数,double类型的scale,计算导数值时可选的缩放因子,默认值是1,表示默认情况下是没有应用缩放的。我们可以在文档中查阅getDerivKernels的相关介绍,来得到这个参数的更多信息。
        第八个参数,double类型的delta,表示在结果存入目标图(第二个参数dst)之前可选的delta值,有默认值0。
        第九个参数, int类型的borderType,我们的老朋友了(万年是最后一个参数),边界模式,默认值为BORDER_DEFAULT。这个参数可以在官方文档中borderInterpolate处得到更详细的信息。
    

    5、二值化

    src=imread("C:/Users/junyi.pc/Desktop/temp.jpg",IMREAD_COLOR);
               dst.create( src.size(), src.type() );
               // 【2】将原图像转换为灰度图像
               cvtColor( src, gray, CV_BGR2GRAY );
               // 【3】先用使用 3x3内核来降噪
               blur( gray, edge, Size(3,3) );
               //type选THRESH_BINARY,大于阈值的设置为maxval(255),其它置0
               threshold(edge, dst, nY20_thresh, 255, THRESH_BINARY);
               qImg = IplImage(dst); // cv::Mat -> IplImage
               cvSaveImage("C://Users//junyi.pc//Desktop//temp.jpg", &qImg);
               cv::namedWindow("二值化图", WINDOW_AUTOSIZE); // 创建一个窗
               cv::imshow("二值化图", dst);
               sleep(5000);
               cv::destroyWindow("二值化图");
    

    关键在于threshold(edge, dst, nY20_thresh, 255, THRESH_BINARY);
    nY20_thresh是阈值,设定阈值的方式有很多种可自行百度,255是最大值,一般就是255

    6、闭运算

    image=imread("C:/Users/junyi.pc/Desktop/temp.jpg",IMREAD_COLOR);
              dst =getStructuringElement(MORPH_RECT,Size(4,4));
              morphologyEx(image,image, MORPH_CLOSE, dst);
              qImg = IplImage(image); // cv::Mat -> IplImage
              cvSaveImage("C://Users//junyi.pc//Desktop//temp.jpg", &qImg);
              cv::namedWindow("闭运算图", WINDOW_AUTOSIZE); // 创建一个窗
              cv::imshow("闭运算图", image);
              sleep(5000);
              cv::destroyWindow("闭运算图");
              break;
    

    dst =getStructuringElement(MORPH_RECT,Size(4,4));
    获取一个内核矩阵
    morphologyEx(image,image, MORPH_CLOSE, dst);
    使用dst这个内核矩阵来执行闭运算,输入输出都是image

    7、绘制边缘

       void func10(Mat im){
        vector<vector<Point> > contours;
        vector<Vec4i> hierarchy;
        if(!im.data)
        {cout<<"Can't find image!";}
        //change the image to binary by setting a threshold
        threshold(im,im,120,255,THRESH_BINARY);
        findContours(im,contours,hierarchy,CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
        Mat contoursImage(im.rows,im.cols,CV_8U,Scalar(255));
           for(int i=0;i<contours.size();i++){
                if(hierarchy[i][3]!=-1){
                 drawContours(contoursImage,contours,i,Scalar(0),3);
                 namedWindow("ha");
                 imshow("ha",contoursImage);
                 sleep(100);
                }
          }
    }
    

    findContours 是寻找边缘的函数
    drawContours 将边缘绘制出来

    相关文章

      网友评论

          本文标题:opencv的初步使用(高斯模糊、边缘检测、灰度化、二值化、闭运

          本文链接:https://www.haomeiwen.com/subject/cgoklxtx.html