OpenCV探索之路(二):图像处理的基础知识点串烧
opencv图像初始化操作
#include<opencv2\opencv.hpp>
#include<opencv2\highgui\highgui.hpp>
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<opencv2\opencv.hpp>
#include<opencv2\highgui\highgui.hpp>
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;
}
原始图

两种二值化效果对比

腐蚀操作
#include <iostream>
#include <opencv2\opencv.hpp>
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;
}
运行效果

使用 均值滤波实现图像模糊
#include <iostream>
#include <opencv2\opencv.hpp>
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;
}
运行效果

canny边缘检测
思路:将原始图像转化为灰度图,用blur函数进行图像模糊以降噪,然后用canny函数进行边缘检测。
#include <iostream>
#include <opencv2\opencv.hpp>
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;
}
运行效果

基础图像操作
创建窗口: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¶ms = std::vector());
创建trackbar以及使用
下面的例子利用trakbar打开多个图片。
#include<opencv2\opencv.hpp>
#include<opencv2\highgui\highgui.hpp>
using namespace std;
using namespace cv;
#define PIC_MAX_NUM 5
int 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);
}
展示一下效果吧!


对一幅图片进行颜色转换,转为灰度图
#include<opencv2\opencv.hpp>
#include<opencv2\highgui\highgui.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat img = imread("lol1.jpg");
Mat dstImg;
cvtColor(img, dstImg,COLOR_BGR2GRAY);//从宏名字就可以知道,是彩色图转换到灰度图
imshow("灰度图", dstImg);
waitKey(0);
}
灰度图

总结一系列常用的数据结构
#include<opencv2\opencv.hpp>
#include<opencv2\highgui\highgui.hpp>
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<opencv2\opencv.hpp>
#include<opencv2\highgui\highgui.hpp>
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<uchar>(i); //获取第i行地址
for (int j = 0; j < img.cols; j++)
{
printf("%d\n",data[j]);
}
}
waitKey(0);
}
直方图均衡化
#include<opencv2\opencv.hpp>
#include<opencv2\highgui\highgui.hpp>
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);
}
显然均衡化后的图片对比度变高了,变得更加明亮!

最后简单总结一下图像处理中概念
离散傅里叶变换
图像高频部分代表了图像的细节、纹理信息;低频代表了图像的轮廓信息。
低通-》模糊
高通-》锐化
腐蚀和膨胀是针对白色部分(高亮部分)而言的。膨胀就是对图像高亮部分进行“领域扩张”,效果图拥有比原图更大的高亮区域;腐蚀是原图中的高亮区域被蚕食,效果图拥有比原图更小的高亮区域。
开运算:先腐蚀再膨胀,用来消除小物体
闭运算:先膨胀再腐蚀,用于排除小型黑洞
形态学梯度:就是膨胀图与俯视图之差,用于保留物体的边缘轮廓。
顶帽:原图像与开运算图之差,用于分离比邻近点亮一些的斑块。
黑帽:闭运算与原图像之差,用于分离比邻近点暗一些的斑块。
OpenCV探索之路(二):图像处理的基础知识点串烧的更多相关文章
- python学习笔记(二):基础知识点
python基本元素 7 // 2 3 7 % 3 1 # 取商以及余数 divmod(7,3) (2, 1) 1j*1j (-1+0j) 10/3 3.3333333333333335 '3,''1 ...
- Hadoop基础知识串烧
 YARN资源调度: 三种 FIFO 大任务独占 一堆小任务独占 capacity 弹性分配 :计算任务较少时候可以利用全部的计算资源,当队列的任务多的时候会按照比例进行资源平衡. 容量保证:保证队 ...
- ☕【Java技术指南】「难点-核心-遗漏」Java线程状态流转及生命周期的技术指南(知识点串烧)!
前提介绍 本章主要介绍相关线程声明周期的转换机制以及声明周期的流转关系以及相关AQS的实现和相关的基本原理,配合这相关官方文档的中英文互译的介绍. 线程状态流转及生命周期 当线程被创建并启动以后,它既 ...
- Java基础知识点(四)
前言:记录Java基础知识点,方便熟悉与掌握. 1.面向对象的"六原则一法则" “六原则一法则”:单一职责原则.开闭原则.依赖倒转原则.里氏替换原则.接口隔离原则.合成聚合复用原则 ...
- Java基础知识点(三)
前言:准备将Java基础知识点总结成一个系列,用于平常复习并加深理解.每篇尽量做到短小精悍,便于阅读. 1.Math类中相关函数 Math.floor(x):返回不大于x的最大整数.eg:Math.f ...
- Java基础知识点(一)
前言:本篇随笔,主要记录Java的基础知识点,不管是用于项目或者面试中,笔者认为都非常有用,所以将持续更新...... 1.Java的访问权限 Java中有四种访问权限:默认访问权限.public.p ...
- OpenCV探索之路(二十四)图像拼接和图像融合技术
图像拼接在实际的应用场景很广,比如无人机航拍,遥感图像等等,图像拼接是进一步做图像理解基础步骤,拼接效果的好坏直接影响接下来的工作,所以一个好的图像拼接算法非常重要. 再举一个身边的例子吧,你用你的手 ...
- [OpenCV-Python] OpenCV 中的图像处理 部分 IV (二)
部分 IVOpenCV 中的图像处理 OpenCV-Python 中文教程(搬运)目录 16 图像平滑 目标 • 学习使用不同的低通滤波器对图像进行模糊 • 使用自定义的滤波器对图像进行卷积(2D 卷 ...
- java基础知识点补充---二维数组
#java基础知识点补充---二维数组 首先定义一个二维数组 int[][] ns={ {1,2,3,4}, {5,6,7,8}, {9,10,11,12}, {13,14,15,16} }; 实现遍 ...
随机推荐
- 工作中git 操作汇总
1. git branch -l 查看本地branch 2. git reset --hard 回滚全部修改 3. git status 查看本地修改 4. git pull 更新代码 5. gi ...
- hdu 4869 Turn the pokers (思维)
Turn the pokers Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- iOS 6.0中UIViewController被弃用的一些方法
郝萌主倾心贡献.尊重作者的劳动成果,请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠,支持郝萌主,捐赠数额任意.重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 概念:de ...
- 关于模式识别中的domain generalization 和 domain adaptation
今晚听了李文博士的报告"Domain Generalization and Adaptation using Low-Rank Examplar Classifiers",讲的很精 ...
- VUE-CLI Vue安装及开发,npm run build无法查看项目的问题
Vue-cli 本地安装vue项目 需要安装node.js,用node命令行npm的方式安装Vue 步骤: 1.进入项目地址安装 npm install vue-cli -g 2.初始化一下 ESli ...
- java表单重复提交常用解决办法
最近在看些基础的东西,顺便做下笔记.相信大家在平时网页使用中,经常会有按钮重复点击,然后点不动刷新,还有当网络延时比较厉害点了没反应在点击的重复提交.为了避免这种情况,总结了一下4点处理方案 表单重复 ...
- #ifdef #else #endif #if #ifndef 的用法
预编译就是在对源文件进行处理之前(如在语法扫描和分析之前),先处理预处理部分,精简代码,然后再进行编译. 预处理命令有:#include 文件包含.#define 宏定义.以及要重点讲的#if.#if ...
- 什么是副作用(Side Effect)
副作用(Side Effect)是指函数或者表达式的行为依赖于外部世界.具体可参照Wiki上的定义,副作用是指 1)函数或者表达式修改了它的SCOPE之外的状态 2)函数或者表达式除了返回语句外还与外 ...
- laravel and lumen 软删除操作
知识都是有联系的,这绝对是真理.作为一名小白,看了一点官方文档,把我自己理解的软删除操作给大家讲讲.有些就是套用官方文档的话. 定义:什么是软删除呢,所谓软删除指的是数据表记录并未真的从数据库删除,而 ...
- ArcGIS API for JavaScript 4.2学习笔记[8] 2D与3D视图同步
同一份数据不同视图查看可能用的比较少,因为3D视图放大很多后就和2D地图差不多了,畸变很小,用于超大范围的地图显示时有用,很多时候都是在平面地图上进行分析.查询.操作.教学需要可能会对这个有要求? 本 ...