设为首页 加入收藏

TOP

BMP图像的灰度化---C++实现 (一)
2014-11-23 20:00:40 来源: 作者: 【 】 浏览:13
Tags:BMP 图像 ---C 实现

灰度图的结构主要包括文件头,BMP信息头,调色板,BMP数据内容四部分。灰度图的调色板共有256项RGBQUAD结构,存放0到255的灰度值,每一项rgbRed、rgbGreen、rgbBlue分量值相等。


参考文章:BMP图像的结构及读写和灰度化
24位真彩BMP图像的灰度化
把24位真彩BMP图像转变成256阶灰度图的具体步骤如下:
(1) 修改信息头
信息头共有11部分,灰度化时需要修改两部分
bi2.biBitCount=8;
bi2.biSizeImage=( (bi.biWidth+3)/4 ) * 4*bi.biHeight;


(2)修改文件头
文件头共有5部分,灰度化时需要修改两部分
bf2.bfOffBits = sizeof(bf2)+sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD);
bf2.bfSize = bf2.bfOffBits + bi2.biSizeImage;


(3)创建调色板
RGBQUAD *ipRGB2 = (RGBQUAD *)malloc(256*sizeof(RGBQUAD));
for ( i = 0; i < 256; i++ )
ipRGB2[i].rgbRed = ipRGB2[i].rgbGreen = ipRGB2[i].rgbBlue = i;


(4)修改位图数据部分
这部分主要是由原真彩图的rgbRed、rgbGreen、rgbBlue分量值得到灰度图像的灰度值Y,

可以用下面公式得到:
Y=0.299*rgbRed+0.587* rgbGreen+0.114*rgbBlue;
具体修改代码如下:
int nBytesPerLine2 = ( (bi.biWidth+3)/4 ) * 4;
nLineStart2 = nBytesPerLine2 * i;
for ( int j = 0; j ImgData2[nLineStart2+j]= int( (float)Imgdata[i][3 * j] * 0.114 + \
(float)Imgdata[i][3 * j + 1] * 0.587 + \
(float)Imgdata[i][3 * j + 2] * 0.299 );//用一个一维数组顺序存储灰度值


(5)按顺序写入BMP图像的各个部分
fwrite(&bf2,sizeof(BITMAPFILEHEADER),1,fp);
fwrite(&bi2,sizeof(BITMAPINFOHEADER),1,fp);
fwrite(ipRGB2,sizeof(RGBQUAD),256,fp);
fwrite(ImgData2,nImageSize2,1,fp);

include  
#include   
 
using namespace std; 
 
 
void main() 
{ 
     
    FILE* stream=fopen("D:\\3.bmp","rb"); 
    if(stream==NULL) 
    { 
        cout<<"文件不存在"<biWidth*24)+31)/32)*4; 
    int destImageLineByteCount=(((bitmapInfoHeader->biWidth)*8+31)/32)*4; 
 
    //************位图信息头**********************  
     
    BYTE** oldImageData=new BYTE*[bitmapInfoHeader->biHeight]; 
    for(int i=0;ibiHeight;i++) 
    { 
        oldImageData[i]=new BYTE[srcImageLineByteCount+1]; 
        memset(oldImageData[i],0,srcImageLineByteCount+1); 
    } 
 
    //***********位图数据***********************  
    fseek(stream,sizeFileHeader+sizeInfoHeader,0); 
    //读取图像数据  
    for(int i=0;ibiHeight;i++) 
    { 
        for (int j=0;jbiBitCount=8; 
    bitmapInfoHeader->biSizeImage=(bitmapInfoHeader->biHeight)*destImageLineByteCount; 
 
    //修改文件头  
    bitmapFileHeader->bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256; 
    bitmapFileHeader->bfSize=bitmapFileHeader->bfOffBits+bitmapInfoHeader->biSizeImage; 
     
 
    //写数据  
     
    BYTE** newImageData=new BYTE*[bitmapInfoHeader->biHeight]; 
 
    for (int i=0;ibiHeight;i++) 
    { 
        newImageData[i]=new BYTE[destImageLineByteCount]; 
    } 
 
    for(int i=0;ibiHeight;i++) 
    { 
        for(int j=0;j
#include 

using namespace std;


void main()
{
 
 FILE* stream=fopen("D:\\3.bmp","rb");
 if(stream==NULL)
 {
  cout<<"文件不存在"<biWidth*24)+31)/32)*4;
 int destImageLineByteCount=(((bitmapInfoHeader->biWidth)*8+31)/32)*4;

 //************位图信息头**********************
 
 BYTE** oldImageData=new BYTE*[bitmapInfoHeader->biHeight];
 for(int i=0;ibiHeight;i++)
 {
  oldImageData[i]=new BYTE[srcImageLineByteCount+1];
  memset(oldImageData[i],0,srcImageLineByteCount+1);
 }

 //***********位图数据***********************
 fseek(stream,sizeFileHeader+sizeInfoHeader,0);
 //读取图像数据
 for(int i=0;ibiHeight;i++)
 {
  for (int j=0;jbiBitCount=8;
 bitmapInfoHeader->biSizeImage=(bitmapInfoHeader->biHeight)*destImageLineByteCount;

 //修改文件头
 bitmapFileHeader->bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+si
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇BMP图像旋转----C++实现 下一篇hdu2594 Simpsons’ Hidden Talen..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·微服务 Spring Boot (2025-12-26 18:20:10)
·如何调整 Redis 内存 (2025-12-26 18:20:07)
·MySQL 数据类型:从 (2025-12-26 18:20:03)
·Linux Shell脚本教程 (2025-12-26 17:51:10)
·Qt教程,Qt5编程入门 (2025-12-26 17:51:07)