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

我们知道真彩图不带调色板,每个象素用 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分量计算。

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

(0)

相关推荐

  • C语言实现BMP图像细化处理

    细化(thinning)算法有很多,我们在这里介绍的是一种简单而且效果很好的算法,用它就能够实现从文本抽取骨架的功能.我们的对象是白纸黑字的文本,但在程序中为了处理的方便,还是采用 256 级灰度图,不过只用到了调色板中 0 和 255 两项. 所谓细化,就是从原来的图中去掉一些点,但仍要保持原来的形状.实际上,是保持原图的骨架.所谓骨架,可以理解为图象的中轴,例如一个长方形的骨架是它的长方向上的中轴线:正方形的骨架是它的中心点:圆的骨架是它的圆心,直线的骨架是它自身,孤立点的骨架也是自身.那么

  • C语言实现BMP图像处理(哈夫曼编码)

    哈夫曼(Huffman)编码是一种常用的压缩编码方法,是 Huffman 于 1952 年为压缩文本文件建立的.它的基本原理是频繁使用的数据用较短的代码代替,较少使用的数据用较长的代码代替,每个数据的代码各不相同.这些代码都是二进制码,且码的长度是可变的. 下面给出具体的 Huffman 编码算法: (1) 首先统计出每个符号出现的频率,上例 S0 到 S7 的出现频率分别为 4/14,3/14,2/14,1/14,1/14,1/14,1/14,1/14. (2) 从左到右把上述频率按从小到大的

  • C语言实现BMP图像处理(直方图均衡化)

    本文实例为大家分享了C语言实现BMP图像直方图均衡化处理的具体代码,供大家参考,具体内容如下 计算步骤: 1)统计各灰度值的概率: 2)计算了累积概率直方图(CDF): 3)取整扩展:Tk = int[ (L-1)*Tk]; #include <Windows.h> #include <stdlib.h> #include <stdio.h> #include <math.h> int main(int* argc, char** argv) { FILE*

  • C语言实现BMP图像闭运算处理

    闭运算可以把比结构元素小的特定图像细节出去,同时保证不产生全局的几何失真.填充比结构元素小的缺口或孔,搭接短的间断而起到连接作用. 运算:也就是先膨胀后腐蚀. #include <stdio.h> #include <stdlib.h> #include <Windows.h> int main(int* argc, char** argv) { FILE* fp = fopen("./threshold.bmp", "rb");

  • C语言实现BMP图像边缘检测处理

    本文实例为大家分享了C语言实现BMP图像边缘检测处理的具体代码,供大家参考,具体内容如下 以Sobel算子为例,其余模板算子卷积代码部分同Sobel算子.如:高斯算子.拉普拉斯算子等 #include <stdio.h> #include <stdlib.h> #include <Windows.h> #include <math.h> int main(int* argc, char** argv) { FILE* fp = fopen("./0

  • C语言实现将彩色bmp图像转化为灰图、灰度图像反色

    本文实例为大家分享了C语言实现将彩色bmp图像转化为灰图.灰度图像反色的具体代码,供大家参考,具体内容如下 彩色图像转灰度图像 彩色(24位)bmp图像结构: typedef struct{ bitmapFileHeader bfHeader; bitmapInfoHeader biHeader; unsigned char *imgData; }bmp; 灰度(8位)bmp图像结构: typedef struct{ bitmapFileHeader bfHeader; bitmapInfoHe

  • C语言实现24位彩色图像二值化

    本文实例为大家分享了C语言实现24位彩色图像二值化的具体代码,供大家参考,具体内容如下 // huiduhua.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<stdio.h> #include<windows.h> int _tmain(int argc, _TCHAR* argv[]) { BITMAPFILEHEADER bfhead; BITMAPINFOHEADER bihead; RGBQUA

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

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

  • C语言实现BMP格式图片转化为灰度

    本文实例为大家分享了C语言将BMP格式图片转化为灰度的具体代码,供大家参考,具体内容如下 代码如下: #include<stdio.h> #include<malloc.h> #include<stdlib.h> #pragma pack(1) typedef struct tagBITMAPFILEHEADER { unsigned char bfType[2];//文件格式 unsigned long bfSize;//文件大小 unsigned short bfR

  • Android-如何将RGB彩色图转换为灰度图方法介绍

    实例:RGB2Grey 项目运行效果图:          源代码: [java] public class MainActivity extends Activity { /* (non-Javadoc)     * @see android.app.Activity#onCreate(android.os.Bundle)     */     @Override     public void onCreate(Bundle savedInstanceState) {         sup

  • Opencv中cv2.cvtColor彩色图转灰度图的其他6种方法

    目录 1.公式集成: 2.代码实现: 3.实验结果: 4.参考文章: 1.公式集成: 2.代码实现: import os import cv2 import queue import threading import numpy as np #用户存取函数的返回值 q=queue.Queue() def rgb2gray(image,method): h,w,c=image.shape gray=np.zeros((h,w),dtype=np.uint8) y=0 for row in rang

  • python opencv将图片转为灰度图的方法示例

    使用opencv将图片转为灰度图主要有两种方法,第一种是将彩色图转为灰度图,第二种是在使用OpenCV读取图片的时候直接读取为灰度图. 将彩色图转为灰度图 import cv2 import numpy as np if __name__ == "__main__": img_path = "timg.jpg" img = cv2.imread(img_path) #获取图片的宽和高 width,height = img.shape[:2][::-1] #将图片缩小

  • C#/VB.NET 实现彩色PDF转为灰度PDF

    目录 配置程序环境 转彩色PDF为灰度 转换结果 补充 本文以C#代码为例介绍如何实现将彩色PDF文件转为灰度(黑白)的PDF文件,即 将PDF文档里面的彩色图片或者文字等通过调用PdfGrayConverter.ToGrayPdf()方法转为文档页面为灰色调.无彩色效果的文档.下面的程序运行环境及代码示例. 配置程序环境 Visual Studio 2017 .Net Framework 4.6.1 Spire.PDF for .NET 关于如何引入dll文件: 1.通过NuGet安装dll(

  • 基于OpenCV自定义色条实现灰度图上色功能代码

    场景需求        Qt在进行2D图像显示时,有很方便的色条接口,可以让灰度图基于其设计的色条进行上色,比如设置1为红色,0.55为黄色,0.45为绿色,0为蓝色,那么灰度图就会在归一化后按照从蓝到红(从小到大)进行渐变色上色.但是有时候这个接口需要搭配的代码太多,给开发带来一定麻烦,因此我基于其原理写了一个可以替代该功能的函数GrayToColor_ColorBar.        函数原理:首先需要将灰度值图转化为0-255的8通道(uchar)灰度图,运用归一化函数可以实现:之后考虑到

  • C++ OpenCV实现灰度图蒙版GrayMask的示例代码

    目录 需求说明 具体流程 功能函数 C++测试代码 测试效果 需求说明 在对图像进行处理时,经常会有这类需求:想对感兴趣区域进行掩膜处理,只操作掩膜内数据,此时需要搭配掩膜绘制功能,并在绘制过程中希望能区分掩膜区和非掩膜区:除了掩膜本身的线条以外,还希望掩膜内图像是原色,掩膜外图像的颜色进行一定调整:通常可以采用图像透明化或者色彩单通道加深的方式实现. 比如对三通道的图像,可以将掩膜外数据的红通道数值提高,此时该部分图像就会偏红色,如下图1所示. 图1 颜色加深的蒙版效果 但是针对灰度图,因为图

随机推荐