将RGB值转换为灰度值的简单算法

  使场景或精灵以灰度的形式显示,这是一般游戏制作中常常用到的效果,如:战棋游戏中当一个角色被使用过后,通常就会变成灰色,代表本回合已不能行动了;《仙剑》中回忆彩蝶的部分是用整屏的灰色来表现的?(记的不太清楚,太久了^_^);还有很多很多例子……
  将RGB值转换为灰度的过程应该是在程序中实现的(至少我是这么认为的)。其实这是非常简单的,基本原理就是将一个点的RGB值分开来求和,然后除以3,把得到的值再分别付给RGB,用公式表示如下:

R = G = B = 0.3R + 0.6G + 0.1B; //第二版改正后的公式
//第一版中的错误公式是 R = G = B = ( R + G + B ) / 3;

  在实际编程应用中又可分为8位、16位和24位三种情况,下面进行一一介绍:
  一、首先说最简单的24位点的转换,24位点的RGB均匀分布,所以分离和合成都较为简单,代码如下:


//=======24位转换============
int gMask=0x00ff00; //绿色掩码
int bMask=0x0000ff; //兰色掩码

int RGB24toGray(int sour)
{
    int r,g,b,t; //临时变量

    r=(sour>>16);
    g=(sour & gMask) >>8;
    b=sour & bMask;
    t=(r*3+g*6+b)/10; //第二版改正的地方

    return (t<<16)|(t<<8)|t;
}

  二、16位点的转换要麻烦一些,因其涉及到555和565两种色码格式,所以在转换前需要我们进行一些初始工作:

//=======16位转换============
BYTE RMove, GMove; //R和G移动到最低位需要的步数

//初始化数据,本函数在游戏初始时执行,仅执行一次
void Init()
{
    if( Is555 ) //555模式 0rrrrrgggggbbbbb
    {
        RMove=10;
        GMove=5;
    }
    else //565模式 rrrrrggggggbbbbb
    {
        RMove=11;
        GMove=6;
        /*注意:为什么这里GMove=6,因为565模式下G值有6位,如果用一个6位值和两个5位值相加除以3,得到的结果可能使5位溢出,所以我们要多移动一位即除以2*/
    }
}

//16位点转换
WORD RGB16toGray(WORD sour)
{
    WORD t;
    WORD r, g, b;
    r= sour >> RMove;
    g= (GMask & sour) >> GMove;
    b= BMask & sour;
    t = (r*3+b*6+g)/10; //第二版改正的地方
    return (t<<RMove)|(t<<GMove)|t;
}

  三、8位点的转换和上面两种有比较大的差异,因为它的颜色是由调色板决定的,我们只有通过改变调色板来进行转换,先用lpDDPal->GetEntries()获得调色板,然后分别转换需要的调色板值,完成后用lpDDPal->SetEntries()更新即可,程序如下:

//===========8位转换(注:本函数只适用于全屏转换)===========
void RGB8_to_Gray()
{
    int t; //临时变量
    LPPALETTEENTRY Pal = (LPPALETTEENTRY) LocalAlloc( LPTR, sizeof( PALETTEENTRY ) * 256 );

    //获取调色板
    lpDDPal->GetEntries(0,0,256,Pal);

    //转换
    for(int i=0; i<256; i++)
    {
        t=( Pal[i].peRed * 3 + Pal[i].peGreen *6 + Pal[i].peBlue ) / 10; //第二版改正的地方
        Pal[i].peRed=Pal[i].peGreen=Pal[i].peBlue=t;
    }

    //更新调色板
    lpDDPal->SetEntries(0,0,256,Pe);
}

  上面代码中16位转换已经过测试,而其余两种尚未测试,如果各位发现有问题请及时指正。另:我曾试图用汇编对16转换进行优化,但由于本人的汇编功底实在过于拙劣,经汇编改写后的代码效率不但没有提高,反而有小幅下降,所以如果有人对其16位转换进行优化后,请务必发给在下一份,不胜感激!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 将图像转换为黑白二图像的方法有很多,以下是其中两种常用的方法: 1. 灰度化后二化:将彩色图像转换为灰度图像,然后使用阈将灰度图像转换为二图像。可以使用以下Python代码实现: ```python import cv2 # 读入彩色图像 img = cv2.imread('image.jpg') # 转换为灰度图像 gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 二化 _, binary_img = cv2.threshold(gray_img, 127, 255, cv2.THRESH_BINARY) # 显示结果 cv2.imshow('binary image', binary_img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 2. 自适应阈化:根据图像局部的灰度值动态调整阈,可以得到更好的二化效果。可以使用以下Python代码实现: ```python import cv2 # 读入彩色图像 img = cv2.imread('image.jpg') # 转换为灰度图像 gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 自适应阈化 binary_img = cv2.adaptiveThreshold(gray_img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2) # 显示结果 cv2.imshow('binary image', binary_img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 以上两种方法都可以将彩色图像转换为黑白二图像,选择哪种方法取决于具体的应用场景和需求。 ### 回答2: 将图像转换为黑白二图像的方法有多种,以下是其中几种常见的方法: 1. 灰度化方法:首先将彩色图像转换为灰度图像,然后根据像素灰度值的阈将图像二化。可以使用公式将彩色图像的红、绿、蓝三个通道的像素值加权平均得到灰度值。然后,根据预先设定的阈,将灰度值大于阈的像素设为白色,灰度值小于等于阈的像素设为黑色。 2. 全局阈法:通过计算整个图像的灰度直方图,确定一个全局阈。然后将图像的每个像素与这个阈进行比较,大于阈的像素设为白色,小于等于阈的像素设为黑色。 3. 自适应阈法:不同区域的图像灰度分布可能不同,使用全局阈法可能导致部分区域的细节信息丢失。自适应阈法根据每个像素周围的邻域信息来确定阈。常见的方法有局部平均法和Otsu法。局部平均法将每个像素周围邻域的灰度值进行平均来计算阈,Otsu法则通过最小化类间灰度方差来确定阈。 4. 基于色彩分量的方法:对于彩色图像,可以根据图像的不同色彩分量的灰度值来进行二化。比如,取彩色图像红、绿、蓝三个通道中的某一个通道的灰度图像进行二化。 以上是常见的将图像转换为黑白二图像的方法,选择适合自己需求的方法进行处理即可。 ### 回答3: 将彩色图像转换为黑白二图像的过程通常称为灰度化或二化。下面是一种常见的图像处理方法: 第一步是将彩色图像转换为灰度图像。可以使用灰度转换算法,根据彩色图像的RGB通道计算灰度值。比较常见的计算公式是将红色、绿色和蓝色通道加权平均: 灰度值 = (0.299 * 红色 + 0.587 * 绿色 + 0.114 * 蓝色) 第二步是将灰度图像转换为黑白二图像。可以选择一个阈,将灰度图像中的像素值与阈进行比较。通常将像素值大于阈的像素设置为白色(255),小于等于阈的像素设置为黑色(0)。 选择合适的阈对于将图像转换为黑白二图像非常重要。可以根据图像的特征和需要进行手动选择,也可以使用一些自动阈选择算法,例如大津算法或自适应阈算法。 通过这个过程,可以将彩色图像转换为黑白二图像。这种转换通常能够突出图像的轮廓和细节,同时减少图像的数据量,便于进行后续的图像处理和分析。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值