将一幅图像转换为灰度图
来源:互联网 发布:传智播客java视频 编辑:程序博客网 时间:2024/06/08 06:06
灰度图是指用灰度表示的图像,灰度是在白色和黑色之间分的若干个等级,其中最常用的是256级,也就是256级灰度图。灰度图在医学、航天等领域有着广泛的应用。
那么如何将一幅彩色图像转换为灰度图呢?根据人眼对红绿蓝三色的敏感程度,可以使用以下比例式进行转换:
Gray = R*0.3+G*0.59+B*0.11
这也是最常用的一种转换,另外还有一种常用的转换叫平均值法,即取去红绿蓝三色的平均值为灰度:
Gray=(R+G+B)/3;
下面来写一段程序实现第一种转换算法,显然对于对于一幅256级灰度图,每个像素采用一个字节表示足矣,即为8位位图。对于8位位图的保存,真正的RGB数据是保存在调色板里的,而实际的数据仅仅是保存的调色板内的像素值的索引。
1 #include "stdafx.h"
2 #include <stdio.h>
3 #include <string>
4 #include <math.h>
5 #include <windows.h>
6 usingnamespace std;
7
8
9 //将位图转换为256色灰度图
10 void ToGray(conststring& srcFile,conststring& desFile)
11 {
12 BITMAPFILEHEADER bmfHeader;
13 BITMAPINFOHEADER bmiHeader;
14
15 FILE *pFile;
16 if ((pFile= fopen(srcFile.c_str(),"rb"))== NULL)
17 {
18 printf("open bmp file error.");
19 exit(-1);
20 }
21 //读取文件和Bitmap头信息
22 fseek(pFile,0,SEEK_SET);
23 fread(&bmfHeader,sizeof(BITMAPFILEHEADER),1,pFile);
24 fread(&bmiHeader,sizeof(BITMAPINFOHEADER),1,pFile);
25 //先不支持16位位图
26 int bitCount= bmiHeader.biBitCount;
27 if (bitCount== 16)
28 {
29 exit(-1);
30 }
31 double byteCount= (double)bitCount/ 8;
32 int nClr= 0;
33 if (bitCount< 16)
34 {
35 nClr = bmiHeader.biClrUsed? bmiHeader.biClrUsed :1 << bitCount;
36 if (nClr> 256)
37 nClr = 0;
38 }
39 //读取调色板
40 RGBQUAD*quad = NULL;
41 if (nClr> 0)
42 {
43 quad = new RGBQUAD[nClr];
44 fread(quad,sizeof(RGBQUAD)* nClr,1,pFile);
45 }
46
47 int srcW= bmiHeader.biWidth;
48 int srcH= bmiHeader.biHeight;
49 //原图像每一行去除偏移量的字节数
50 int lineSize= bitCount * srcW >>3;
51 //偏移量,windows系统要求每个扫描行按四字节对齐
52 int alignBytes= (((bmiHeader.biWidth* bitCount + 31)& ~31)>> 3)
53 - ((bmiHeader.biWidth* bitCount)>> 3);
54 //原图像缓存
55 int srcBufSize= lineSize * srcH;
56 BYTE* srcBuf= new BYTE[srcBufSize];
57 int i,j;
58 //读取文件中数据
59 for (i= 0; i< srcH; i++)
60 {
61 fread(&srcBuf[lineSize* i],lineSize,1,pFile);
62 fseek(pFile,alignBytes,SEEK_CUR);
63 }
64 //256色位图调色板
65 RGBQUAD*quadDes = NULL;
66 quadDes = new RGBQUAD[256];
67 for (i= 0; i< 256; i++)
68 {
69 //灰度图的RGB值相等
70 quadDes[i].rgbBlue= quadDes[i].rgbGreen= quadDes[i].rgbRed= i;
71 }
72 //灰度图每个像素采用8位表示
73 int desBufSize= (((srcW * 8+ 31)& ~31)>> 3)* srcH;
74 BYTE *desBuf =new BYTE[desBufSize];
75 //每个扫描行占用字节数
76 int desLineSize= ((srcW * 8+ 31)>> 5)* 4;
77
78 for (i= 0; i< srcH; i++)
79 {
80 for (j= 0; j< srcW; j++)
81 {
82 //从调色板中读取RGB值
83 if (nClr> 0)
84 {
85 unsignedint pos = srcBuf[i * lineSize + int(j* byteCount)];
86 desBuf[i* desLineSize+ j] = 0.3* quad[pos].rgbRed
87 +0.59 * quad[pos].rgbGreen
88 +0.11 * quad[pos].rgbBlue;
89 }
90 else
91 desBuf[i* desLineSize+ j] = 0.3* srcBuf[i * lineSize + int(j* byteCount)]
92 +0.59 * srcBuf[i * lineSize + int(j* byteCount)+ 1]
93 +0.11 * srcBuf[i * lineSize + int(j* byteCount)+ 2];
94 }
95 }
96
97 //创建目标文件
98 HFILE hfile= _lcreat(desFile.c_str(),0);
99 //文件头信息
100 BITMAPFILEHEADER nbmfHeader;
101 nbmfHeader.bfType= 0x4D42;
102 nbmfHeader.bfSize= sizeof(BITMAPFILEHEADER)+ sizeof(BITMAPINFOHEADER)
103 +256 * sizeof(RGBQUAD)+ srcW * srcH;
104 nbmfHeader.bfReserved1= 0;
105 nbmfHeader.bfReserved2= 0;
106 nbmfHeader.bfOffBits= sizeof(BITMAPFILEHEADER)+ sizeof(BITMAPINFOHEADER)+ 256* sizeof(RGBQUAD);
107 //Bitmap头信息
108 BITMAPINFOHEADER bmi;
109 bmi.biSize=sizeof(BITMAPINFOHEADER);
110 bmi.biWidth=srcW;
111 bmi.biHeight=srcH;
112 bmi.biPlanes=1;
113 bmi.biBitCount=8;
114 bmi.biCompression=BI_RGB;
115 bmi.biSizeImage=0;
116 bmi.biXPelsPerMeter=0;
117 bmi.biYPelsPerMeter=0;
118 bmi.biClrUsed=256;
119 bmi.biClrImportant=0;
120
121 //写入文件头信息
122 _lwrite(hfile,(LPCSTR)&nbmfHeader,sizeof(BITMAPFILEHEADER));
123 //写入Bitmap头信息
124 _lwrite(hfile,(LPCSTR)&bmi,sizeof(BITMAPINFOHEADER));
125 if (quadDes)
126 {
127 _lwrite(hfile,(LPCSTR)quadDes,sizeof(RGBQUAD)* 256);
128 }
129 //写入图像数据
130 _lwrite(hfile,(LPCSTR)desBuf,desBufSize);
131 _lclose(hfile);
132 if (quad)
133 {
134 delete[] quad;
135 quad = NULL;
136 }
137 if (quadDes)
138 {
139 delete[] quadDes;
140 quadDes= NULL;
141 }
142 }
143
144 int main(int argc,char* argv[])
145 {
146 string srcFile("e://t.bmp");
147 string desFile("e://gray.bmp");
148 ToGray(srcFile,desFile);
149 system("pause");
150 return0;
151 }
转换前的图像:
转换后的图像:
- 将一幅图像转换为灰度图
- 深度图像转换为灰度图
- 灰度图像转换为彩色
- 彩色图像转换为灰度图像
- openCV彩色图像转换为灰度图像
- 彩色图像批量转换为灰度图像
- 毕业课题---RGB图像转换为灰度图
- Qt 中彩色图像转换为灰度图
- Qt 中彩色图像转换为灰度图
- Qt 中彩色图像转换为灰度图
- 转换为不同灰度级图像
- 使用 Java 进行图像处理 - 将彩色图像转换为灰度图
- 将各种格式的图像转换为灰度图像
- /LGC图形渲染/彩色图像转换为灰度图像
- C#将RGB图像转换为8位灰度图像
- C#将RGB图像转换为8位灰度图像
- OpenCV 原始RGB图像转换为灰度图像
- vc将彩色图像转换为灰度图像
- STL auto_ptr
- Session的基本操作
- 本机与虚拟机可ping通但无法SSH连接
- linux 文件权限 与 查找
- C++ 中的static
- 将一幅图像转换为灰度图
- uva10361--String
- U-boot移植
- cdoframework系列介绍1:CDO对象说明
- Hibernate关联关系
- Ubuntu下构建内核源码树
- SQL SERVER
- 目标2——摸清目录结构功能
- hadoop学习笔记(2)-hadoop安装目录权限的问题导致datanode启动失败