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 ...
随机推荐
- 「CH2201」小猫爬山 解题报告
CH2201 小猫爬山 背景 Freda和rainbow饲养了N只小猫,这天,小猫们要去爬山.经历了千辛万苦,小猫们终于爬上了山顶,但是疲倦的它们再也不想徒步走下山了(呜咕>_<). 描述 ...
- java 多线程 快速入门
------------恢复内容开始------------ java 多线程 快速入门 1. 进程和线程 什么是进程? 进程是正在运行的程序它是线程的集合 进程中一定有一个主线程 一个操作系统可以有 ...
- python二维列表求解所有元素之和
2020-01-14 相信很多初学小伙伴都会遇到二维列表求解所有元素之和问题,下面给出两种两种常见的求和方法. 方法1: 思想:遍历整个二维列表元素,然后将所有元素加起来 def Sum_matrix ...
- Golang最强大的访问控制框架casbin全解析
Golang最强大的访问控制框架casbin全解析 Casbin是一个强大的.高效的开源访问控制框架,其权限管理机制支持多种访问控制模型.目前这个框架的生态已经发展的越来越好了.提供了各种语言的类库, ...
- SnowflakeId雪花ID算法,分布式自增ID应用
概述 snowflake是Twitter开源的分布式ID生成算法,结果是一个Long型的ID.其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器I ...
- SpringCloud之Ribbon(四)
一:Ribbon是什么? Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起.Ribbon客户端组件提供一系列完善的配置项如连接 ...
- win10 指纹无法登记
搞了好久指纹登记不了,一度认为是电脑有问题.后来终于找到答案: 那就是先删除PNI密码再登记指纹! 经过重装驱动屡试无果,最后突发奇想,把PIN码删除掉再登记指纹,果然可以了. ----------- ...
- 转:详解G1垃圾收集器
G1垃圾收集器入门 说明 concurrent: 并发, 多个线程协同做同一件事情(有状态) parallel: 并行, 多个线程各做各的事情(互相间无共享状态) 参考: What’s the dif ...
- Window下安装并使用InfluxDB可视化工具 —— InfluxDBStudio
下载 直接访问: https://github.com/CymaticLabs/InfluxDBStudio/releases/tag/v0.2.0-beta.1 创建or编辑InfluxDB 这个软 ...
- Django 滑动验证
极验官网:https://www.geetest.com/ 文档: https://docs.geetest.com/ 查看 行为验证的部署文档