嵌入式人工智能应用-第三章 opencv操作 4 灰度处理
嵌入式人工智能应用
嵌入式人工智能应用-第三章 opencv操作 4 灰度处理
- 嵌入式人工智能应用
- 1 灰度处理
- 2 算法
- 2.1 均值方法
- 2.2 最大值法
- 2.3 分量法
- 2.4 加权平均法(Weighted Average Method)
- 2.5 系统自带方法
- 3 总结
1 灰度处理
图像灰处理即是将一幅彩色图像转换为灰度化图像的过程。彩色图像通常包括 R、G、B 三个分量,分别显示出红绿蓝等各种颜色,灰度化就是使彩色图像的 R、G、B 三个分量相等的过程。灰度图像中每个像素仅具有一种样本颜色,其灰度是位于黑色与白色之间的多级色彩深度,灰度值大的像素点比较亮,反之比较暗,像素值最大为 255(表示白色),像素值最小为 0(表示黑色)。灰度处理有很多中方法,例如一张彩色图片,OpenCV 在读取这张图片的时候就可以直接读取为灰度图像。还可以调用 OpenCV 提供的 cvtColor 接口进行灰度处理(前面的实验中已经用到了)。还可以使用平均值法、最大值法、分量法、加权平均法等让一张彩色的图片转换成灰度图像。
灰度处理是将彩色图像转换为灰度图像的过程,保留亮度信息但丢弃颜色信息,常用于简化计算、提升处理速度或适配某些算法(如边缘检测)。
2 算法
2.1 均值方法
均值法就是 把每个像素的 B、G、R 三个颜色通道的值加起来,然后取平均值,作为这个像素的灰度值。
公式如下:
✅ 优点:
实现简单
运算速度快
❌ 缺点:
没考虑人眼对颜色的敏感度(人眼对绿色更敏感,对蓝色不敏感)
效果可能不如加权平均法自然
// 均值法
cv::Mat grayByMean(const cv::Mat& colorImage) {cv::Mat grayImage(colorImage.size(), CV_8UC1);for (int i = 0; i < colorImage.rows; i++) {for (int j = 0; j < colorImage.cols; j++) {cv::Vec3b pixel = colorImage.at<cv::Vec3b>(i, j);uchar gray = (pixel[0] + pixel[1] + pixel[2]) / 3; // B + G + RgrayImage.at<uchar>(i, j) = gray;}}return grayImage;
}
2.2 最大值法
最大值法是一种将彩色图像转换为灰度图像的简单方法。它的原理是 取每个像素的 B、G、R 三个颜色通道中数值最大的那个,作为灰度值。
最大值法的特点:
会强调颜色中最亮的分量,比如绿色值大,那么灰度图会更亮。
有点像对图像的“亮度增强”处理,所以整体可能比加权平均法或均值法看起来更亮一些。
✅ 优点:
简单,容易实现
能强调图像中亮的部分,对某些场景有用(如亮度检测)
❌ 缺点:
不符合人眼感知模型,容易失真
会丢失颜色信息之间的平衡,某些细节可能变得不自然
// 最大值法
cv::Mat grayByMax(const cv::Mat& colorImage) {cv::Mat grayImage(colorImage.size(), CV_8UC1);for (int i = 0; i < colorImage.rows; i++) {for (int j = 0; j < colorImage.cols; j++) {cv::Vec3b pixel = colorImage.at<cv::Vec3b>(i, j);uchar gray = std::max({pixel[0], pixel[1], pixel[2]});grayImage.at<uchar>(i, j) = gray;}}return grayImage;
}
2.3 分量法
分量法就是:直接使用彩色图像中某一个颜色通道(R、G 或 B)来作为灰度图像的灰度值。换句话说,不做任何计算,直接拿一个通道的值当作灰度值。
✅ 优点:
运算快(不需要计算平均值或加权)
可用于突出某种颜色特征的区域,比如只关注红色区域就用 R 通道
❌ 缺点:
不是真正意义上的“综合灰度图”
颜色失衡,比如只看 R,图像中其他颜色会被忽略
// 分量法(以红色通道为例)
cv::Mat grayByComponent(const cv::Mat& colorImage, int channel = 2) {// channel = 0: Blue, 1: Green, 2: Redcv::Mat grayImage(colorImage.size(), CV_8UC1);for (int i = 0; i < colorImage.rows; i++) {for (int j = 0; j < colorImage.cols; j++) {grayImage.at<uchar>(i, j) = colorImage.at<cv::Vec3b>(i, j)[channel];}}return grayImage;
}
2.4 加权平均法(Weighted Average Method)
把 B、G、R 三个颜色通道按照人眼对它们的感知敏感度,给不同的权重,计算出一个灰度值。
这个权重是根据**人眼对颜色的感知模型(ITU-R BT.601 标准)**定下来的:
人眼对 绿色最敏感,所以权重大:0.587
对 红色也比较敏感:0.299
对 蓝色不太敏感:0.114
✅ 优点:
最符合人眼视觉感知的灰度图
图像细节自然、对比度适中
是工业界和学术界默认方法(包括 OpenCV、Pillow、Matlab 等)
❌ 缺点:
运算稍微比“均值法”复杂一点(但在现代计算中可以忽略)
// 加权平均法
cv::Mat grayByWeightedAverage(const cv::Mat& colorImage) {cv::Mat grayImage(colorImage.size(), CV_8UC1);for (int i = 0; i < colorImage.rows; i++) {for (int j = 0; j < colorImage.cols; j++) {cv::Vec3b pixel = colorImage.at<cv::Vec3b>(i, j);uchar gray = static_cast<uchar>(0.114 * pixel[0] + 0.587 * pixel[1] + 0.299 * pixel[2]);grayImage.at<uchar>(i, j) = gray;}}return grayImage;
}
2.5 系统自带方法
将彩色图像转换为灰度图像。
cv::cvtColor(src, dst, cv::COLOR_BGR2GRAY);