微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将 16 位 (RBG565) 转换为灰度图像的 C 代码

如何解决将 16 位 (RBG565) 转换为灰度图像的 C 代码

我正在尝试将 16 位 (RBG565) 转换为灰度图像。我尝试了互联网上建议的各种公式组合,都适用于 24 位 RGB888 格式。当我尝试使用 16 位 (RBG565) 时,图像具有蓝色、红色像素,无法创建准确的灰度图像。请帮忙。

公式 1 比公式 2 效果更好:

公式 1: unsigned char gray = (red * 77+((green)* 150)/2 + blue * 29+128) / 256;

公式 2: 无符号字符灰色 = 红色 * 0.212 + 绿色 * 0.715 + 蓝色 * 0.072;

解决方法

由于 RGB 分量往往是每个原色从无色到全色的比例(一般意义上的原色,意味着颜色组合形成其他颜色),我可能会预先转换为 RGB,然后使用正常的灰度缩放算法(您声明“适用于 24 位 RGB888”的任何算法)。

第一个位可能可以用(大写是八位值,小写是 5/6 位值):

R = r * 8 ; 256/32,8-bit from 5-bit
B = b * 4 ; 256/64,8-bit from 6-bit
G = g * 8 ; 256/32,8-bit from 5-bit

在提取位时确保顺序正确,因为您正在将 RBG 转换为 RGB


例如,这里有一个完整的 C 程序(因为您没有提供语言标记),其中包含一个可以执行此操作的函数,但它使用的缩放比例略有不同,该缩放比例依赖于百分比而不是需要 0..255 的固定值输入:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

uint16_t greyScale(uint16_t rbg565) {
    // Get the values (32-bit to hold larger intermediate values).

    uint32_t r = (rbg565 >> 11) & 31U; // XXXXX___________
    uint32_t g = rbg565         & 31U; // ___________XXXXX
    uint32_t b = (rbg565 >> 5)  & 63U; // _____XXXXXX_____

    // Scale each of them up to the range 0..500.

    g = g * 500 / 31;
    b = b * 500 / 63;
    r = r * 500 / 31;

    // Use example RGB weights of 299/587/114 (summing to 1,000).
    // Range then 0..500,000 so divide by 500 to get grey 0..1,000.

    uint32_t grey = (r * 299 + g * 587 + b * 114);
    grey /= 500;
    return (uint16_t)grey;
}

int main(int argc,char *argv[])
{
    for (int i = 1; i < argc; i++) {
        uint16_t rbg = atoi(argv[i]);
        printf("%5d -> %d\n",rbg,greyScale(rbg));
    }
    return 0;
}

如果你用一些示例值运行它,你会看到灰度值出来(评论是我添加的):

pax:~> ./prog 0 65535 31 $((63*32)) $((31*2048)) $((16*2048+32*32+16))
    0 -> 0       # No colour components.
65535 -> 1000    # Max RGB (white).
   31 -> 587     # Max green,nothing else.
 2016 -> 114     # Max blue,nothing else.
63488 -> 299     # Max red,nothing else.
33808 -> 514     # A little more than half of everything.

如果您想使用与我提供的权重不同的权重(29.9%、58.7% 和 11.4%),只需将此行更改为匹配,确保它们的总和仍为一千:

uint32_t grey = (r * 299 + g * 587 + b * 114);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。