本文档创建于2023年3月10日
本文记录了C++版opencv读取灰度图像的不同方式及区别
作者:RobotFreak
C++版的opencv
读取灰度图像可以有不同的方法,这里列出几种方法,并简述它们的区别。
这里用到的两张图片为lena.jpg(彩色)和lena.bmp(灰度)
直接读取灰度图像
图像本身就是灰度图像,直接使用imread()
读取图像:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat img = imread("../lena.bmp"); //读取图片
cout << "图片通道数: " << img.channels() << endl;
cout << "图片行数: " << img.rows << " 图片列数: " << img.cols << endl;
cout << img << endl;
system("pause");
return 0;
}
输出的信息如下:
可以看到直接读取灰度图像的情况下,虽然是灰度图像,但是读取的矩阵是3通道。这与灰度图像本身像素处只有灰度值一个值是不符合的。
图像读取时使用0或者IMREAD_GRAYSCALE,以灰度方式读取图图像
在调用imread
时传入参数0或者IMREAD_GRAYSCALE:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat img = imread("../lena.bmp",0); //读取图片
//Mat img = imread("../lena.bmp",IMREAD_GRAYSCALE);
cout << "图片通道数: " << img.channels() << endl;
cout << "图片行数: " << img.rows << " 图片列数: " << img.cols << endl;
cout << img << endl;
system("pause");
return 0;
}
打印信息如下:
可以看到,以灰度方式读取图像的结果,存储图像的矩阵是1通道。与上面对比,推测可能是默认按彩色3通道读取,需要指明用灰度方式读取才可以得到1通道的矩阵。而且与上方的矩阵对比发现,以默认3通道方式读取灰度图像,得到的每个像素的3个通道的值均是该像素处灰度值,把一份灰度值复制了3份。
下方是彩色图像按照默认3通道方式读取与按照灰度方式读取的打印信息对比:
- 彩色图像,默认3通道
- 彩色图像,灰度方式读取
算了一下彩色的3通道的均值,发现与imread
按照灰度方式读取得到的矩阵结果不同,可能imread
这个函数按照灰度方式读取内部并不是按照均值的方式处理的。
使用cvtColor()函数将图像转换为灰度图像
opencv
内有cvtColor()
函数用于颜色转换:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat img = imread("../lena.jpg"); //读取图片
cvtColor(img, img, COLOR_BGR2GRAY);
cout << "图片通道数: " << img.channels() << endl;
cout << "图片行数: " << img.rows << " 图片列数: " << img.cols << endl;
cout << img << endl;
system("pause");
return 0;
}
打印的结果如下:
这个结果与使用灰度方式读取彩色图像的结果相同。
同时,我还试验了将灰度图像通过cvtColor
转换为灰度图像。发现在以默认3通道方式读取后使用cvtColor
也没问题,转换完之后变为了1通道;但是以灰度方式读取灰度图像后转换颜色报错。推测能够进行转换的条件是图像是3通道,而不是图像必须是彩色。
3通道取均值
将3通道图像的单个像素的3通道均值赋给另一个矩阵,得到灰度图像:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat img = imread("../lena.jpg"); //读取图片
Mat grayImg(img.rows, img.cols, CV_8UC1, Scalar(0)); //初始化目标矩阵
for (int i = 0; i < img.rows; i++)
{
for (int j = 0; j < img.cols; j++)
{
grayImg.at<uchar>(i, j) = (img.at<Vec3b>(i, j)[0] + img.at<Vec3b>(i, j)[1] + img.at<Vec3b>(i, j)[2]) / 3;
}
}
imshow("lena", img);
imshow("lena-gray", grayImg);
waitKey(0);
return 0;
}
运行结果如下:
文章来源:https://www.toymoban.com/news/detail-456503.html
总结来说,我们想要的灰度图像为单通道的。不管原始图像是灰度图像还是彩色图像,我们都需要通过以下3中方法之一得到1通道的灰度图像:文章来源地址https://www.toymoban.com/news/detail-456503.html
- 以灰度方式读取图像
imread(img,0)
- 使用
cvtColor()
函数转换为灰度图像 - 3通道取均值
到了这里,关于opencv读取灰度图像的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!