一般来讲,opencv中的图像在处理时需要具备对称性,即三通道的图像复制到一个Mat类型的矩阵中(说白了就是图像复制),那么该矩阵定义也应当是3通道的,这样操作时候不会出问题,那么我如果把三通道的图像变成一个单通道的灰度图像,怎么办?当然可以的,定义的单通道的灰度图就可以了,只是访问的时候不能使用传统的三通道的访问格式,即使用动态地址来对图像的像素进行操作,这样会出问题的,当然你也可以定义一个三通道的矩阵,只使用其中一个通道就可以,但是出来的图就是彩色图,为什么只有一个通道有像素值,却会出现彩色图呢?因为另外两个通道默认为0,相当于RGB图中有两个通道的像素值是0,所以还是彩色图,但是这不妨碍我们使用一个通道来计算图像的值,
来看。
Mat M(src.rows,src.cols,CV_8UC3,Scalar(0,0,0)); //三通道
for(int y=0;y<src.rows;y++)
{
//uchar*data=M.ptr<uchar>(y);
for(int x=0;x<src.cols;x++)
{
M.at<Vec3b>(y,x)[0]=(src.at<Vec3b>(y,x)[0]+src.at<Vec3b>(y,x)[1]+src.at<Vec3b>(y,x)[2])/3;
// data[x]=(src.at<Vec3b>(y,x)[0]+src.at<Vec3b>(y,x)[1]+src.at<Vec3b>(y,x)[2])/3;
}
}
原图:
单通道的彩色图:
好了,我用的是彩色图的第一通道,所以就是这个样子了
更改代码
Mat M(src.rows,src.cols,CV_8UC1,Scalar(0,0,0)); //注意单通道,我的图像访问形式也变了,采用指针而不是动态地址了
for(int y=0;y<src.rows;y++)
{
uchar*data=M.ptr<uchar>(y);
for(int x=0;x<src.cols;x++)
{
// M.at<Vec3b>(y,x)[0]=(src.at<Vec3b>(y,x)[0]+src.at<Vec3b>(y,x)[1]+src.at<Vec3b>(y,x)[2])/3;
data[x]=(src.at<Vec3b>(y,x)[0]+src.at<Vec3b>(y,x)[1]+src.at<Vec3b>(y,x)[2])/3;
}
}
原图一样,单通道图如下:
这一看就是灰度图,不过是彩色图三通道平均值得到的