赞
踩
我们的目标是:使用代码把两张图片拼接在一起
本节内容A:OpenCV视角下的图片
本节内容B:OpenCV处理图像的Class
OpenCV习惯将图片数据加载到类cv::Mat
中,通过Mat的member Function
或者以Mat
为处理对象的算法进行图像处理。如上图所示,模板类Mat
支持多种数据类型。
OpenCV的官方文档中给出了Mat的member Functions和其参数表的说明,详情可访问:https://docs.opencv.org/master/d3/d63/classcv_1_1Mat.html
据文档描述,Mat是一种支持复数处理的多维矩阵,可以用各种标准的数据结构——譬如vector来初始化一个Mat。
总而言之,有了Mat,就可以忽略各中图片文件格式,可以直接用类似于下列的方法把图片数据加载到Mat中进行处理,十分方便。
Mat imga = imread("D:\\cat.jpg");
令人兴奋的是,一般情况下,我们可以把Mat看成是一个存放像素数据的多维数组(一般二维),通过数组操作进行图像处理。
Mat的内部类似于这样:
噢对!图片的组成类似于这样(可以把(单色)图片看成是各种许多个具有不同亮度的像素点组成的点阵,每下图黄色框内的每个数字都代表着对应点的亮度):
而彩色图片的数据则像这样组织起来:
For multichannel images the columns contain as many sub columns as the number of channels. For example in case of an BGR color system:
(每个像素点都由蓝绿红三个通道的亮度数据组成)
了解一个数据容器的结构之后,接着就应该思考如何遍历这个容器中的数据,刚才介绍过了,可以使用类似于操作一般数据容器(譬如数组)的方法处理Mat的数据,譬如这样遍历一个装有彩色图片的数据的Mat
对象imga
:
for (int i = 1;i < imga.rows;i++) {
for (int j = 1;j < imga.cols;j++) {
for(int c =1;c<imga.channels();c++)
imga.at<Vec3b>(i, j)[c] = 0;
}
}
其中:
A、rows
(行)和cols
(列)都是Mat的属性,(i,j)
对应着Mat
中某个像素点的数据(包含着BGR三个通道的数据);
B、channels()是Mat的member Function,返回Mat的通道数;
C、imag.at(i,j)[c]可以访问到图片中任一像素点的某一通道的数据,具体介绍参考官方文档的cv::Mat::at部分。
类似的,还可以采用如下方法遍历单通道(灰度)图片的数据:
for (int i = 1;i < imga.rows;i++) {
for (int j = 1;j < imga.cols;j++) {
for(int c =1;c<imga.channels();c++)
imga.at<uchar>(i, j) = 0;
}
}
当然,也可以采用迭代器的方法遍历:
for (auto it = imga.begin<uchar>();it != imga.end<uchar>();it++) {
*it = 0;
}
下一节:用图片拼接实例熟悉CV矩阵操作
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。