前言:
欢迎来到本博客
本专栏主要结合OpenCV和C++来实现一些基本的图像处理算法并详细解释各参数含义,适用于平时学习、工作快速查询等,随时更新。
具体食用方式:可以点击本专栏【OpenCV快速查找(更新中)】–>搜索你要查询的算子名称或相关知识点,或者通过这篇博客通俗易懂OpenCV(C++版)详细教程——OpenCV函数快速查找(不断更新中)]查阅你想知道的知识,即可食用。
支持:如果觉得博主的文章还不错或者您用得到的话,可以悄悄关注一下博主哈,如果三连收藏支持就更好啦!这就是给予我最大的支持!
首先,对灰度图像做个简单介绍。例如,计算机中存储的一张灰度图像,右击–>属性–>详细信息。
下图中,每一个方格代表图像的一个像素,水平方向上的方格数对应上图中的“宽度”,垂直方向上的方格数对应上图中的“高度”,计算机会将每一个方格数字化为一个数值,上图中的“位深度”是8(bit),代表将每一个方格数字化为[0,255]之间的uchar
类型数字,即用256个数字来衡量灰度的深浅,值越大,代表越亮,值越小,代表越灰,255代表白色,0代表黑色。
实际上,计算机“看到”这张图像是一个224行(高度)*224列(宽度)
的二维数字矩阵。数字图像处理的本质就是操作矩阵。
(1) 读取
在 opencv2/highgui/highgui.hpp
头文件中声明了读取本地磁盘中的灰度图像并转换为Mat的函数:
Mat imread(const string filename,int flags=1);
本专栏主要以OpenCV3.x为主,对于OpenCV2.x与OpenCV3.x版本略有区别:
版本 | filename | flags |
---|---|---|
OpenCV2.x | 图像文件名(可含路径) | CV_LOAD_IMAGE_COLOR:彩色图像;CV_LOAD_IMAGE_GRAYSCALE:灰度图像;CV_LOAD_IMAGE_ANYCOLOR:任意图像 |
OpenCV3.x | 同上 | IMREAD_COLOR:彩色图像;IMREAD_GRAYSCALE:灰度图像;IMREAD_ANYCOLOR:任意图像 |
(2) 显示
参数flags
为常用的几种。相反,如何将Mat对象作为图像进行显示呢?在highgui
模块中定义了imshow
函数来完成该功能。
void imread(const string winname,InputArray mat);
winname
:显示图像窗口名;
mat
:Mat对象;
imread
和imshow
这两个函数,就可以完成读取并显示图像了。下面演示一个灰度图像读取显示小程序:
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
int main(int argc, char**argv) {
Mat image;
image = imread("D:/VSCodeFile/OpenCV_CSDN/image/logo_gray.jpeg",IMREAD_GRAYSCALE);
if (image.empty()){
return -1;
}
//namedWindow("图片显示", WINDOW_AUTOSIZE);
string winname = "图片显示";
imshow(winname,image);
waitKey(0);
//destroyAllWindows();
return 0;
}
注意: 如果读取一个彩色图像文件,imread的参数flags
设置的是读入灰度图像,那么会对彩色图像进行灰度化处理。
同样,对彩色图像做个简单介绍,对彩色图像数字化的理解,和对灰度图像数字化的理解类似。例如,计算机中存储的一张彩色图像,右击–>属性–>详细信息。
使用图像编辑器打开该图像,放大观察图像,会出现类似于下图的样子,有很多小方格,但是这些方格都是彩色的,不是灰色的。其实每一个彩色的方格都是由三个数值量化的,或者说是由一个具有三个元素的向量量化的。
灰度图像的每一个像素都是由一个数字量化的,而彩色图像的每一个像素都是由三个数字组成的向量量化的。最常用的是由R、G、B三个分量来量化的,具体色彩的值用三个元素的向量来表示,这三个元素的数值分别代表三种基色:Red、Green、Blue的亮度。
假设每种基色的数值量化成m= 2 n 2^n 2n个数,如同8位灰度图像一样,将灰度量化成 2 8 2^8 28 =256个数。RGB图像的红、绿、蓝三个通道的图像都是一张8位图,因此颜色的总数为 25 6 3 256^3 2563 =16777216,如:
(0,0,0)
:代表黑色;
(255,255,255)
:代表白色;
(255,0,0)
:代表红色。
需将imread的flags
修改一下,就可以将彩色图像转换为三通道的Mat对象,对于彩色图像的每一个方格,我们可以理解为一个Vec3b
。
需要注意的是:在OpenCV中,每一个像素的向量不是按照R、G、B分量排列的,而是按照B、G、R顺序排列的,所以通过split
函数分离通道后,先后得到的是B、G、R通道。
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
int main(int argc, char**argv) {
//彩色图像
Mat image;
image = imread("D:/VSCodeFile/OpenCV_CSDN/image/logo.jpeg",IMREAD_COLOR);
vector<Mat> Img;
split(image, Img);
imshow("原图", image);
//channel--1
Mat channel_1 = Img[0];
imshow("第一通道—Blue", channel_1);
//channel--2
Mat channel_2 = Img[1];
imshow("第二通道—Green", channel_2);
//channel--1
Mat channel_3 = Img[2];
imshow("第三通道--Red", channel_3);
waitKey(0);
return 0;
}
图中,经过和原图对比,可以直观感受到不同通道图像的差异。
最后,长话短说,大家看完就好好动手实践一下,切记不能三分钟热度、三天打鱼,两天晒网。OpenCV是学习图像处理理论知识比较好的一个途径,大家也可以自己尝试写写博客,来记录大家平时学习的进度,可以和网上众多学者一起交流、探讨,有什么问题希望大家可以积极评论交流,我也会及时更新,来督促自己学习进度。希望大家觉得不错的可以点赞、关注、收藏。
今天的文章就到这里啦~
喜欢的话,点赞、收藏⭐️、关注哦 ~