文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

C语言实现BMP图像处理(彩色图转灰度图)

2024-04-02 19:55

关注

我们知道真彩图不带调色板,每个象素用 3 个字节,表示 R、G、B 三个分量。所以处理很简单,根据 R、G、B 的值求出 Y 值后,将 R、G、B 值都赋值成 Y,写入新图即可。 在YUV 的颜色表示方法中,Y 分量的物理含义就是亮度,它含了灰度图(grayscale)的所有信息,只用 Y 分量就完全能够表示出一幅灰度图来。YUV 和RGB 之间有着如下的对应关系:

再来看看带调色板的彩色图,我们知道位图中的数据只是对应调色板中的一个索引值,我们只需要将调色板中的彩色变成灰度,形成新调色板,而位图数据不用动,就可以了。

以上解释来自于:《数字图像处理编程入门》,代码参考:C语言实现24位彩色图像二值化


#include<stdio.h>
#include<windows.h>
 
int main(int argc, char* argv[])
{
 int bmpHeight;
 int bmpWidth;
 unsigned char *pBmpBuf;
 RGBQUAD *pColorTable;
 int biBitCount;
 
 //读取bmp文件
 FILE *fp = fopen("./02.bmp", "rb");
 if (fp == 0)
  return 0;
 fseek(fp, sizeof(BITMAPFILEHEADER), 0);
 
 BITMAPINFOHEADER head;
 fread(&head, 40, 1, fp);
 bmpHeight = head.biHeight;
 bmpWidth = head.biWidth;
 biBitCount = head.biBitCount;
 
 fseek(fp, sizeof(RGBQUAD), 1);
 
 int LineByte = (bmpWidth*biBitCount / 8 + 3) / 4 * 4;//保证每一行字节数都为4的整数倍
 pBmpBuf = new unsigned char[LineByte*bmpHeight];
 fread(pBmpBuf, LineByte*bmpHeight, 1, fp);
 fclose(fp);
 
 //将24位真彩图灰度化并保存
 FILE *fp1 = fopen("gray.bmp", "wb");
 if (fp1 == 0)
  return 0;
 int LineByte1 = (bmpWidth * 8 / 8 + 3) / 4 * 4;
 
 //修改文件头,其中有两项需要修改,分别为bfSize和bfOffBits
 BITMAPFILEHEADER bfhead;
 bfhead.bfType = 0x4D42;
 bfhead.bfSize = 14 + 40 + 256 * sizeof(RGBQUAD)+LineByte1*bmpHeight;//修改文件大小
 bfhead.bfReserved1 = 0;
 bfhead.bfReserved2 = 0;
 bfhead.bfOffBits = 14 + 40 + 256 * sizeof(RGBQUAD);//修改偏移字节数
 fwrite(&bfhead, 14, 1, fp1);    //将修改后的文件头存入fp1;
 
 //修改信息头,其中有两项需要修改,1个位biBitCount:真彩图为24 ,应改成8;另一个是biSizeImage:由于每像素所占位数的变化,所以位图数据的大小发生变化
 BITMAPINFOHEADER head1;
 head1.biBitCount = 8;    //将每像素的位数改为8
 head1.biClrImportant = 0;
 head1.biCompression = 0;
 head1.biClrUsed = 0;
 head1.biHeight = bmpHeight;
 head1.biWidth = bmpWidth;
 head1.biPlanes = 1;
 head1.biSize = 40;
 head1.biSizeImage = LineByte1*bmpHeight;//修改位图数据的大小
 head1.biXPelsPerMeter = 0;
 head1.biYPelsPerMeter = 0;
 fwrite(&head1, 40, 1, fp1);  //将修改后的信息头存入fp1;
 
 pColorTable = new RGBQUAD[256];
 for (int i = 0; i < 256; i++){
  pColorTable[i].rgbRed = i;
  pColorTable[i].rgbGreen = i;
  pColorTable[i].rgbBlue = i; //是颜色表里的B、G、R分量都相等,且等于索引值
 }
 fwrite(pColorTable, sizeof(RGBQUAD), 256, fp1); //将颜色表写入fp1;
 
 //写位图数据
 unsigned char *pBmpBuf1;
 pBmpBuf1 = new unsigned char[LineByte1*bmpHeight];
 for (int i = 0; i < bmpHeight; i++){
  for (int j = 0; j<bmpWidth; j++){
   unsigned char *pb1, *pb2;
   pb1 = pBmpBuf + i*LineByte + j * 3;
   int y = *(pb1)*0.299 + *(pb1 + 1)*0.587 + *(pb1 + 2)*0.114;   //将每一个像素都按公式y=B*0.299+G*0.587+R*0.114进行转化
   pb2 = pBmpBuf1 + i*LineByte1 + j;
   *pb2 = y;
  }
 }
 fwrite(pBmpBuf1, LineByte1*bmpHeight, 1, fp1);
 
 fclose(fp1);
 
 system("pause");
 return 0;
}

实验结果分析:

实验结果分析:真彩色图不带调色板,而灰度图的调色板为256级。所以在修改调色板时需要将RGB三个分量修改为256级,根据YUV颜色空间中Y分量计算。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯