博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
OpenCV探索之路(二):图像处理的基础知识点串烧
阅读量:5815 次
发布时间:2019-06-18

本文共 5814 字,大约阅读时间需要 19 分钟。

opencv图像初始化操作

#include
#include
using namespace std;using namespace cv;int main(int argc, char** argv){ //这些方式都是自己拥有独立的内存空间 Mat img1(2, 2, CV_8UC3, Scalar(0, 0, 255)); cout << img1 << endl; int sz[3] = { 2,2,2 }; Mat img2(3, sz, CV_8UC1, Scalar(0, 0, 0)); //cout << img2 << endl; Mat img5; img5.create(4, 4, CV_8UC3); cout << img5 << endl; Mat img6 = Mat::zeros(4, 4, CV_8UC3); cout << img6 << endl; Mat img7 = img6.clone(); cout << img7 << endl; Mat img8; img6.copyTo(img8); cout << img8 << endl; //下面都是浅拷贝,指针指向同一个实例 Mat img9 = img8; Mat img10(img8); waitKey(0); return 0;}

图像二值化操作

两种方法,全局固定阈值二值化和局部自适应阈值二值化

全局固定阈值很容易理解,就是对整幅图像都是用一个统一的阈值来进行二值化;

局部自适应阈值则是根据像素的邻域块的像素值分布来确定该像素位置上的二值化阈值。

#include
#include
using namespace std;using namespace cv;int main(int argc, char** argv){ Mat image = imread("lol1.jpg", CV_LOAD_IMAGE_GRAYSCALE); //注意了,必须是载入灰度图 if (image.empty()) { cout << "read image failure" << endl; return -1; } // 全局二值化 int th = 100; Mat global; threshold(image, global, th, 255, CV_THRESH_BINARY_INV); // 局部二值化 int blockSize = 25; int constValue = 10; Mat local; adaptiveThreshold(image, local, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV, blockSize, constValue); imshow("全局二值化", global); imshow("局部二值化", local); waitKey(0); return 0;}

原始图

1093303-20170518165051900-718998586.png

两种二值化效果对比

1093303-20170518165102010-2022967431.png

腐蚀操作

#include 
#include
using namespace cv;using namespace std;int main(){ Mat SrcPic = imread("lena.jpg"); imshow("Src Pic", SrcPic); Mat element = getStructuringElement(MORPH_RECT, Size(15, 15)); //getStructuringElement函数返回的是指定形状和尺寸的结构元素 Mat DstPic; erode(SrcPic, DstPic, element); //腐蚀操作 imshow("腐蚀效果图", DstPic); waitKey(); return 0;}

运行效果

1093303-20170518120142478-1134432788.png

使用 均值滤波实现图像模糊

#include 
#include
using namespace cv;using namespace std;int main(){ Mat SrcPic = imread("lena.jpg"); imshow("Src Pic", SrcPic); Mat DstPic; blur(SrcPic, DstPic, Size(7, 7)); imshow("均值模糊效果图", DstPic); waitKey(); return 0;}

运行效果

1093303-20170518120159463-2108736610.png

canny边缘检测

思路:将原始图像转化为灰度图,用blur函数进行图像模糊以降噪,然后用canny函数进行边缘检测。

#include 
#include
using namespace cv;using namespace std;int main(){ Mat SrcPic = imread("lena.jpg"); imshow("Src Pic", SrcPic); Mat DstPic, edge, grayImage; //创建与src同类型和同大小的矩阵 DstPic.create(SrcPic.size(), SrcPic.type()); //将原始图转化为灰度图 cvtColor(SrcPic, grayImage, COLOR_BGR2GRAY); //先使用3*3内核来降噪 blur(grayImage, edge, Size(3, 3)); //运行canny算子 Canny(edge, edge, 3, 9, 3); imshow("边缘提取效果", edge); waitKey(); return 0;}

运行效果

1093303-20170518120217807-156823332.png

基础图像操作

创建窗口:namedWindow()

void namedWindow(const String& winname, int flags = WINDOW_AUTOSIZE);

因为有时候需要用到窗口的名字,尽管这个时候还没有载入图片,比如我们要在一个窗口上加入一个工具条,我们必须首先知道窗口的名字,这样才知道在哪里加上这个toolbar。

namedWindow还有一个很重要的功能,如果使用默认参数,窗口是无法自由调整的,如果想实现用户自由拉伸窗口,可以这么做:

namedWindow("srcImage", WINDOW_NORMAL);// 注意这个宏,使用WINDOW_NORMAL可以允许用户自由伸缩窗口大小    imshow("srcImage", srcImage);

输出图像到文件:imwrite()

bool imwrite( const String& filename, InputArray img,const std::vector

创建trackbar以及使用

下面的例子利用trakbar打开多个图片。

#include
#include
using namespace std;using namespace cv;#define PIC_MAX_NUM 5int pic_num = 0;void on_track(int,void*){ char file[10]; sprintf(file, "lol%d.jpg", pic_num); Mat img = imread(file); if (!img.data) { cout << "读取图片失败" << endl; return; } imshow("展示多幅图片", img);}int main(){ namedWindow("展示多幅图片"); createTrackbar("图片编号", "展示多幅图片", &pic_num, PIC_MAX_NUM, on_track); on_track(pic_num, NULL); waitKey(0);}

展示一下效果吧!

1093303-20170518120240900-2077524793.png

1093303-20170518120253557-2016388006.png

对一幅图片进行颜色转换,转为灰度图

#include
#include
using namespace std;using namespace cv;int main(){ Mat img = imread("lol1.jpg"); Mat dstImg; cvtColor(img, dstImg,COLOR_BGR2GRAY);//从宏名字就可以知道,是彩色图转换到灰度图 imshow("灰度图", dstImg); waitKey(0);}

灰度图

1093303-20170518120308353-1428897185.png

总结一系列常用的数据结构

#include
#include
using namespace std;using namespace cv;//常见数据结构使用方法总结int main(){ //Mat的用法 Mat m1(2, 2, CV_8UC3, Scalar(0, 0, 255)); //其中的宏的解释:CV_[位数][带符号与否][类型前缀]C[通道数] cout << m1 << endl; //或者,利用IplImage指针来初始化,将IplImage*转化为Mat IplImage* image = cvLoadImage("lena.jpg"); Mat mat = cvarrToMat(image); //Mat转IplImage: IplImage img = IplImage(mat); //或者 Mat m2; m2.create(4, 5, CV_8UC(2)); //点的表示:Point Point p; p.x = 1; //x坐标 p.y = 1; //y坐标 //或者 Point p2(1, 1); //颜色的表示:Scalar(b,g,r);注意不是rgb,注意对应关系 Scalar(1, 1, 1); //尺寸的表示:Size Size(5, 5);// 宽度和高度都是5 //矩形的表示:Rect,成员变量有x,y,width,height Rect r1(0, 0, 100, 60); Rect r2(10, 10, 100, 60); Rect r3 = r1 | r2; //两个矩形求交集 Rect r4 = r1 & r2; //两个矩形求并集 waitKey(0);}

访问图片中像素的方式

#include
#include
using namespace std;using namespace cv;//访问每个像素,我喜欢使用指针的方式int main(){ Mat img = imread("lol1.jpg"); for (int i = 0; i < img.rows; i++) { uchar* data = img.ptr
(i); //获取第i行地址 for (int j = 0; j < img.cols; j++) { printf("%d\n",data[j]); } } waitKey(0);}

直方图均衡化

#include
#include
using namespace std;using namespace cv;//直方图均衡化int main(){ Mat img = imread("lol3.jpg"); imshow("原始图", img); Mat dst; cvtColor(img, img, CV_RGB2GRAY); imshow("灰度图", img); equalizeHist(img, dst); imshow("直方图均衡化", dst); waitKey(0);}

显然均衡化后的图片对比度变高了,变得更加明亮!

1093303-20170519164703728-713193608.png

最后简单总结一下图像处理中概念

离散傅里叶变换

图像高频部分代表了图像的细节、纹理信息;低频代表了图像的轮廓信息。

低通-》模糊

高通-》锐化

腐蚀和膨胀是针对白色部分(高亮部分)而言的。膨胀就是对图像高亮部分进行“领域扩张”,效果图拥有比原图更大的高亮区域;腐蚀是原图中的高亮区域被蚕食,效果图拥有比原图更小的高亮区域。

开运算:先腐蚀再膨胀,用来消除小物体

闭运算:先膨胀再腐蚀,用于排除小型黑洞

形态学梯度:就是膨胀图与俯视图之差,用于保留物体的边缘轮廓。

顶帽:原图像与开运算图之差,用于分离比邻近点亮一些的斑块。

黑帽:闭运算与原图像之差,用于分离比邻近点暗一些的斑块。

转载地址:http://tqmbx.baihongyu.com/

你可能感兴趣的文章
map的erase()释放内存
查看>>
spring-boot | 整合Redis缓存数据
查看>>
国外研究员研发薄而柔韧的新柔性材料 拉伸和压缩可产生电流
查看>>
多进程问题
查看>>
【编程练习】复习一下树的遍历
查看>>
电视台成阿里云下一个大数据重塑目标
查看>>
5G:在期待中缓行
查看>>
RabbitMQ管理(1)——多租户与权限
查看>>
Android Studio2.2 使用CMake编译 C/C++
查看>>
vivo独家冠名天猫双十一狂欢夜,一个新的经典即将到来
查看>>
微软为啥让免费升Win10?
查看>>
SaaS与云计算的区别
查看>>
关于SQLServer的游标类型、锁定类型
查看>>
JAVA通信编程(三)——TCP通讯
查看>>
PHP设计模式——职责链模式
查看>>
ExtJs之Ext.ElementLoader.load
查看>>
Mysql 第三篇:完整性约束
查看>>
朱近之:云计算对21世纪IT人才的挑战
查看>>
何召卫博士:我在阿里干了三年的总结
查看>>
Day3---D2:治理与企业风险管理
查看>>