bmp文件信息头调色板 在图像编程上的应用

我们知道,bmp(bitmap picture)图像格式是目前在数字图像处理领域通用的图片格式。

它是windows系统交换图形、图像数据的一种标准格式。

下图1是文件信息头的格式。
图1 文件信息头
根据上面的图表,我们实现以下两个问题:
1. 将24位真彩色图像转为8位灰度图
2. 实现图像的裁剪


实例1: 将24位真彩色图像转为8位灰度图(BMP格式)

  1. 实例分析
    1) 读取24位真彩色图像
    读取24位真彩色图像和8位灰度图像最大的区别有两个:a. 24位真彩色图像的图像数据为24位,分别是BGR(各8位)。b. 没有调色板(因为每BGR三个分量就表示一种颜色)
    特别注意:的是RGB图像三个分量的排列方式是BGR
    2) 将彩色信息转化为灰度信息
    一般有以下三种转换公式:
    a. RGB各占三分之一
    Gray = R*0.333 + G*0.333 + B*0.333
    b. 基于人类视觉对RGB三种颜色的敏感程度不同,而有以下公式:
    Gray = R*0.299 + G*0.587 + B*0.114
    c. 这种公式我应用在车牌识别中,因为我国车牌大多蓝底白字,所以我将蓝色分量的权值改为0,那么蓝色像素体现在灰度图像中就变黑了,而白色依然是白色,有着较好的区分效果。
    Gray = R*0.5 + G*0.5
    3) 保存灰度图像
    a. 需要注意的是,我们读取彩色图像的文件头,是不能直接用在灰度图像中的。需要修改文件头的第2-5字节、10-13字节和28-29字节的内容。第2-5字节的内容为bmp文件的大小,其大小包括文件信息头54字节,调色板1024字节(8位灰度图,位数不同都不一样,24位真彩色没有调色板),位图数据。
    举个例子:一幅640*480的8位灰度bmp格式文件的大小为
    Size = 54 + 1024 + 640*480 = 308278 byte(转为16进制就是00 04 B4 36H)
    一幅640*480的24位真彩色bmp格式文件的大小为
    Size = 54 + 640*480*3 = 921654 byte(转为16进制就是00 0E 10 36H)
    第10-13字节和28-29字节的修改在图1已经详尽说明,在此不再赘述。

  2. 彩色图像转灰度图像函数代码(图像读写函数未贴出)

void ColtoGray(int Row,int Col,unsigned char *imageIn,unsigned char *imageOut,float a,float b,float c)
{
    int x,y;
    int n;
    float sum=0;
    for(y=0;y<Row;y++)
        for(x=0;x<Col;x++)
        {
            for(n=0;n<3;n++)
            {
                switch(n)
                {
                    case 0:
                        sum=sum+imageIn[(y*Col+x)*3]*a;   break;
                    case 1:
                        sum=sum+imageIn[(y*Col+x)*3+1]*b; break;
                    case 2:
                        sum=sum+imageIn[(y*Col+x)*3+2]*c; break;
                }
            }
            imageOut[y*Col+x]=sum;
            sum=0;
        }
}

实例2: 实现图像的裁剪

  1. 实例分析
    1)图像裁剪就是在原图上抠出一个矩形区域,并将它另存为bmp图像输出。
    2)重点和难点是修改文件信息头中的宽(第18-21字节)和高(22-25字节)的信息以及实例1中文件大小的修改。
  2. 实例代码
void imageCut(int Row,int Col,unsigned char *imageIn,unsigned char *Fheadg,int startCutX,int startCutY,int cutx,int cuty,unsigned char *imageOut,unsigned char isCol)
{
    int i,j;
    int x,y;
    unsigned char n;
    int imageSize;
    if(Row<startCutY+cuty||Col<startCutX+cutx)
    {
        printf("超出裁剪范围");
        return; 
    }
    if(isCol == 1) 
    {
        n = 3;
        imageSize = n*cutx*cuty+54;
    }
    else
    {
        n = 1;
        imageSize = n*cutx*cuty+1078;
    }
    //头文件宽高和文件大小修改
    Fheadg[2]  = imageSize%256;
    Fheadg[3]  = imageSize/256%256;
    Fheadg[4]  = imageSize/256/256%256;
    Fheadg[5]  = imageSize/256/256/256%256;
    Fheadg[18] = cutx%256;
    Fheadg[19] = cutx/256;
    Fheadg[22] = cuty%256;
    Fheadg[23] = cuty/256;
    for(y=0,i=startCutY;i<startCutY+cuty;y++,i++)
        for(x=0,j=startCutX;j<(startCutX+cutx)*n;x++,j++)
            imageOut[y*cutx*n+x] = imageIn[i*Col*n+j];
}

*本文章是作者辛苦所做,如有不足望大家指出。另转载请注明出处,谢谢各位了。*

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值