第5章 直方图修正和彩色变换
- 格式:doc
- 大小:449.50 KB
- 文档页数:45
颜色校正算法一、引言颜色校正算法是计算机图形学中的一个重要技术,旨在修正由于光照、摄像设备、显示器等因素引起的颜色偏差。
在计算机图像处理和计算机视觉领域,颜色校正算法被广泛应用于图像增强、图像重建、色彩匹配等方面。
本文将介绍几种常见的颜色校正算法及其原理。
二、直方图均衡化直方图均衡化是一种简单而有效的颜色校正算法。
它通过对图像的像素值分布进行调整,使图像的亮度分布更加均匀。
具体步骤如下:1. 计算图像的灰度直方图,统计每个像素值的频率。
2. 计算累积直方图,即将每个像素值的频率累加起来。
3. 根据累积直方图,计算每个像素值的映射关系。
4. 将原始图像的每个像素值根据映射关系进行替换,得到校正后的图像。
三、颜色空间转换颜色校正算法中常用的一种方法是进行颜色空间的转换。
最常见的颜色空间是RGB和HSV。
RGB颜色空间由红、绿、蓝三个分量组成,而HSV颜色空间由色相、饱和度和亮度三个分量组成。
通过将图像从RGB颜色空间转换到HSV颜色空间,可以更好地调整图像的色彩和亮度。
具体步骤如下:1. 将RGB图像转换为HSV图像。
2. 根据需要调整HSV图像的色相、饱和度和亮度分量。
3. 将调整后的HSV图像转换回RGB图像。
四、灰度世界假设灰度世界假设是一种基于图像平均亮度的颜色校正方法。
该方法假设图像中的物体颜色在整个图像中具有相同的平均亮度。
具体步骤如下:1. 计算图像的平均亮度,可以根据图像的RGB分量或HSV分量进行计算。
2. 根据计算得到的平均亮度,调整图像的RGB分量或HSV分量,使其平均亮度与整个图像的平均亮度一致。
五、颜色映射颜色映射是一种基于颜色直方图的颜色校正算法。
它将原始图像和目标图像的颜色直方图进行比较,通过调整原始图像的颜色分布来实现校正。
具体步骤如下:1. 计算原始图像和目标图像的颜色直方图,并进行归一化处理。
2. 计算原始图像和目标图像的累积直方图。
3. 根据累积直方图,计算每个像素值的映射关系。
遥感影像直方图修正及彩色变换
韩玲;吴云海
【期刊名称】《地球科学与环境学报》
【年(卷),期】2002(024)001
【摘要】遥感技术是当前人类研究地球资源环境的一种主要技术手段.针对遥感影像的特点,对其进行直方图修正及彩色变换的数字图像处理,用VC++6.0程序设计语言,实现几种变换.
【总页数】4页(P59-62)
【作者】韩玲;吴云海
【作者单位】长安大学,地质工程与测绘工程学院,陕西,西安,710054;长安大学,地质工程与测绘工程学院,陕西,西安,710054
【正文语种】中文
【中图分类】P238.8;TP391.41
【相关文献】
1.基于I HS变换和小波变换的遥感影像融合 [J], 戴洪宝;许继影;夏青森;陈力
2.基于彩色空间变换的迭代反射投影遥感影像的超分辨率重建 [J], 郭桐宇
3.选择最佳彩色变换用于遥感影像复合的定量评价方法 [J], 贾永红;李德仁
4.彩色空间变换在DEM与遥感影像复合中的应用研究 [J], 梁伟;杨勤科
5.全彩色遥感影像彩色合成效应的研究 [J], 万晓霞;易尧华
因版权原因,仅展示原文概要,查看原文内容请购买。
重庆交通大学测量与空间信息处理实验报告实验课程:遥感原理及应用实验名称:直方图修正法班级:姓名:学号:实验日期:2012 年11 月17 日实验原理一.直方图均衡化直方图均衡算法是图象增强空域法中的最常用、最重要的算法之一。
目前较常用的增强方法有全局直方图均衡化、局部直方图均衡化两大类。
全局直方图均衡化是将原图像的直方图通过变换函数变为均匀的直方图, 然后按均匀直方图修正原图像, 从而获得一幅灰度分布均匀的新图像。
它以概率理论作基础, 运用灰度点运算来实现直方图的变换, 从而达到图象增强的目的。
它的变换函数取决于图像灰度直方图的累积分布函数。
概括的说, 就是把一已知灰度概率分布的图像, 经过一种变换, 使之演变成一幅具有均匀概率分布的新图像。
当图像的直方图为一均匀分布时,图像的信息熵最大,此时图像包含的信息量最大,图像看起来就显得清晰。
下面先讨论连续变化图像的均衡化问题。
设r 、s 分别表示原图像和增强后图像的灰度。
假设r 被归一化到区间[0,1], 且r =0 表示黑色及 r = 1表示白色。
当r 、s 在[0,1] 之间时,表示像素灰度在黑白之间变化。
灰度变换函数为s=T(r) 0≤r≤1 (1)它满足以下两个条件:(1) T(r)在区间0≤r≤1中为单值且单调递增;(2) 当0≤r≤1时, 0 ≤T(r)≤1;条件(1)中要求T(r)为单值是为了保证反变换存在, 单调条件保证原图各灰度级在变换后仍保持从黑到白( 或从白到黑) 的排列次序;条件(2)保证变换前后灰度值动态范围的一致性。
图1 给出了满足这两个条件的一个变换函数的例子, 由s 到r 的反变换可以表示为:= 0≤s≤1 (2)r-),(1sT即使 T(r)满足条件(1)和(2), 相应的函数)(1sT-也可能不为单值。
一幅图像的灰度级可被视为区间[0,1] 的随机变量。
令)(r p r 和)(s p s 分别代表随机变量 r 和s 的概率密度函数。
一、实验名称:直方图修正二、实验目的1.对影像进行直方图规定化和均衡化2.利用另外一幅影像进行直方图匹配3.利用直方图统计功能对结果进行分析三、实验内容1.对两幅卫星遥感影像进行规定化并统计分析2.对一幅卫星遥感影像进行均衡化并统计分析四、实验所用的仪器设备计算机和ENVI软件在不同时刻同地的卫星遥感影像2幅五、实验原理1.直方图规定化:是使原图像灰度直方图变成规定形状的直方图而对原始图像作修正的增强方法。
作用:对于在不同时间获取的同一地区或者邻接地区的图像,或者是由于太阳高度角或大气的影响引起差异的图像很有用,特别是对图像镶嵌和变化检测。
2.直方图均衡化:又称直方图平坦化,是将一已知灰度概率密度分布的影响,经过某种变换变成一幅具有均匀灰度概率密度分布的新影像,其结果是是扩大了像元取值得动态范围。
效果:(1)均衡后每个灰度级的像元频率近似相等。
(2)频率少的灰度级被合并,频率数高的灰度级被保留,可以增强影像上大面积地物与周围地物的反差。
六、实验步骤1.直方图规定化与统计:同时打开两幅遥感影像,影像显示号分别为Display#1,Display#2.规划化前影像——Display#2规划化前影像——Display#11)在Display#2的主影像窗口选择Enhance/HistogramMatching,出现HistogramMatchingInputparameter对化框。
2)在“MatchTo”列表中,选择匹配的直方图的影像显示号Display#1。
3)在InputHistogram/Image/OK得到直方图匹配后的结果。
4)在“Flie/SaveImageAs/Imagefile”中得到对话框“OutputDisplaytoimageFile”选择保存所在文件下,保存为”guihua”。
在“BasicTools/statistics/ComputerStatistics/ComputerStatisticsInputFile”,选择所要分析统计的图像文件.例如guihua/OK/BasicStats/Histograms/OK按Display#1的影像进行匹配后的Display#2即guihua规划化前影像——Display#1 在StatisticsResults:guihua/SelectPlot/Histogram:AllBands并对三幅图进行分析Guihua直方统计图Display#2直方统计图Display#1直方统计图结果分析:[1].由上显示图—1为规划化后的图,图—2,3为规划化前的图,三幅图每个都有3个波段,图—2,3在灰度值0—255之间变化,图—1在0-210之间变化,图—1,2在灰度值80—170变化较集中。
色彩校正和调整色彩校正和调整在图像处理和设计中扮演着重要的角色。
它可以改善图像的视觉效果,使色彩更加真实、鲜明,从而提升观看者的视觉体验。
在本文中,我们将探讨色彩校正和调整的概念、方法和应用。
一、概念色彩校正是指通过调整和修正图像的色彩参数,使其与实际场景或预期效果更加接近。
它可以涉及到亮度、对比度、饱和度、色调等多个方面的调整。
而色彩调整则是指对图像的色彩进行修正和改变,以达到设计、艺术或个人喜好的目的。
二、方法1. 直方图调整直方图是图像中灰度级别分布的统计图,可以用来分析图像的色彩分布情况。
通过直方图调整可以改变图像的亮度、对比度和色调。
具体方法包括:- 亮度调整:通过调整曲线在直方图上的位置,增加或减少图像的亮度;- 对比度调整:通过拉伸直方图中的对比度范围,增加或减少图像的对比度;- 色调调整:通过调整直方图中不同色彩通道的分布,改变图像的色调。
2. 色彩平衡调整色彩平衡调整可以改变图像中不同色彩通道的分布,使得整个图像的色彩更加均衡。
具体方法包括:- 色阶调整:通过调整图像中不同灰度级别的亮度,改变图像整体的色彩平衡;- 色相饱和度调整:通过调整不同色彩通道的饱和度,增加或减少图像的颜色鲜艳程度。
3. 色彩校正工具现代图像处理软件提供了多种色彩校正工具,可以简化和加速色彩校正的过程。
其中一些常见的工具包括:- 色彩平衡工具:通过滑动条调整不同色彩通道的分布;- 曲线工具:可以直接调整直方图曲线,改变亮度和对比度;- 色相/饱和度工具:通过调整色相、饱和度和亮度的值,改变图像的色彩效果。
三、应用色彩校正和调整广泛应用于各行各业,包括摄影、电影制作、广告设计等。
以下是一些具体的应用场景:1. 摄影后期处理在摄影中,由于光线、相机参数等各种因素的影响,拍摄出来的照片可能存在色彩偏差或不理想的情况。
通过色彩校正和调整,可以使照片的色彩更加真实、自然。
2. 影视特效制作在电影、电视剧等影视作品的制作中,色彩校正和调整可以用来营造不同的视觉效果,增强故事情节的表现力。
Photoshop调整直方图和色阶的方法和技巧Photoshop是一款功能强大的图像处理软件,可以通过调整直方图和色阶来改善图片的曝光、对比度和色彩平衡等方面。
本文将详细介绍使用Photoshop调整直方图和色阶的方法和技巧,帮助读者更好地掌握这一技巧。
一、调整直方图的方法和技巧1. 打开图片:在Photoshop中,点击“文件”-“打开...”,选择你想要处理的图片并点击“打开”。
2. 打开直方图:在Photoshop的右边工具栏中,找到“窗口”-“直方图”,点击打开直方图面板。
3. 分析直方图:直方图显示了图片的亮度和颜色分布情况。
从左到右代表了图片的亮度从黑到白的变化,从下到上代表了亮度的数量。
4. 调整曝光:如果直方图的分布不够均匀,说明图片的曝光可能有问题。
可以通过移动直方图面板下方的曝光调节滑块,增加或减少曝光来调整整体图片的明亮度。
5. 扩展直方图范围:如果直方图范围不够宽,即直方图的左右两端有过多的空白,可以尝试移动直方图面板下方的黑色和白色调节滑块,以扩展直方图的范围。
6. 确认调整效果:在进行直方图调整后,需要及时预览调整效果。
可以点击直方图面板右上角的眼睛图标,打开和关闭预览模式,以便更好地观察调整结果。
二、调整色阶的方法和技巧1. 打开图片:同样先打开需要处理的图片。
2. 打开色阶:依然在Photoshop的右边工具栏中,找到“窗口”-“色阶”,点击打开色阶面板。
3. 分析色阶:色阶面板上有一个直方图和三个灰度调节滑块,分别代表了图片的黑色、中间调和白色。
可以通过调整这三个滑块来改变图片的对比度和颜色平衡。
4. 调整黑色点:将黑色调节滑块向右移动,使得黑色逐渐变暗,可以增加图片的对比度和深度。
5. 调整白色点:将白色调节滑块向左移动,使得白色逐渐变亮,可以增加图片的亮度和清晰度。
6. 调整中间调:移动中间调节滑块,可以改变图片的整体明暗对比度。
向左移动会使图片变暗,向右移动则会使图片变亮。
实验名称:直方图的修正一、实验内容1、对影像进行直方图的均衡化;2、利用另外一幅影像进行直方图的匹配;3、利用直方图统计功能对结果进行分析。
二、实验所用的仪器设备遥感处理ENVI软件,遥感影像bhtmref.img文件三、实验原理图像增强是指按特定的需要突出一幅图像中的某些信息,同时,消弱或去除某些不需要的信息的处理方法。
其主要目的是处理后的图像对某些特定的应用比原来的图像更加有效。
图像增强技术主要有直方图修改处理、图像平滑化处理、图像尖锐化处理和彩色处理技术等。
本次实验以直方图的均衡化和规定化的方法为主要内容。
1、图象灰度的直方图:横坐标为灰度级,纵坐标为概率建立的图形2、直方图的修正包括:1直方图均衡化 2直方图规定化直方图的均衡化又称平坦化,是将一已知灰度概率密度分布影像,经过某种变换,变成一幅具有均匀灰度概率密度分布的新影像,其结果是扩大了象元取值的动态范围;直方图均衡化后的效果::①各灰度级所占图像的面积近似相等。
②原图像上频数小的灰度级被合并,频数高的灰度级则保留且不能被分割,因此可以增强图像上大面积地物与周围地物的反差。
③当输出数据分段级较少时,则会产生一些大类地物的大致近似的轮廓。
直方图的规定化是指将原始影像调整到事先规定的已知的形状,以此来对原始影像特定灰度范围进行增强处理。
四、实验步骤1.打开envi 软件,依次选择TM Band 4 ,TM Band3, TM Band 2得到该影像的标准假彩色合成图像,如图一所示:图一图二2、在Basic tools 里选择 statistics → computer statistics → Spectral Subset 选择4、3、2波段→勾选 covariance 、histogram 、output to a statistics (.sta)、output to a Text Report File (.txt)得到直方图及其计算数据如图二所示:由图二的直方图可看到每个灰度级的分布状况,并且有以下数据统计(在输出的txt文件中查看)(二)对bhtmref影像进行均衡化,并与原始图像进行对比1、选择enhance → [image]equalization 得到图像三save image as image file (equ_b.img)→open image file →在available bands list 中依次选择bhtmref1 的4、3、2波段→display #2→new play →load图三图四2、将bhtmref1 重复(一)的步骤得到均衡化后的直方图如图四所示由图四均衡化后的灰度直方图可得到以下数据对比分析:①均衡化后的图像比原始图像轮廓更为清晰,大面积地物与周围地物仍然存在强烈反差,影像效果更加明显。
第5章直方图修正和彩色变换这一章,我们主要和调色板打交道。
先从最简单的反色讲起。
5.1 反色反色(invert)就是形成底片效果。
例如,图5.2为图5.1反色后的结果。
图5.1 原图图5.2 图5.1反色后的结果反色有时是很有用的,比如,图5.1中黑色区域占绝大多数,这样打印起来很费墨,我们可以先进行反色处理后再打印。
反色的实际含义是将R、G、B值反转。
若颜色的量化级别是256,则新图的R、G、B值为255减去原图的R、G、B值。
这里针对的是所有图,包括真彩图、带调色板的彩色图(又称为伪彩色图)、和灰度图。
针对不同种类有不同的处理。
先看看真彩图。
我们知道真彩图不带调色板,每个象素用3个字节,表示R、G、B三个分量。
所以处理很简单,把反转后的R、G、B值写入新图即可。
再来看看带调色板的彩色图,我们知道位图中的数据只是对应调色板中的一个索引值,我们只需要将调色板中的颜色反转,形成新调色板,而位图数据不用动,就能够实现反转。
灰度图是一种特殊的伪彩色图,只不过调色板中的R、G、B值都是一样的而已。
所以反转的处理和上面讲的一样。
这里,我想澄清一个概念。
过去我们讲二值图时,一直都说成黑白图。
二值位图一定是黑白的吗?答案是不一定。
我们安装Windows95时看到的那幅setup.bmp是由蓝色和黑色组成的,但它实际上是二值图。
原来,它的调色板中的两种颜色是黑与蓝,而不是黑与白。
所以说二值图也可以是彩色的,只不过一般情况下是黑白图而已。
下面的程序实现了反色,注意其中真彩图和调色板位图处理时的差别。
BOOL Invert(HWND hWnd){DWORD OffBits,BufSize; LPBITMAPINFOHEADER lpImgData;LPSTR lpPtr;HLOCAL hTempImgData;LPBITMAPINFOHEADER lpTempImgData;LPSTR lpTempPtr;HDC hDc;HFILE hf;LONG x,y;LOGPALETTE *pPal;HPALETTE hPrevPalette=NULL;HLOCAL hPal;DWORD i;unsigned char Red,Green,Blue;OffBits=bf.bfOffBits-sizeof(BITMAPFILEHEADER);BufSize=OffBits+bi.biHeight*LineBytes; //新开缓冲区的大小if((hTempImgData=LocalAlloc(LHND,BufSize))==NULL) {MessageBox(hWnd,"Error alloc memory!","Error Message",MB_OK| MB_ICONEXCLAMATION);return FALSE;}lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);lpTempImgData=(LPBITMAPINFOHEADER)LocalLock(hTempImgData);//拷贝头信息memcpy(lpTempImgData,lpImgData,BufSize);hDc=GetDC(hWnd);if(NumColors!=0){ //NumColors不为0说明是带调色板的lpPtr=(char *)lpImgData+sizeof(BITMAPINFOHEADER);//指向原图数据lpTempPtr=(char *)lpTempImgData+sizeof(BITMAPINFOHEADER);//指向新图数据//为新调色板分配内存hPal=LocalAlloc(LHND,sizeof(LOGPALETTE)+NumColors*sizeof(PALETTEENTRY));pPal =(LOGPALETTE *)LocalLock(hPal);pPal->palNumEntries =(WORD) NumColors;pPal->palVersion = 0x300;for (i = 0; i < NumColors; i++) {Blue=(unsigned char )(*lpPtr++);Green=(unsigned char )(*lpPtr++);Red=(unsigned char )(*lpPtr++);lpPtr++;//反转调色板中的颜色,存入新的调色板pPal->palPalEntry[i].peRed=(BYTE)(255-Red);pPal->palPalEntry[i].peGreen=(BYTE)(255-Green);pPal->palPalEntry[i].peBlue=(BYTE)(255-Blue);pPal->palPalEntry[i].peFlags=0;*(lpTempPtr++)=(unsigned char)(255-Blue);*(lpTempPtr++)=(unsigned char)(255-Green);*(lpTempPtr++)=(unsigned char)(255-Red);*(lpTempPtr++)=0;}if(hPalette!=NULL)DeleteObject(hPalette);hPalette=CreatePalette(pPal); //产生新的调色板LocalUnlock(hPal);LocalFree(hPal);if(hPalette){hPrevPalette=SelectPalette(hDc,hPalette,FALSE);RealizePalette(hDc);}}else{ //不带调色板,说明是真彩色图for(y=0;y<bi.biHeight;y++){lpPtr=(char *)lpImgData+(BufSize-LineBytes-y*LineBytes);lpTempPtr=(char *)lpTempImgData+(BufSize-LineBytes-y*LineBytes);for(x=0;x<bi.biWidth;x++){Blue=(unsigned char )(*lpPtr++);Green=(unsigned char )(*lpPtr++);Red=(unsigned char )(*lpPtr++);//反转位图数据中的颜色,存入新的位图数据中*(lpTempPtr++)=(unsigned char)(255-Blue);*(lpTempPtr++)=(unsigned char)(255-Green);*(lpTempPtr++)=(unsigned char)(255-Red);}}}if(hBitmap!=NULL)DeleteObject(hBitmap);hBitmap=CreateDIBitmap(hDc,(LPBITMAPINFOHEADER)lpTempImgData, (LONG)CBM_INIT,(LPSTR)lpTempImgData+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD),(LPBITMAPINFO)lpTempImgData,DIB_RGB_COLORS);if(hPalette && hPrevPalette){SelectPalette(hDc,hPrevPalette,FALSE);RealizePalette(hDc);}hf=_lcreat("c:\\invert.bmp",0);_lwrite(hf,(LPSTR)&bf,sizeof(BITMAPFILEHEADER));_lwrite(hf,(LPSTR)lpTempImgData,BufSize);_lclose(hf);//释放内存和资源ReleaseDC(hWnd,hDc);LocalUnlock(hTempImgData);LocalFree(hTempImgData);GlobalUnlock(hImgData);return TRUE;}5.2 彩色图转灰度图第2章中提到了YUV的颜色表示方法,在这种表示方法中,Y分量的物理含义就是亮度,它含了灰度图(grayscale)的所有信息,只用Y分量就完全能够表示出一幅灰度图来。
YUV和RGB之间有着如下的对应关系:我们利用上式,根据R、G、B的值求出Y值后,将R、G、B值都赋值成Y,就能表示出灰度图来,这就是彩色图转灰度图的原理。
先看看真彩图。
我们知道真彩图不带调色板,每个象素用3个字节,表示R、G、B三个分量。
所以处理很简单,根据R、G、B的值求出Y值后,将R、G、B值都赋值成Y,写入新图即可。
再来看看带调色板的彩色图,我们知道位图中的数据只是对应调色板中的一个索引值,我们只需要将调色板中的彩色变成灰度,形成新调色板,而位图数据不用动,就可以了。
下面的程序实现了彩色图到灰度图的转换,注意其中真彩图和调色板位图处理时的差别。
BOOL ColortoGrayScale(HWND hWnd){DWORD SrcOffBits,SrcBufSize,DstBufSize,DstLineBytes;LPBITMAPINFOHEADER lpImgData;LPSTR lpPtr;HLOCAL hTempImgData;LPBITMAPINFOHEADER lpTempImgData;LPSTR lpTempPtr;HDC hDc;HFILE hf;LONG x,y;BITMAPFILEHEADER DstBf;BITMAPINFOHEADER DstBi;LOGPALETTE *pPal;HPALETTE hPrevPalette;HLOCAL hPal;DWORD NewNumColors;WORD NewBitCount;float Y;DWORD i;unsigned char Red,Green,Blue,Gray;NewNumColors=NumColors; //NewNumColors为新图的颜色数NewBitCount=bi.biBitCount; //NewBitCount为新图的颜色位数if(NumColors==0) //真彩图{NewNumColors=256;NewBitCount=8;}//由于颜色位数有可能发生了改变,所以要重新计算每行占用的字节数以及//新图的缓冲区大小DstLineBytes=(DWORD)WIDTHBYTES(bi.biWidth*NewBitCount);DstBufSize=(DWORD)(sizeof(BITMAPINFOHEADER)+NewNumColors* sizeof(RGBQUAD)+(DWORD)DstLineBytes*bi.biHeight);//DstBf和DstBi为新的BITMAPFILEHEADER和BITMAPINFOHEADER //拷贝原来的头信息memcpy((char *)&DstBf,(char *)&bf,sizeof(BITMAPFILEHEADER));memcpy((char *)&DstBi,(char *)&bi,sizeof(BITMAPINFOHEADER));//做必要的改变DstBf.bfSize=DstBufSize+sizeof(BITMAPFILEHEADER);DstBf.bfOffBits=(DWORD)(NewNumColors*sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER));DstBi.biClrUsed=0;DstBi.biBitCount=NewBitCount;//原图的缓冲区的大小SrcOffBits=bf.bfOffBits- sizeof(BITMAPFILEHEADER);SrcBufSize=SrcOffBits+bi.biHeight*LineBytes;if((hTempImgData=LocalAlloc(LHND,DstBufSize))==NULL){MessageBox(hWnd,"Error alloc memory!","Error Message",MB_OK|MB_ICONEXCLAMATION);return FALSE;}lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);lpTempImgData=(LPBITMAPINFOHEADER)LocalLock(hTempImgData); //拷贝头信息和位图数据memcpy(lpTempImgData,lpImgData,DstBufSize);//用新的BITMAPINFOHEADER替换原来的头信息memcpy(lpTempImgData,(char *)&DstBi,sizeof(BITMAPINFOHEADER));//lpPtr指向原图的数据lpPtr=(char *)lpImgData+sizeof(BITMAPINFOHEADER);//lpTempPtr指向新图的数据lpTempPtr=(char *)lpTempImgData+sizeof(BITMAPINFOHEADER);//为新的调色板分配内存hPal=LocalAlloc(LHND,sizeof(LOGPALETTE) + NewNumColors* sizeof(PALETTEENTRY));pPal =(LOGPALETTE *)LocalLock(hPal);pPal->palNumEntries =(WORD) NewNumColors;pPal->palVersion = 0x300;if(NumColors==0) //真彩色for (i = 0; i < 256; i++) { //灰度从(0,0,0)到(255,255,255)pPal->palPalEntry[i].peRed=(BYTE)i;pPal->palPalEntry[i].peGreen=(BYTE)i;pPal->palPalEntry[i].peBlue=(BYTE)i;pPal->palPalEntry[i].peFlags=(BYTE)0;*(lpTempPtr++)=(unsigned char)i;*(lpTempPtr++)=(unsigned char)i;*(lpTempPtr++)=(unsigned char)i;*(lpTempPtr++)=0;}elsefor (i = 0; i < NewNumColors; i++) { //带调色板的彩色图Blue=(unsigned char )(*lpPtr++);Green=(unsigned char )(*lpPtr++);Red=(unsigned char )(*lpPtr++);Y=(float)(Red*0.299+Green*0.587+Blue*0.114);Gray=(BYTE)Y;lpPtr++;//从原来的调色板中的颜色计算得到Y值,写入新的调色板pPal->palPalEntry[i].peRed=Gray;pPal->palPalEntry[i].peGreen=Gray;pPal->palPalEntry[i].peBlue=Gray;pPal->palPalEntry[i].peFlags=0;*(lpTempPtr++)=(unsigned char)Gray;*(lpTempPtr++)=(unsigned char)Gray;*(lpTempPtr++)=(unsigned char)Gray;*(lpTempPtr++)=0;}if(hPalette!=NULL)DeleteObject(hPalette);//生成新的逻辑调色板hPalette=CreatePalette(pPal);LocalUnlock(hPal);LocalFree(hPal);hDc=GetDC(hWnd);if(hPalette){hPrevPalette=SelectPalette(hDc,hPalette,FALSE);RealizePalette(hDc);}if(NumColors==0) //真彩色图才需要处理位图数据for(y=0;y<bi.biHeight;y++){lpPtr=(char *)lpImgData+(SrcBufSize-LineBytes-y*LineBytes);lpTempPtr=(char*)lpTempImgData+(DstBufSize-DstLineBytes-y*DstLineBytes);for(x=0;x<bi.biWidth;x++){Blue=(unsigned char )(*lpPtr++);Green=(unsigned char )(*lpPtr++);Red=(unsigned char )(*lpPtr++);Y=(float)(Red*0.299+Green*0.587+Blue*0.114);//从位图数据计算得到Y值,写入新图中Gray=(BYTE)Y;*(lpTempPtr++)=(unsigned char)Gray;}}if(hBitmap!=NULL)DeleteObject(hBitmap);//产生新的位图hBitmap=CreateDIBitmap(hDc,(LPBITMAPINFOHEADER)lpTempImgData, (LONG)CBM_INIT,(LPSTR)lpTempImgData+sizeof(BITMAPINFOHEADER)+NewNumColors*sizeof(RGBQUAD),(LPBITMAPINFO)lpTempImgData,DIB_RGB_COLORS);if(hPalette && hPrevPalette){SelectPalette(hDc,hPrevPalette,FALSE);RealizePalette(hDc);}hf=_lcreat("c:\\gray.bmp",0);_lwrite(hf,(LPSTR)&DstBf,sizeof(BITMAPFILEHEADER));_lwrite(hf,(LPSTR)lpTempImgData,DstBufSize);_lclose(hf);//释放内存和资源ReleaseDC(hWnd,hDc);LocalUnlock(hTempImgData);LocalFree(hTempImgData);GlobalUnlock(hImgData);return TRUE;}5.3 真彩图转256色图我们知道,真彩图中包含最多达224种颜色,怎样从中选出256种颜色,又要使颜色的失真比较小,这是一个比较复杂的问题。