天天看点

opencv 把3通道图像转成单通道_数字图像处理之opencv中Mat数据操作

数字图像处理其实就是处理二维矩阵数据。利用opencv来学习处理算法是一种比较好的方式。学习opencv,主要就是调用其中的图像处理函数来实现各种操作。如果要得到想要的处理结果,还需要对图像处理算法有一定的了解。同时,可能也有自己想写一些算法的冲动,并急切的想验证自己写的算法是否能够满足处理的要求。可是,真正到自己动手写的时候,总发现无从下手,比如,想得到图像中的ROI区域(感兴趣区域),想对图像做加减运算算,将两幅图像连接成一幅图像等等。如果要想随心所欲的按照自己的想法来操作一幅图像,则需要对opencv的mat数据操作非常熟练,建议初学者将这些基本的操作背下来,然后你会发现,你再进行这样的操作将是得心应手。

在opencv中对图像数据进行操作,我们可以简单的把mat数据看成一个二维数,里面存储的就是图像的数据,所以,对mat数组的操作就是在操作二维图像数据。下面我们来实现常见的Mat数据操作。

首先,在c++中新建一个空的控制台程序,然后,在属性管理器中添加我们之前设置好的opencv4.0配置文件,回到解决方案界面,选择源文件,右键添加新项目,然后得到一个空白的源文件,如图1和图2所示。

opencv 把3通道图像转成单通道_数字图像处理之opencv中Mat数据操作

图1添加配置好的opencv配置文件

opencv 把3通道图像转成单通道_数字图像处理之opencv中Mat数据操作

图2 添加空白的源文件

然后,就可以在这个空白的源文件中写代码了。下面用具体的代码来说明怎么操作mat数据。下面的代码都可以直接复制到自己的工程中直接运行如果涉及到要打开图像文件的,直接替换代码中的文件路径为自己电脑中的图像路径就可以了。

int main(int argc, char** argv){//构造3X3的Mat矩阵// CV_8UC1和CV_8UC3是数据类型和通道,指8位无符号单通道和3数据,通道数据Mat a(Size(3,3),CV_8UC1);Mat b = Mat(Size(3,3),CV_8UC3);cout<
           
opencv 把3通道图像转成单通道_数字图像处理之opencv中Mat数据操作

图3 输出构造的mat数据

图3是上面代码输出的结果,a是单通道,b是三通道,所以b是3行9列。里面的具体的值是opencv随机自动给的,因为我们还没有对mat赋值,这个不用管。再来看几个操作,

Mat mz = Mat::zeros(Size(5,5),CV_8UC1);//构造5X5的全是0的mat数据

Mat mo = Mat::ones(Size(5,5),CV_8UC1);// 构造5X5的全是1的mat数据

Mat me = Mat::eye(Size(5,5),CV_8UC1); 构造5X5的单位矩阵的mat数据

上面的代码可以直接在上面的main函数里面接着往下写。图4是输出结果

opencv 把3通道图像转成单通道_数字图像处理之opencv中Mat数据操作

图4 上面三行代码的输出结果

接着往下写。

下面我们重新写一个main函数,不自己构造mat数据,直接从图像中得到。然后对图像数据的mat进行操作

opencv 把3通道图像转成单通道_数字图像处理之opencv中Mat数据操作

图5 输出结果显示

上面包括了mat数据的主要操作命令,如果能够把这些命令记住了,要对图像做一般的操作基本上没有什么问题了。

此外,如果要访问图像中的每一个像素值,可以采用下面指针的方式,速度是最快的。下面的代码只是演示了怎么使用指针访问像素,没有什么特别的目的。

Mat dyImg = Mat(src1.rows, src1.cols,0);

for(int i=0;i

{

uchar* srcdata = src1.ptr(i);

uchar* dydata = dyImg.ptr(i);

for(int j=0;j< src1.cols;j++)

{

double tempValue = double(srcdata [j]) + 20.0;

if(tempValue < 0)

dydata[j] = 0;

else if(tempValue > 255)

dydata[j] = 255;

else

dydata[j] = tempValue;

}

}

namedWindow("dyImg ",0);

imshow("dyImg ", dyImg);

继续阅读