OpenCV3入门(四)图像的基础操作
1、访问图像像素
1)灰度图像
2)彩色图像
OpenCV中的颜色顺序是BGR而不是RGB。
访问图像的像素在OpenCV中就是访问Mat矩阵,常用的有三种方法。
- at定位符访问
Mat数据结构,操作灰度图像像素点:
int gray_value = (int) image.at<uchar>(i , j) ;
操作彩色图像像素点:
int color_value = (int) image.at<Vec3b>(i , j) [k];
- 指针访问
for (int i = ; i < mat.rows; i++)
{
uchar* row = mat.ptr<uchar>(i); // 行指针
for (int j = ; j < mat.cols; j++) // 遍历每一行
{
row[j] = (uchar)((j / ) * );
}
}
- 迭代器iterator访问
Mat_<Vec3b>::iterator it = M.begin<Vec3b>();//初始位置的迭代器
Mat_<Vec3b>::iterator itend = M.end<Vec3b>();//终止位置的迭代器
for (; it != itend; it++)
{
//处理BGR三个通道
(*it)[] = ;//B
(*it)[] = ;//G
(*it)[] = ;//R
}
2、图像亮度、对比度调节
图像亮度调节可以等效为图像的像素操作。如下面公式是一个线性的亮度调节。
g(x)=a*f(x) + b
其中:
g(x):处理后的图像
f(x):输入图像
a:增益(放大倍数),用来控制图像的对比度
b:偏置,用控制图像的亮度
Mat M = imread("D:/WORK/5.OpenCV/LeanOpenCV/pic_src/pic4.bmp", IMREAD_GRAYSCALE);
Mat M2 = Mat(M.rows, M.cols, CV_8UC1);
cout << M.channels() << endl;
cout << M.rows<<","<<M.cols << endl; float a = 0.5;
float b = ;
for (int i = ; i < M.rows; i++)
for (int j = ; j < M.cols; j++)
{
float pix = (float)M.at<uchar>(i, j);
pix = a * (float)pix + b;
if ((int)pix > ) pix = ;
M2.at<uchar>(i, j) = (uchar) pix;
} imshow("pic1", M);
imshow("pic2", M2);
waitKey();
3、获取图像ROI区域
图像的ROI(region of interest)是指图像中感兴趣区域、在OpenCV中图像设置图像ROI区域,实现对ROI区域操作。
方法1:
img(Rect(100, 100, 100, 100));
Rect代表一个矩形,Rect_ (_Tp _x, _Tp _y, _Tp _width, _Tp _height),参数分别是x,y,width,height。
方法2:
img(Range(100, 200), Range(100,200));
Range表示连续的行或列,Range (int _start, int _end);
示例:
Mat M = imread("D:/WORK/5.OpenCV/LeanOpenCV/pic_src/pic1.bmp");
cout << M.rows<<","<<M.cols << endl;
Mat roi = M(Rect(, , , )); imshow("pic1", M);
imshow("roi", roi);
4、图像混合
图像线性混合,产生类似画中画的效果。
h(x)=(1-a)*f(x) + b*g(x)
a的取值范围为0到1之间,通过对两幅图的像素加权得到最终的输出图像,两幅图像的大小和类型必须完全一致(两个矩阵相加维度必须一致)。
CV_EXPORTS_W void addWeighted(InputArray src1, double alpha, InputArray src2,
double beta, double gamma, OutputArray dst, int dtype = -1);
例1:图片与背景图混合
Mat M = imread("D:/WORK/5.OpenCV/LeanOpenCV/pic_src/pic1.bmp");
cout << M.rows<<","<<M.cols << endl;
Mat y(M.rows, M.cols, CV_8UC3, Scalar(, , ));
Mat dst;
addWeighted(M, 0.3, y, 0.7, 0.0, dst); imshow("pic1", M);
imshow("y", y);
imshow("add", dst);
例2:两幅图像混合,先统一尺寸
Mat M = imread("D:/WORK/5.OpenCV/LeanOpenCV/pic_src/pic1.bmp");
Mat M2 = imread("D:/WORK/5.OpenCV/LeanOpenCV/pic_src/pic2.bmp");
M2 = M2(Rect(, , M.cols, M.rows)); //x,y,width,height
cout << M.rows<<","<<M.cols << endl;
cout << M2.rows << "," << M2.cols << endl;
Mat dst;
addWeighted(M, 0.7, M2, 0.3, 0.0, dst); imshow("pic1", M);
imshow("pic2", M2);
imshow("add", dst);
5、图像多通道分离
1)函数原型
/** @brief Divides a multi-channel array into several single-channel arrays.
@param src input multi-channel array.
@param mvbegin output array; the number of arrays must match src.channels(); the arrays themselves are reallocated, if needed.
*/
CV_EXPORTS void split(const Mat& src, Mat* mvbegin); /** @overload
@param m input multi-channel array.
@param mv output vector of arrays; the arrays themselves are reallocated, if needed.
*/
2)图像颜色通道
Mat M = imread("D:/WORK/5.OpenCV/LeanOpenCV/pic_src/pic5.bmp");
vector<Mat> channels;
split(M, channels); imshow("pic1", M);
imshow("B", channels.at());
imshow("G", channels.at());
imshow("R", channels.at());
/* 方法2
Mat channels[3];
split(M, channels); imshow("pic1", M);
imshow("B", channels[0]);
imshow("G", channels[1]);
imshow("R", channels[2]);
6、图像多通道合并
图像合并函数merge是split的逆操作,将多个数组合并成多通道的数组。
merge(const Mat * mv, size_t count, OutputArray dst )
merge(InputArrayOfArrays mv, OutputArray dst )
//图像合并例子,方式1:
Mat M = imread("D:/WORK/5.OpenCV/LeanOpenCV/pic_src/pic5.bmp");
Mat channels[];
split(M, channels); imshow("pic1", M);
imshow("B", channels[]);
imshow("G", channels[]);
imshow("R", channels[]); Mat dst;
merge(channels, , dst);
imshow("merged", M);
//方式2:
Mat M = imread("D:/WORK/5.OpenCV/LeanOpenCV/pic_src/pic5.bmp");
vector<Mat> channels;
split(M, channels); imshow("pic1", M);
imshow("B", channels.at());
imshow("G", channels.at());
imshow("R", channels.at()); Mat dst;
merge(channels, dst);
imshow("merged", M);
输出如下图。
7、参考文献
1、《OpenCV3 编程入门》,电子工业出版社,毛星雨著
2、《学习OpenCV》,清华大学出版社,Gary Bradski, Adrian kaehler著
3、opencv常用api简单分析: split()、merge()
尊重原创技术文章,转载请注明。
OpenCV3入门(四)图像的基础操作的更多相关文章
- MySQL入门(1)——基础操作
MySQL入门(1)--基础操作 创建数据库 创建基本数据库: create database db_admin; 创建基本数据库(等价于CREATE DATABASE): create schema ...
- OpenCV3入门(二)Mat操作
1.Mat结构 1.1.Mat数据 Mat本质上是由两个数据部分组成的类: 矩阵头:包含信息有矩阵的大小,用于存储的方法,矩阵存储的地址等 数据矩阵指针:指向包含了像素值的矩阵. 矩阵头部的大小是恒定 ...
- 第六十四天 JS基础操作
一.分支结构 1.if语句 if基础语句 if(条件表达式){ 代码块: } // 当条件表达式结果为true,会执行代码块:反之不执行 // 条件表达式可以为普通表达式 // 0.undefined ...
- python_Opencv_图像的基础操作
目标 获取像素值并修改 获取图像的属性(信息) 图像的ROI() 图像通道的拆分及合并 为图像扩充边缘 几乎所有以上的操作,与Numpy 的关系都比与OpenCV 的关系更加紧密,因此熟练Numpy ...
- opencv3 学习四 - 图像减色
程序如下 #include "opencv2/opencv.hpp" using namespace cv; int main() { // 灰度图 Mat original = ...
- Swift语法基础入门四(构造函数, 懒加载)
Swift语法基础入门四(构造函数, 懒加载) 存储属性 具备存储功能, 和OC中普通属性一样 // Swfit要求我们在创建对象时必须给所有的属性初始化 // 如果没办法保证在构造方法中初始化属性, ...
- Python文件基础操作(IO入门1)
转载请标明出处: http://www.cnblogs.com/why168888/p/6422270.html 本文出自:[Edwin博客园] Python文件基础操作(IO入门1) 1. pyth ...
- C#基础入门 四
C#基础入门 四 方法参数 值参数:不附加任何修饰符: 输出参数:以out修饰符声明,可以返回一个或多个给调用者: 如果想要一个方法返回多个值,可以用输出参数来处理,输出参数由out关键字标识,如st ...
- 小白学 Python 数据分析(5):Pandas (四)基础操作(1)查看数据
在家为国家做贡献太无聊,不如跟我一起学点 Python 人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Panda ...
随机推荐
- Codeforces Round #612 (Div. 2)
https://codeforces.com/contest/1287/ A - Angry Students 题意:求A后面的P最长连续有几个? 题解:? int n; char s[200005] ...
- 解决springmvc报错,java.lang.IllegalArgumentException:No converter found for return value of type: class .......
1.背景 最近在自学java中的三大框架 ssm,在 springmvc 与 mybatis 整合过程中用到 json 数据交互.因为看的视频的是比较早的嘛,一些配置.jar包什么的,要么跟 jdk ...
- Java 发展简史:初生遇低谷,崛起于互联网
Java 起源与诞生 20世纪90年代,单片式计算机系统诞生,单片式计算机系统不仅廉价,而且功能强大,使用它可以大幅度提升消费性电子产品的智能化程度. SUN公司为了抢占市场先机,在1991年成立了一 ...
- Flink系列之Time和WaterMark
当数据进入Flink的时候,数据需要带入相应的时间,根据相应的时间进行处理. 让咱们想象一个场景,有一个队列,分别带着指定的时间,那么处理的时候,需要根据相应的时间进行处理,比如:统计最近五分钟的访问 ...
- 密码 | 对称加密 - AES
一.AES 算法简介 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准,用来替换 ...
- 小白学Java:包装类
目录 小白学Java:包装类 包装类的继承关系 创建包装类实例 自动装箱与拆箱 自动装箱 自动拆箱 包装类型的比较 "=="比较 equals比较 自动装箱与拆箱引发的弊端 自动装 ...
- vs删除空白行 注释
在vs编辑器中有时需要批量删除无用的空白行,为此,可以使用vs编辑器的查找替换功能: 1. Ctrl+H,打开替换功能框. 2.选择“使用正则表达式”,“当前文档”. 3.在查找框中输入: (?< ...
- Java BIO NIO 与 AIO
回顾 上一章我们介绍了操作系统层面的 IO 模型. 阻塞 IO 模型. 非阻塞 IO 模型. IO 复用模型. 信号驱动 IO 模型(用的不多,知道个概念就行). 异步 IO 模型. 并且介绍了 IO ...
- Java 设置Word页边距、页面大小、页面方向、页面边框
本文将通过Java示例介绍如何设置Word页边距(包括上.下.左.右).页面大小(可设置Letter/A3/A4/A5/A6/B4/B5/B6/Envelop DL/Half Letter/Lette ...
- 替代not in 和 in 的办法
在程序中,我们经常会习惯性的使用in和not in,在访问量比较小的时候是可以的,但是一旦数据量大了,我们就推荐使用not exists或者外连接来代替了.如果要实现一张表有而另外一张表没有的数据时, ...