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

前提:已经配好了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核的大小;必须取1357。
    第七个参数,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 将边缘绘制出来



作者:Moonsmile
链接:https://www.jianshu.com/p/6890d691e684
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值