前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >opencv的初步使用(高斯模糊、边缘检测、灰度化、二值化、闭运算、绘制边缘)

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

作者头像
张俊怡
发布2018-04-24 14:24:19
1.5K0
发布2018-04-24 14:24:19
举报

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

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

代码语言:javascript
复制
#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::

代码语言:javascript
复制
  //【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 让展示的窗口消失

代码语言:javascript
复制
void sleep(unsigned int Msec){
    QTime reachTime=QTime::currentTime().addMSecs(Msec);
    while(QTime::currentTime()<reachTime){
      QCoreApplication::processEvents(QEventLoop::AllEvents,100);
    }
}

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

代码语言:javascript
复制
       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、灰度化 作用:将图片彩色去掉

代码语言:javascript
复制
 cvtColor( src, dst, CV_RGB2GRAY );
//src, dst都是Mat 类型,前者是输入图片,后者是输出图片-即灰度图

4、索贝尔边缘检测

代码语言:javascript
复制
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、二值化

代码语言:javascript
复制
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、闭运算

代码语言:javascript
复制
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、绘制边缘

代码语言:javascript
复制
   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 将边缘绘制出来

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.07.30 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档