参考资料:彩色图像灰度化
图片灰度化与转换为八位灰度图片
1、灰度化公式
-
彩色图像灰度化的算法公式一般有如下两种:明度公式,视觉公式。
-
明度公式:实际上就是取一个像素的红绿蓝三通道均值,将均值作为该像素的灰度值,以此实现灰度化效果。
-
视觉公式:由于人眼对于颜色的感应是不同的,人眼对绿色的敏感最高,对蓝色敏感最低,因此,上述公式是通过对像素R、G、B三分量进行加权平均,得到一种较合理的灰度图像,该公式也是最经典的灰度化公式。
-
结果写入,红绿蓝以相同程度进行混合,即呈现为灰色图像。
2、24 位真彩图灰度化
- 在 24 位真彩图的灰度化中,在公式之中的情况下,就可以利用公式进行编写了,其实现过程也比较简单。
/************************************************************
*Function: Bmp24_2_GrayBmp24
*Description: 24 位真彩图图片灰度化
*Params: imgData - 位图数据
* width - 图像宽度
* height - 图像高度
* mode - 灰度化方式,枚举类型
*Return: None
************************************************************/
void Bmp24_2_GrayBmp24(uint8_t* imgData, uint32_t width, uint32_t height, int mode)
{
// 计算真实的行字节
uint32_t realWidth = WidthBytes(width * 24);
// 循环处理像素数据
for (uint32_t i = 0; i < height; i++) {
for (uint32_t j = 0; j < width; j++) {
// 定义 gray 灰度值,以及计算真实位图数据位置偏移量,对应于图像的各像素点RGB的起点
uint8_t gray = 0;
uint32_t point = i * realWidth + j * 3;
// 模式选择
switch (mode)
{
case 1:
gray = (imgData[point] + imgData[point + 1] + imgData[point + 2]) / 3; // 平均计算
break;
default:
gray = (imgData[point] * 114 + imgData[point + 1] * 587 + imgData[point + 2] * 299 + 500) / 1000; // 视觉公式
break;
}
// 数据写入
imgData[point] = imgData[point + 1] = imgData[point + 2] = gray;
}
}
}
3、24 位真彩图转换成 8 位灰度图片
- 计算结果图片的真实行字节,因为图片的像素位数不同,因此图片的真实行字节也不同。
- 开辟空间,用于存储结果数组。
- 若将 24 位真彩图转换成 8 位灰度图片,其在结果图片像素个数中进行两层循环,进行结果值的存储。
/************************************************************
*Function: Bmp24_2_GrayBmp8
*Description: 讲 24 位真彩图图片 转换成 8 位灰度图片
*Params: imgData - 位图数据
* width - 图像宽度
* height - 图像高度
* mode - 灰度化方式,枚举类型
*Return: None
************************************************************/
uint8_t* Bmp24_2_GrayBmp8(uint8_t* imgData, uint32_t width, uint32_t height, int mode)
{
// 计算真实的行字节
uint32_t realWidth = WidthBytes(width * 24); // 原始图片的真实行字节
uint32_t dstRealWidth = WidthBytes(width * 8); // 目标图片的真实行字节
// 数据的写入
uint32_t num = 0; // 在结果数组中,定位真实的数据位置
uint8_t* dstData = new uint8_t[dstRealWidth * height](); // 开辟结果图像空间
// 计算计算与写入
for (uint32_t i = 0; i < height; i++) {
for (uint32_t j = 0; j < dstRealWidth; j++) { // 此时的 宽 为 行字节,保障完全被处理
uint8_t gray = 0;
uint32_t point = i * realWidth + j * 3;
// 模式选择
switch (mode)
{
case 1:
gray = (imgData[point] + imgData[point + 1] + imgData[point + 2]) / 3; // 平均计算
break;
default:
gray = (imgData[point] * 114 + imgData[point + 1] * 587 + imgData[point + 2] * 299 + 500) / 1000; // 视觉公式
break;
}
dstData[num++] = gray;
}
}
return dstData;
}
一只连 ID 都重复的菜狗
发布了101 篇原创文章 · 获赞 1 · 访问量 1229
私信
关注