前提:已经配好了opencv+Qt
这里只讲如何使用api,不怎么讲算法原理
既然要用opencv的库,首先把相应的头文件导进去吧
#include
#include
#include
#include
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()
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 > contours;
vector 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
findContours 是寻找边缘的函数
drawContours 将边缘绘制出来