VC编程实现灰度图像与彩色图像的相互转换要点
图像灰度化方法总结及其VC实现
图像灰度化方法总结及其VC实现最近一段时间作者开始进行运动目标识别定位系统设计,本文以及后续的几篇文章都是从一个图像处理初学者的角度来总结目标检测定位过程中所应用到的各种常见的算法,尤其是解决算法实现过程中由于粗心大意或者C编程基本功不扎实所引起的各种问题。
本文主要对彩色图片灰度化的方法及其实现过程进行总结,最终给出实现的C代码。
在进行视频流目标识别与跟踪时,通常第一个步骤就是对采集到的彩色图像进行灰度化,这是因为黑白照片数据量小,相比彩照更易实现实时算法,另一方面黑白照片是由未处理的光线所形成的照片,因此从图像处理学角度来看,这种未经特殊滤光处理的图片所涵盖的信息更有价值。
目前,在图像处理过程中,最常用的彩色图片格式有RGB,HSV、YUV以及HLS三种。
以下分别对这三种格式的彩色图像进行灰度化实现。
1、RGB空间图像定义于RGB空间的彩色图,其每个像素点的色彩由R、G、B三个分量共同决定。
每个分量在内存所占的位数共同决定了图像深度,即每个像素点所占的字节数。
以常见的24深度彩色RGB图来说,其三个分量各占1个字节,这样每个分量可以取值为0~255,这样一个像素点可以有1600多万(255*255*255)的颜色的变化范围。
对这样一幅彩色图来说,其对应的灰度图则是只有8位的图像深度(可认为它是RGB三个分量相等),这也说明了灰度图图像处理所需的计算量确实要少。
不过需要注意的是,虽然丢失了一些颜色等级,但是从整幅图像的整体和局部的色彩以及亮度等级分布特征来看,灰度图描述与彩色图的描述是一致的。
对于RGB图像进行灰度化,通俗点说就是对图像的RGB三个分量进行加权平均得到最终的灰度值。
最常见的加权方法如下:1)Gray=B;Gray=G;Gray=R2)Gray=max(B+G+R)3)Gray=(B+G+R)/34)Gray= 0.072169B+ 0.715160G+ 0.212671R5)Gray= 0.11B+ 0.59G+ 0.3R这三种方法中,第一种为分量法,即用RGB三个分量的某一个分量作为该点的灰度值;第二种方法为最大值法,将彩色图像中的三分量亮度的最大值作为灰度图的灰度值。
C#两种获取灰度图像的方法
C#两种获取灰度图像的方法第一种:在图像处理程序开发中,常会遇到将一幅彩色图像转换成灰度图像的情况,笔者在最近的一个项目中便遇到了这点。
经过一翻努力最终解决,想想有必要分享一下,于是便写下此文。
在本文中,将向各位读者介绍两种实现这一变换的方法,这也是笔者先后使用的两种方法。
本文的例子使用C#语言编写,使用的集成开发环境是Visual Studio 2005。
第一种,直接调用GetPixel/SetPixel方法。
我们都知道,图像在计算机中的存在形式是位图,也即一个矩形点阵,每一个点被称为一个像素。
在这种方法中,我们通过GDI+中提供的GetPixel方法来读取像素的颜色,并加以计算,然后再使用SetPixel方法将计算后的颜色值应用到相应的像素上去,这样便可以得到灰度图像。
上边提到的“计算”便是指得到灰度图像的计算,其公式是:r = (像素点的红色分量 + 像素点的绿色分量 + 像素点的蓝色分量) / 3最后得到的r便是需要应用到原像素点的值。
具体的编程实现也非常的简单,只需要遍历位图的每一个像素点,然后使用SetPixel方法将上边计算得到的值应用回去即可。
主要代码如下所示:Color currentColor;int r;Bitmap currentBitmap = new Bitmap(picBox.Image);Graphics g = Graphics.FromImage(currentBitmap);for (int w = 0; w < currentBitmap.Width; w++){for (int h = 0; h < currentBitmap.Height; h++){currentColor = currentBitmap.GetPixel(w, h);r = (currentColor.R + currentColor.G + currentColor.B) / 3;currentBitmap.SetPixel(w, h, Color.FromArgb(r, r, r));}}g.DrawImage(currentBitmap, 0, 0);picBox.Image = currentBitmap;g.Dispose();以上代码非常简单,不需要做太多的解释。
cvtcolor 函数 原理 c++ opencv 背后代码
cvtColor是OpenCV 中的一个非常有用的函数,用于将图像从一种颜色空间转换到另一种颜色空间。
在C++ 中,它的基本语法如下:
cpp复制代码
void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0);
其中:
•src是输入图像,它是一个多通道的图像。
•dst是输出图像,它的类型和通道数由code参数决定。
•code是转换类型,比如CV_BGR2GRAY,CV_BGR2HSV等。
•dstCn是输出图像的通道数,如果为0,则根据code参数确定通道数。
下面我们深入到其背后代码的工作原理:
cvtColor的工作方式是通过使用查找表(LUT)来实现的。
查找表是一个预先计算好的数组,用于快速查找像素的转换值。
这使得颜色空间转换可以在常数时间内完成,大大提高了效率。
对于每个像素,我们可以通过查找表找到其在新颜色空间中的值。
例如,如果我们正在将一个RGB 图像转换为灰度图像,那么对于每个RGB 值,我们可以在查找表中查找其对应的灰度值。
然后,我们用这个灰度值替换原来的RGB 值。
这种方法的优点是速度快,但也有一个缺点:它需要预先计算查找表,这可能会占用大量的内存。
然而,对于大多数应用来说,这是可以接受的。
请注意,OpenCV 提供了许多内置的颜色空间转换代码,如CV_BGR2GRAY(从BGR 颜色空间到灰度颜色空间),CV_BGR2HSV(从BGR 颜色空间到HSV 颜色空间)等。
用户也可以定义自己的颜色空间转换代码。
color_gray2bgr 原理
color_gray2bgr 原理color_gray2bgr是一个用于将灰度图像转换为彩色图像的函数。
在计算机视觉和图像处理中,灰度图像是一种只有灰度值而没有颜色的图像,每个像素点的灰度值表示了该像素的亮度。
而彩色图像则具有多个通道,每个通道对应不同的颜色分量,例如红、绿、蓝(RGB)。
在很多应用中,我们需要将灰度图像转换为彩色图像,以提供更多的信息和细节。
color_gray2bgr函数正是为了满足这个需求而设计的。
它的原理是通过将灰度图像的灰度值赋给彩色图像的每个颜色通道,从而生成一个具有相同亮度但是彩色的图像。
具体而言,color_gray2bgr函数首先创建一个与灰度图像相同大小的彩色图像。
然后,它遍历灰度图像中的每个像素,将该像素的灰度值分别赋给彩色图像的红、绿和蓝通道。
这样,我们就得到了一个彩色图像,其中的每个像素都具有与原灰度图像相同的亮度,但是拥有不同的颜色。
通过这种方式,color_gray2bgr函数能够将灰度图像转换为彩色图像,从而提供更多的信息和细节。
这对于一些图像处理任务非常有用,例如目标检测和图像分割。
通过将灰度图像转换为彩色图像,我们可以更好地区分不同的物体和区域,从而提高算法的准确性和效果。
需要注意的是,color_gray2bgr函数只是一种简单的转换方式,它并不能从灰度图像中恢复出原始的彩色信息。
因为在灰度图像中,不同的颜色信息已经被丢失,只剩下了亮度信息。
所以,通过简单地将灰度值赋给彩色通道,并不能还原出原始的彩色图像。
在实际应用中,如果我们需要从灰度图像中恢复出原始的彩色信息,就需要借助其他的方法和技术。
例如,可以通过图像分析和机器学习的方法,从其他信息中推断出原始的彩色信息。
这是一个非常复杂的问题,需要深入的研究和专业的知识。
color_gray2bgr是一个用于将灰度图像转换为彩色图像的函数。
它通过将灰度值赋给彩色通道,生成一个具有相同亮度但是彩色的图像。
彩色图像与灰度图像之间的转换
彩⾊图像与灰度图像之间的转换⼀.彩⾊图像简介在RGB⾊彩空间,图像深度与⾊彩的映射关系主要有真彩⾊、伪彩⾊和调配⾊。
真彩⾊是指在组成⼀幅彩⾊图像的每个像素值中,有R,G,B三个基⾊分量,每个基⾊分量直接决定显⽰设备的基⾊强度,这样产⽣的彩⾊称为真彩⾊,是真实的原图彩⾊。
伪彩⾊图像的每个像素值实际上是⼀个索引值或代码,该代码值作为⾊彩查找表CLUT中某⼀项的⼊⼝地址,根据该地址可查找出包含实际R,G,B的强度值。
这种⽤查找映射的⽅法产⽣的⾊彩称为伪彩⾊。
⾊彩查找表CLUT是⼀个事先做好的表,表项⼊⼝地址也称为索引号。
彩⾊图像本⾝的像素数值和⾊彩查找表的索引号有⼀种变换关系,这种关系可以是系统定义的,也可以是⽤户⾃⼰定义的变换关系。
使⽤查找得到的数值显⽰的彩⾊是真的,可⼜不是图像本⾝的颜⾊,因为其没有完全反映原图的彩⾊,所以称其为伪彩⾊。
调配⾊的获取是通过每个像素点的R,G,B分量分别作为单独的索引值进⾏变换,经相应的⾊彩查找表找出各⾃的基⾊强度,⽤变换后的R,G,B强度值产⽣⾊彩。
⼆.灰度图像简介灰度是描述灰度图像内容的最直接的视觉特征。
它指⿊⽩图像中点的颜⾊深度,范围⼀般从0到255,⽩⾊为255,⿊⾊为0,故⿊⽩图像也称灰度图像。
灰度图像矩阵元素的取值通常为[0,255],因此其数据类型⼀般为8位⽆符号整数,这就是⼈们通常所说的256级灰度。
三.彩⾊图像转化为灰度图像彩⾊图像转换为灰度图像时,需要计算图像中每个像素有效的亮度值,其计算公式为:Y = 0.3R + 0.59G + 0.11B代码如下:clear all;close all;I = imread('lenna.png');[M N H] = size(I);I2 = zeros(M, N);for x = 1 : Mfor y = 1 : NA = double([I(x, y, 1) I(x, y, 2) I(x, y, 3)]);B = [0.3; 0.59; 0.11];[gray] = A * B; % 计算灰度值I2(x, y) = gray;endendimshow(uint8(I2));四.灰度图像转换为彩⾊图像将灰度图像转换为彩⾊图像,称为灰度图像的伪彩⾊处理。
cvcvtcolor函数
cvcvtcolor函数cvCvtColor函数是OpenCV中的一个非常重要的函数,它能够实现将视频图像数据中的RGB颜色空间转换到其他格式,也就是彩色图像可以由它转换成灰度图像,或者灰度图像可以转换成彩色图像。
1. cvCvtColor函数的作用cvCvtColor函数的作用是实现图像的颜色空间变换,因此它通常被用于彩色图像转换为灰度图像和灰度图像转换为彩色图像。
它的应用非常广泛,包括图像处理、计算机视觉等。
2. cvCvtColor函数的参数cvCvtColor函数定义格式为:cvCvtColor( src, dst, code ),其中src代表原图像,dst代表目标图像,code代表转换类型:(1)CV_BGR2GRAY: BGR图像转换到灰度图像;(2)CV_RGB2GRAY: RGB图像转换到灰度图像;(3)CV_GRAY2BGR:灰度图转换到BGR图像;(4)CV_GRAY2RGB:灰度图转换到RGB图像。
3. cvCvtColor函数的应用(1)数字图像处理:在数字图像处理中,OpenCV中提供了cvCvtColor函数,可以将彩色图像数据转换为其他格式或者灰度图像转换为彩色图像,以便对图像进行更进一步的处理;(2)计算机视觉:cvCvtColor函数也可以用于计算机视觉,可以将彩色图像数据转换为灰度图像或者灰度图像转换为彩色图像,便于进一步提取图像特征信息再使用。
4. cvCvtColor函数的优点(1)cvCvtColor函数有效简化了图像转换操作,可以大大提高图像处理效率;(2)它提供了多种不同的颜色空间转换,灵活性强;(3)转换的结果一般来说满足客观要求;(4)它可以让图像数据对更多的开发平台都可以被有效利用。
灰度转伪彩原理
灰度转伪彩原理灰度转伪彩原理是数字图像处理中常用的一种技术,它可以将灰度图像转换为伪彩色图像,使得图像更加直观、易于观察和分析。
本文将介绍灰度转伪彩的原理及其应用。
一、灰度图像与伪彩色图像的区别灰度图像是指每个像素点的颜色只有黑、白和灰色,它的颜色信息只有一个通道,即灰度值。
而伪彩色图像是将灰度图像的灰度值映射到伪彩色表中,通过伪彩色表来表示不同的灰度值范围对应的颜色,从而使图像呈现出多种颜色,增加了图像的信息量。
二、灰度转伪彩的原理灰度转伪彩的原理主要包括灰度映射和伪彩色表的生成两个步骤。
1. 灰度映射灰度映射是将灰度图像中的灰度值映射到伪彩色表上的过程。
常用的灰度映射方法有线性映射、对数映射、幂次映射等。
其中,线性映射是最常用的方法,它通过线性函数将灰度值映射到伪彩色表上,从而实现灰度图像到伪彩色图像的转换。
2. 伪彩色表的生成伪彩色表是指将灰度图像中的不同灰度值映射到不同的颜色上,形成伪彩色图像的颜色表。
伪彩色表通常由多种颜色组成,每种颜色代表一定范围的灰度值。
生成伪彩色表的方法有很多种,常用的有线性映射法、对数映射法、直方图均衡化等。
三、灰度转伪彩的应用灰度转伪彩技术在医学影像、地质勘探、红外图像处理等领域有着广泛的应用。
1. 医学影像在医学影像中,灰度转伪彩技术可以将CT、MRI等灰度图像转换为伪彩色图像,使得医生在观察病灶时更加直观和准确。
例如,将肿瘤映射为红色、健康组织映射为绿色,可以帮助医生更好地诊断和治疗疾病。
2. 地质勘探在地质勘探中,利用灰度转伪彩技术可以将地质图像中的地质信息以不同的颜色显示出来,帮助地质学家更好地分析地质结构和地质特征。
例如,将不同类型的矿石映射为不同的颜色,可以帮助地质学家找到矿产资源。
3. 红外图像处理在红外图像处理中,灰度转伪彩技术可以将红外图像中的温度信息以不同的颜色呈现出来,使得人眼可以直观地观察到温度分布的差异。
例如,在建筑物的热成像检测中,将高温区域映射为红色,低温区域映射为蓝色,可以帮助工程师及时发现隐患。
图像打开,另存为,转为灰度图像(利用cimage方法实现)
CImage类的介绍与使用程序代码下载处:/source/2098910下载处:/wangleitongxing/blog/item/9063b03e5e20f3c97c1e71c8.htmlVisual C++的CBitmap类和静态图片控件的功能是比较弱的,它只能显示出在资源中的图标、位图、光标以及图元文件的内容,而不像VB中的Image控件可以显示出绝大多数的外部图像文件(BMP、GIF、JPEG等)。
因此,想要在对话框或其他窗口中显示外部图像文件则只能借助于第三方提供的控件或代码。
现在,MFC和ATL共享的新类CImage为图像处理提供了许多相应的方法,这使得Visual C++在图像方面的缺憾一去不复返了。
CImage类概述CImage是MFC和ATL共享的新类,它能从外部磁盘中调入一个JPEG、GIF、BMP和PNG格式的图像文件加以显示,而且这些文件格式可以相互转换。
由于CImage在不同的Windows 操作系统中其某些性能是不一样的,因此在使用时要特别注意。
例如,CImage::PlgBlt和CImage::MaskBlt只能在Windows NT 4.0 或更高版本中使用,但不能运行在Windows 95/98 应用程序中。
CImage::AlphaBlend和CImage::TransparentBlt也只能在Windows 2000/98或其更高版本中使用。
即使在Windows 2000运行程序还必须将stdafx.h文件中的WINVER和_WIN32_WINNT的预定义修改成0x0500才能正常使用。
CImage封装了DIB(设备无关位图)的功能,因而可以让我们能够处理每个位图像素。
它具有下列最酷特性:1、AlphaBlend支持像素级的颜色混合,从而实现透明和半透明的效果。
2、PlgBlt能使一个矩形区域的位图映射到一个平行四边形区域中,而且还可能使用位屏蔽操作。
3、TransparentBlt在目标区域中产生透明图像,SetTransparentColor用来设置某种颜色是透明色。
实验灰度图像锐化处理
实验五灰度图像的锐化处理一、实验目的1.了解图像锐化的根本原理;2.掌握图像空域锐化处理的方法;3.利用VC编写图像空域锐化处理的程序;4.在微机上调试程序。
二、实验原理图像平滑处理可以减弱噪声的影响,但窗口增大后将会产生图像边缘不清的问题。
图像在传输和转换过程中,一般来讲,质量都会降低,除了噪声的因素之外,图像一般都要变得模糊一些,这主要因为图像的传输或转换系统的传递函数对高频成分的衰减作用,造成图像的细节轮廓不清晰。
图像锐化的作用就是补偿图像的轮廓,增强图像的边缘级灰度跳变局部,使图像较清晰。
图像锐化是一种能加强图像轮廓的处理方法,因此,从增强的目的来看它是与图像平滑相反的一类处理,图像锐化同样也可分为频域和空域处理两类实现方法。
本实验要求完成空域中图像的锐化处理。
1.图像空域锐化处理的方法微分处理可加强高频成分,例如对正弦信号微分处理后,信号的频率不变,幅度增大N处理后:sin(Nx),其微分为余弦函数Ncos(Nx),经倍,且频率越高,增幅越大。
对图像进行微分f/ xG[(x,y)]=f/ yG[(x,y )]是点(x,y)的梯度,其方向指向f(x,y)最大变化方向。
对连续图像:G[(x,y)] =[〔f/ x〕2+〔f/ y〕2]1/2对离散图像:G[(x,y)]常采用以下几种算法:〔1〕典型的差分算法G[(x,y)]=[[f(x,y)-f(x+1,y)] 2+[f(x,y)-f(x,y+1)]2]1/2〔2〕罗伯茨算法G[(x,y)]=[[f(x,y)-f(x+1,y+1)] 2+[f(x+1,y)-f(x,y+1)]2]1/2〔3〕绝对差算法相对于典型的差分算法和罗伯茨算法有:G[(x,y)]=|f(x,y)-f(x+1,y)|+|f(x,y)-f(x,y+1)|G[(x,y)]=|f(x,y)-f(x+1,y+1)|+|f(x+1,y)-f(x,y+1)|在实际处理一幅图像时,最后一行〔列〕梯度的值一般可以用前一行〔列〕的梯度的值来代替。
c++ cvtcolor 算法原理
c++ cvtcolor 算法原理
`cvtColor`是OpenCV中的一个重要函数,用于将一种颜色空间的图像转换为另一种颜色空间的图像。
该函数的实现基于线性插值算法,因此在转换过程中可能会出现一定的误差。
函数的原型为`cv::cvtColor(InputArray src, OutputArray dst, int code)`,其中`src`表示输入图像,`dst`表示输出图像,`code`表示颜色空间转换码。
该函数根据给定的颜色空间转换码`code`,将输入图像`src`从其原始颜色空间转换为指定的目标颜色空间,并将结果存储在输出图像`dst`中。
在OpenCV的源码中,针对不同的颜色空间转换也有不同的实现方式。
比如,对于RGB 和Lab颜色空间的转换,`cvtColor`函数使用的是矩阵乘法的方式实现的,而对于HSV颜色空间的转换,则使用了一些更为复杂的数学公式。
此外,在OpenCV的源码中,还针对不同的平台提供了不同的优化版本,以提升`cvtColor`函数的效率。
在使用`cvtColor`函数进行图像处理时,需要注意颜色空间的选择。
如果选择的颜色空间和实际图像的特征不匹配,那么处理结果就可能会出现偏差。
(完整版)实验-灰度图像的锐化处理
实验五灰度图像的锐化处理一、实验目的1.了解图像锐化的基本原理;2.掌握图像空域锐化处理的方法;3.利用VC编写图像空域锐化处理的程序;4.在微机上调试程序。
二、实验原理图像平滑处理可以减弱噪声的影响,但窗口增大后将会产生图像边缘不清的问题。
图像在传输和转换过程中,一般来讲,质量都会降低,除了噪声的因素之外,图像一般都要变得模糊一些,这主要因为图像的传输或转换系统的传递函数对高频成分的衰减作用,造成图像的细节轮廓不清晰。
图像锐化的作用就是补偿图像的轮廓,增强图像的边缘级灰度跳变部分,使图像较清晰。
图像锐化是一种能加强图像轮廓的处理方法,因此,从增强的目的来看它是与图像平滑相反的一类处理,图像锐化同样也可分为频域和空域处理两类实现方法。
本实验要求完成空域中图像的锐化处理。
1.图像空域锐化处理的方法微分处理可加强高频成分,例如对正弦信号sin(Nx),其微分为余弦函数Ncos(Nx),经微分处理后,信号的频率不变,幅度增大N倍,且频率越高,增幅越大。
对图像进行微分处理后:∆f/∆xG[(x,y)]=∆f/∆yG[(x,y)]是点(x,y)的梯度,其方向指向f(x,y)最大变化方向。
对连续图像:G[(x,y)]=[(∆f/∆x)2+(∆f/∆y)2]1/2对离散图像:G[(x,y)]常采用下列几种算法:(1)典型的差分算法G[(x,y)]=[[f(x,y)-f(x+1,y)]2+[f(x,y)-f(x,y+1)]2]1/2(2)罗伯茨算法G[(x,y)]=[[f(x,y)-f(x+1,y+1)]2+[f(x+1,y)-f(x,y+1)]2]1/2(3)绝对差算法相对于典型的差分算法和罗伯茨算法有:G[(x,y)]=|f(x,y)-f(x+1,y)|+|f(x,y)-f(x,y+1)|G[(x,y)]=|f(x,y)-f(x+1,y+1)|+|f(x+1,y)-f(x,y+1)|在实际处理一幅图像时,最后一行(列)梯度的值一般可以用前一行(列)的梯度的值来代替。
各种颜色相互转换算法的C语言源代码
各种颜色相互转换算法的C语言源代码2010-05-24 18:43:50//RGB to CMYkint* rgb2cmyk(int R,int G,int B){int cmyk [4];cmyk[3]=(int)(min(min(255-R,255-G),255-B)/2.55);//cmykK int MyR = (int)(R/2.55);int Div = 100-cmyk[3];if (Div == 0)Div = 1;cmyk[0] = ((100-MyR-cmyk[3])/Div)*100;//cmykCint MyG = (int)(G/2.55);cmyk[1] = ((100-MyG-cmyk[3])/Div)*100;int MyB = (int)(B/2.55);cmyk[2] = ((100-MyB-cmyk[3])/Div)*100;return cmyk;}//CMYK to RGBint* cmyk2rgb(int C,int M,int Y,int K){int rgb[3];int *R=&rgb[0];int *G=&rgb[1];int *B=&rgb[2];float MyC = C/100;float MyM = M/100;float MyY = Y/100;float MyK = K/100;int *R = (int)((1-(MyC*(1-MyK)+MyK))*255); int *G = (int)((1-(MyM*(1-MyK)+MyK))*255); int *B = (int)((1-(MyY*(1-MyK)+MyK))*255);if (*R<0) *R=0;if (*G<0) *G=0;if (*B<0) *B=0;if (*R>255) *R=255;if (*G>255) *G=255;if (*B>255) *B=255;return rgb;}//RGB to YUVint* rgb2yuv(int R,int G,int B){int yuv[3];yuv[0] = (int)(0.299*R+0.587*G+0.114*B); yuv[1] = (int)(-0.147*R-0.289*G+0.437*B); yuv[2] = (int)(0.615*R-0.515*G-0.1*B);return yuv;}//YUV to RGBint* yuv2rgb(int y,int u,int v){int rgb[3];int *R=&rgb[0];int *G=&rgb[1];int *B=&rgb[2];*R = (int)(y+1.14*v);*G = (int)(y-0.394*u-0.581*v);*B = (int)(y+2.028*u);if (*R<0) *R=0;if (*G<0) *G=0;if (*B<0) *B=0;if (*R>255) *R=255;if (*G>255) *G=255;if (*B>255) *B=255;return rgb;}//RGB to YIQint* rgb2yiq(int R,int G,int B){int yiq[3];yiq[0] = (int)(0.299*R+0.587*G+0.114*B); yiq[1] = (int)(0.596*R-0.274*G-0.322*B); yiq[2] = (int)(0.212*R-0.523*G+0.311*B); return yiq;}//YIQ to RGBint* yiq2rgb(float y,float i,float q){int rgb[3];int *R=&rgb[0];int *G=&rgb[1];int *B=&rgb[2];*R = (int)(y+0.956*i+0.621*q);*G = (int)(y-0.272*i-0.647*q);*B = (int)(y-1.105*i+1.702*q);if (*R<0) *R=0;if (*G<0) *G=0;if (*B<0) *B=0;if (*R>255) *R=255;if (*G>255) *G=255;if (*B>255) *B=255;return rgb;}//RGB to YCbCrint* rgb2ycbcr(int R, int G,int B){int ycbcr[3];ycbcr[0] = (int)(0.299*R+0.587*G+0.114*B);ycbcr[1] = (int)(-0.1687*R-0.3313*G+0.5*B+128); if (ycbcr[1] > 255) ycbcr[1] = 255;ycbcr[2] = (int)(0.5*R-0.4187*G-0.0813*B+128); if (ycbcr[2] > 255) ycbcr[2] = 255;return ycbcr;}//YCbCr to RGBint* ycbcr2rgb(int Y,int Cb,int Cr){int rgb[3];int *R=&rgb[0];int *G=&rgb[1];int *B=&rgb[2];*R = (int)(Y + 1.402 * (Cr -128));*G = (int)(Y - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128)); *B = (int)(Y + 1.772 * (Cb -128));if (*R > 255) *R = 255;if (*G > 255) *G = 255;if (*B > 255) *B = 255;if (*R < 0) *R =0;if (*G < 0) *G =0;if (*B < 0) *B =0;return rgb;}。
cv2.cvtcolor原理
1. cv2.cvtColor函数的功能cv2.cvtColor是OpenCV中的一个函数,用于将图像从一个颜色空间转换为另一个颜色空间。
通常情况下,图像的颜色空间包括灰度空间、RGB空间、HSV空间等。
cv2.cvtColor函数的功能是将图像从一个颜色空间转换为另一个颜色空间,从而可以对图像进行更多的处理和分析。
2. cv2.cvtColor的调用方式cv2.cvtColor函数的调用方式为:dst = cv2.cvtColor(src, code, dstCn)其中,src表示输入的图像,可以是任意通道数的图像;code表示颜色空间转换的类型,例如cv2.COLOR_BGR2GRAY表示将BGR颜色空间转为灰度空间,cv2.COLOR_BGR2HSV表示将BGR颜色空间转为HSV颜色空间等;dstCn表示输出图像的通道数,通常为0。
3. cv2.cvtColor的原理cv2.cvtColor函数的原理是基于颜色空间的数学模型进行变换。
以将BGR颜色空间转为灰度空间为例,cv2.cvtColor函数的原理如下:将BGR颜色空间的图像表示为三个通道的矩阵,分别为蓝色通道、绿色通道和红色通道;根据灰度空间的数学模型,利用加权平均的方式将这三个通道的值进行加权求和,得到灰度空间的图像表示。
4. cv2.cvtColor的应用cv2.cvtColor函数广泛应用于图像处理和计算机视觉领域。
在图像处理过程中,常常需要将图像转为灰度图像进行边缘检测、轮廓提取等操作;在计算机视觉领域,常常需要将彩色图像转为HSV颜色空间,以便进行颜色识别、目标跟踪等操作。
5. cv2.cvtColor函数的性能优化对于cv2.cvtColor函数的性能优化,可以从以下几个方面进行考虑:a. 使用合适的颜色空间转换类型,避免不必要的转换计算;b. 对于大规模图像处理,可以利用多线程或GPU加速技术,提高处理速度;c. 对于特定的应用场景,可以针对性地设计优化算法,提高函数执行效率。
数据图像处理实验报告
//对y方向进行快速付立叶变换
FFT(&TD[w * i], &FD[w * i], wp);
}
//保存变换结果
for(i = 0; i < h; i++)
{
for(j = 0; j < w; j++)
{
TD[i + h * j] = FD[j + w * i];
}
}
for(i = 0; i < w; i++)
YCBCR空间图像中Y是指亮度分量,Cb指蓝色色度分量,而Cr指红色色度分量。主要的子采样格式有YCbCr 4:2:0、YCbCr 4:2:2和YCbCr 4:4:4。
2、图像灰度变换与代码编写
a)在VC6.0环境下打开“医学图像处理系统”代码,进行编译调试,打开实验前准备的医学图像,进行灰度变换曲线调整如下图,观察图像进行灰度调整后的效果;
实验二 图像的FFT变换实验
一、实验目的:
1、练习Visual C++的一些FFT变换的算法实现方式;
2、编写Visual C++关于图像的FFT变换函数的编写和调试;
3、熟悉FFT变换在图像处理中的作用及功能;
4、熟悉FFT变换后的显示基本算法;
5、学会编写图像的FFT变换相关函数:
二、实验原理:
}
return TRUE;
}
3、灰度运算对于图像处理的作用,对照观察灰度变换前后的图像,了解各种灰度变换的作用
使图像加亮使图像减暗
提高图像对比度降低图像对比度
灰度级切片
四、思考题
1、要设计一个功能完善的图像灰度变换处理软件,需要在那些功能上进行完善和设计;
24位真彩色转换为8位灰度图_VC++_代码
24位真彩色转换为8位灰度图//////////////////////////////////////////////////////////////////////////#include <windows.h>BOOL BMP24to8(char *szSourceFile,char *szTargetFile);int main(int argc,char* argv[]){//调用这个函数直接把24位真彩色灰度化BOOL stat=BMP24to8("c://source.bmp","c://target.bmp");return 0;}BOOL BMP24to8(char *szSourceFile,char *szTargetFile){HANDLEhSourceFile=INV ALID_HANDLE_V ALUE,hTargetFile=INV ALID_HANDL E_V ALUE;DWORD dwSourceSize=0,dwTargetSize=0;PBYTE pSource=NULL,pTarget=NULL;hSourceFile=CreateFile(szSourceFile,GENERIC_READ,FILE_SHARE_REA D,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);if(hSourceFile==INV ALID_HANDLE_V ALUE)return FALSE;dwSourceSize=GetFileSize(hSourceFile,NULL);pSource=(PBYTE)VirtualAlloc(NULL,dwSourceSize,MEM_COMMIT,PAG E_READWRITE);//分配空间失败或者文件太小(BMP文件不可能小于54个字节)if(pSource==NULL||dwSourceSize<=54){CloseHandle(hSourceFile);return FALSE;}DWORD dwTemp=0;ReadFile(hSourceFile,pSource,dwSourceSize,&dwTemp,NULL);BITMAPFILEHEADER*pSourceFileHeader=(BITMAPFILEHEADER*)pSource;BITMAPINFOHEADER*pSourceInfoHeader=(BITMAPINFOHEADER*)(pSource+sizeof(BITMAPF ILEHEADER));//不是BMP文件或者不是24位真彩色if(pSourceFileHeader->bfType!=0x4d42||pSourceInfoHeader->biBitCount!=2 4){CloseHandle(hSourceFile);VirtualFree(pSource,NULL,MEM_RELEASE);return FALSE;}CloseHandle(hSourceFile);LONG nWidth=pSourceInfoHeader->biWidth;LONG nHeight=pSourceInfoHeader->biHeight;LONG nSourceWidth=nWidth*3;if(nSourceWidth%4)nSourceWidth=(nSourceWidth/4+1)*4;LONG nTargetWidth=nWidth;if(nTargetWidth%4)nTargetWidth=(nTargetWidth/4+1)*4;dwTargetSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEAD ER)+sizeof(RGBQUAD)*256+nHeight*nTargetWidth;pTarget=(PBYTE)VirtualAlloc(NULL,dwTargetSize,MEM_COMMIT,PAGE _READWRITE);memset(pTarget,0,dwTargetSize);if(pTarget==NULL){VirtualFree(pTarget,NULL,MEM_RELEASE);return FALSE;}BITMAPFILEHEADER *pTargetFileHeader=(BITMAPFILEHEADER *)pTarget;BITMAPINFOHEADER *pTargetInfoHeader = (BITMAPINFOHEADER *)(pTarget+sizeof(BITMAPFILEHEADER)); pTargetFileHeader->bfType=pSourceFileHeader->bfType; pTargetFileHeader->bfSize=dwTargetSize;pTargetFileHeader->bfReserved1=0;pTargetFileHeader->bfReserved2=0;pTargetFileHeader->bfOffBits=sizeof(BITMAPFILEHEADER) +sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256; pTargetInfoHeader->biBitCount=8;pTargetInfoHeader->biClrImportant=0;pTargetInfoHeader->biClrUsed=256;pTargetInfoHeader->biCompression=BI_RGB;pTargetInfoHeader->biHeight=pSourceInfoHeader->biHeight; pTargetInfoHeader->biPlanes=1;pTargetInfoHeader->biSize=sizeof(BITMAPINFOHEADER);pTargetInfoHeader->biSizeImage=nHeight*nTargetWidth;pTargetInfoHeader->biWidth=pSourceInfoHeader->biWidth;pTargetInfoHeader->biXPelsPerMeter=pSourceInfoHeader->biXPelsPerMeter ;pTargetInfoHeader->biYPelsPerMeter=pSourceInfoHeader->biYPelsPerMeter ;RGBQUAD *pRgb;for(int i=0;i<256;i++)//初始化8位灰度图的调色板信息{pRgb = (RGBQUAD*)(pTarget+sizeof(BITMAPFILEHEADER)+ sizeof(BITMAPINFOHEADER)+i*sizeof(RGBQUAD));pRgb->rgbBlue=i;pRgb->rgbGreen=i;pRgb->rgbRed=i;pRgb->rgbReserved=0;}for (int m=0;m<nHeight;m++)//转化真彩色图为灰度图{for(int n=0;n<nWidth;n++){pTarget[pTargetFileHeader->bfOffBits+m*nTargetWidth+n] =pSource[pSourceFileHeader->bfOffBits+m*nSourceWidth+n*3]*0.114+pSource[pSourceFileHeader->bfOffBits+m*nSourceWidth+n*3+1 ]*0.587+pSource[pSourceFileHeader->bfOffBits+m*nSourceWidth+n*3+2 ]*0.299;}}hTargetFile =CreateFile(szTargetFile,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);BOOL stat=WriteFile(hTargetFile,pTarget,dwTargetSize,&dwTemp,NULL);CloseHandle(hTargetFile);VirtualFree(pSource,NULL,MEM_RELEASE);VirtualFree(pTarget,NULL,MEM_RELEASE);return stat;}转化效果如下图在GDI+中将24位真彩色图转换为灰度图(原理、C#调用指针)在图像处理中,我们经常需要将真彩色图像转换为黑白图像。
基于c#图像灰度化、灰度反转、二值化的实现方法详解
基于c#图像灰度化、灰度反转、⼆值化的实现⽅法详解本篇⽂章是对c#图像灰度化、灰度反转、⼆值化的实现⽅法进⾏了详细的分析介绍,需要的朋友参考下图像灰度化:将彩⾊图像转化成为灰度图像的过程成为图像的灰度化处理。
彩⾊图像中的每个像素的颜⾊有R、G、B三个分量决定,⽽每个分量有255中值可取,这样⼀个像素点可以有1600 多万(255*255*255)的颜⾊的变化范围。
⽽灰度图像是R、G、B三个分量相同的⼀种特殊的彩⾊图像,其⼀个像素点的变化范围为255种,所以在数字图像处理种⼀般先将各种格式的图像转变成灰度图像以使后续的图像的计算量变得少⼀些。
灰度图像的描述与彩⾊图像⼀样仍然反映了整幅图像的整体和局部的⾊度和亮度等级的分布和特征。
图像的灰度化处理可⽤两种⽅法来实现。
第⼀种⽅法使求出每个像素点的R、G、B三个分量的平均值,然后将这个平均值赋予给这个像素的三个分量。
第⼆种⽅法是根据YUV的颜⾊空间中,Y的分量的物理意义是点的亮度,由该值反映亮度等级,根据RGB和YUV颜⾊空间的变化关系可建⽴亮度Y与R、G、B三个颜⾊分量的对应:Y=0.3R+0.59G+0.11B,以这个亮度值表达图像的灰度值。
///<summary>///图像灰度化///</summary>///<param name="bmp"></param>///<returns></returns>public static Bitmap ToGray(Bitmap bmp){for (int i = 0; i < bmp.Width; i++){for (int j = 0; j < bmp.Height; j++){//获取该点的像素的RGB的颜⾊Color color = bmp.GetPixel(i, j);//利⽤公式计算灰度值int gray = (int)(color.R * 0.3 + color.G * 0.59 + color.B * 0.11);Color newColor = Color.FromArgb(gray, gray, gray);bmp.SetPixel(i, j, newColor);}}return bmp;}灰度反转:把每个像素点的R、G、B三个分量的值0的设为255,255的设为0。
Qt中彩色图像转换为灰度图
Qt中彩⾊图像转换为灰度图近期在做⼏个图像处理相关的项⽬。
⾥⾯有⼀个操作就是须要先将彩⾊图像转换为灰度图像。
QImage 有⼀个convertToFormat⽅法。
最開始⼀直⽤这个函数来实现。
可是今天细致看了看,发现这个函数转换出的灰度图与原始图像的亮度似乎是有差别的。
⽐⽅说以下这副图像:⽤以下这三⾏代码转换:QImage image2 = image.convertToFormat(QImage::Format_Indexed8);image2.setColorCount(256);for(int i = 0; i < 256; i++){image2.setColor(i, qRgb(i, i, i));}得到的结果是这种:明显转换之后的图像要暗⼀些,对照度也差⾮常多。
说明这种⽅法是错误的。
事实上想想也能知道,convertToFormat 仅仅是选取了原始图像中出现最多的那些颜⾊,并以此⽣成了colorTable。
这个colorTable 的顺序与亮度事实上不⼀定具有线性关系。
我这样任意的转换从原理上就是说不通的。
后来花了点时间,⾃⼰写了个转换代码:QImage toGray( QImage image ){int height = image.height();int width = image.width();QImage ret(width, height, QImage::Format_Indexed8);ret.setColorCount(256);for(int i = 0; i < 256; i++){ret.setColor(i, qRgb(i, i, i));}switch(image.format()){case QImage::Format_Indexed8:for(int i = 0; i < height; i ++){const uchar *pSrc = (uchar *)image.constScanLine(i);uchar *pDest = (uchar *)ret.scanLine(i);memcpy(pDest, pSrc, width);}break;case QImage::Format_RGB32:case QImage::Format_ARGB32:case QImage::Format_ARGB32_Premultiplied:for(int i = 0; i < height; i ++){const QRgb *pSrc = (QRgb *)image.constScanLine(i);uchar *pDest = (uchar *)ret.scanLine(i);for( int j = 0; j < width; j ++){pDest[j] = qGray(pSrc[j]);}}break;}return ret;}利⽤这个代码的转换结果例如以下:这个的转换效果明显要好⾮常多。
数字图像处理2-真彩色,灰度图像,索引色图像等的相互转化
timg 真彩色timg1 灰度图像timg2 索引色图像(64色)timg3 二值图像(阈值为0.5)这里从网上找到了timg真彩色图像作为本次作业中进行数字处理的图像。
首先在ps中调整了图像模式,并进行了另存为,生成了timg1与timg2,又在MATLAB中将灰度图像转化为了二值图像timg3,其中阈值为0.5。
这一步操作的代码如下:A = imread('timg1.jpg');B = im2bw(A, 0.5);imshow(B)imwrite(B,'timg3.jpg');随后我们来对每个图像imread的返回值进行观察。
对于timg处理的程序如下:A = imread('timg.jpg');disp(A);whos Aimshow(A)由于disp显示数据过多,这里不放原始数据了。
其具体内容为3个数组,每个数组都是320*200的,分别代表图片中每个像素的rgb值。
而whos语句显示出的内容如下:Bytes Class Name Size192000 uint8A 200x320x3其中200*320*3说明图像像素为200*320而且为rgb格式,有3个矩阵。
192000为图片大小,而其rgb值是用unit8即8位无符号整数存储,0-255的值代表了某一点像素某一颜色分量的强度。
同理,若将上述程序中的timg改为timg1灰度图像,显示出来的矩阵则只有一个,大小仍为200*320但是每个点的数值则代表对应像素的灰度值。
whos语句显示出的内容如下:Name SizeBytes Class64000 u int8A 200x320由于灰度图像只需要存储灰度而不是rgb3个分量,其大小便没有最后的*3,因此其大小也只为timg的1/3。
对于索引图进行的操作与其他图像不同,由于其本身存储的是索引值,需要导入索引表才能还原原本的图像,因此程序如下:[IM, map] = imread('timg2.png','png');disp(IM);IMrgb(:,:,:) = ind2rgb(IM,map);whos IMrgbimshow(IMrgb)这里如果直接imshow原本图像的话会根据灰度图像的方式显示错误的图像,因此采用了一个ind2rgb函数通过之前导入的索引表和索引值矩阵将图像恢复为rgb图像矩阵。
C语言课程设计--图像处理
序号:学号: ********CHANG Z H OU U N I V E RSITY课程设计设计课程名称:C语言课程设计题目:数字图像处理—几何变换1学生姓名:***学院(系):******* 专业班级:***** 指导教师:*** 专业技术职务:*****设计时间:**** 年*月** 日**** 年* 月**目录1、系统的意义以及主要功能 (2)系统的意义 (2)图像的功能 (2)2、整个系统的功能结构图以及调用关系 (2)3、各个功能实现流程图 (2)彩色图像变成灰度图像 (2)几何变换之--旋转 (3)几何变换之--镜像 (3)4、调试运行,程序的界面以及输入数据,以及输出结果 (4)原图 (4)彩色图像变为灰度图像 (4)灰度图像水平镜像 (4)灰度图像垂直镜像 (5)彩色图像水平镜像 (5)彩色图像垂直镜像 (5)灰度图像旋转(48) (6)彩色图像旋转(90) (6)5、使用说明 (6)6、C语言源程序代码 (7)7、心得体会 (12)8、实习日志 (13)9、参考文献 (13)~ 1 ~1、系统的意义以及主要功能系统的意义目前图像处理的应用越来越广泛,已经渗透到工业、航空航天、军事等各领域,在国民经济中发挥越来越大的作用图像的功能读入一幅彩色的数字图像,完成一系列的几何运算,并输出每个运算的效果图1.将彩色图像变为灰度图像2.将灰度图像旋转任意角度;并对彩色图像进行相应旋转3.将灰度图像和彩色图像进行水平镜像和垂直镜像2、整个系统的功能结构图以及调用关系3几何变换之--旋转几何变换之--镜像~ 3 ~4、调试运行,程序的界面以及输入数据,以及输出结果原图彩色图像变为灰度图像灰度图像水平镜像~ 4 ~灰度图像垂直镜像彩色图像水平镜像彩色图像垂直镜像~ 5 ~灰度图像旋转(48)彩色图像旋转(90)5、使用说明编译链接后出现对话框和原始图片,按任意键即可在对话框中输入,根据对话框提示输入数字完成对应功能,出现功能图像按任意键摧毁窗口,即可继续输入完成对应功能。
c语言数字图像处理(四):灰度变换
c语⾔数字图像处理(四):灰度变换灰度变换灰度变换函数 s = T(r) 其中r为输⼊图像在(x, y)点处的灰度值,s为输出图像在(x, y)点处的灰度值灰度变换的作⽤上图所⽰的两幅T(s)函数的图像曲线,第⼀幅图可以增强图像对⽐度,第⼆幅图可以对图像进⾏⼆值化处理灰度变换函数反转函数1void reverse(short** in_array, short** out_array, long height, long width)2 {3for (int i = 0; i < height; i++){4for (int j = 0; j <width; j++)5 out_array[i][j] = GRAY_LEVELS - in_array[i][j];6 }7 }最简单的灰度变换函数,将图像中的每个像素点处的颜⾊值反转,对于8位灰度图⽚,⽤255减去原灰度值原图反转图对数变换s = clog(1 + r) c为常数,本次测试中c取101void logarithm(short** in_array, short** out_array, long height, long width) 2 {3for (int i = 0; i < height; i++){4for (int j = 0; j <width; j++)5 out_array[i][j] = (short)(10 * log((1 + in_array[i][j])));6 }7 }可以看出,对数变换降低了图像的对⽐度幂律(伽马)变换s = crγ其中 c 和γ为正常数其中γ<1时,降低对⽐度,γ>1时,提⾼对⽐度γ = 1.21void gamma(short** in_array, short** out_array, long height, long width)2 {3for (int i = 0; i < height; i++){4for (int j = 0; j <width; j++)5 out_array[i][j] = (short)pow(in_array[i][j], 1.2);6 }7 }直⽅图均衡化直⽅图为离散函数h(r k) = n k, 其中r k是第k级灰度值,n k是图像中h灰度为r k的像素个数现在给出上⾯⼏幅图像的直⽅图可以明显看出,对⽐度越⾼的图像,直⽅图的分布越均衡,因此直⽅图均衡化算法可以显著提⾼图像对⽐度直⽅图均衡化算法推导(需⼀定⾼等数学及概率论知识)算法实现1void calculate_histogram(long height, long width, short **image, unsigned long histogram[]) 2 {3short k;4for(int i=0; i < height; i++){5for(int j=0; j < width; j++){6 k = image[i][j];7 histogram[k] = histogram[k] + 1;8 }9 }10 }1112void histogram_equalization(short** in_array, short** out_array, long height, long width)13 {14 unsigned long sum, sum_of_h[GRAY_LEVELS];15double constant;16 unsigned long histogram[GRAY_LEVELS] = {};1718 calculate_histogram(height, width, in_array, histogram);19 sum = 0;20for(int i=0; i < GRAY_LEVELS; i++){21 sum = sum + histogram[i];22 sum_of_h[i] = sum;23 }2425 constant = (double)(GRAY_LEVELS)/(double)(height*width);26for(int i = 0, k = 0; i < height; i++){27for(int j = 0; j < width; j++){28 k = in_array[i][j];29 out_array[i][j] = sum_of_h[k] * constant;30 }31 }32 }。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
VC编程实现灰度图像与彩色图像的相互转换PhotoShop的图像处理功能很强,其中有一个功能是将灰度图像转换为彩色图像,数字图像处理中,也经常要遇到灰度图像与彩色图像相互转换的问题,如何自己解决这个问题,值得大家探讨,现将我解决这类问题的方法陈述如下:工程应用中经常要遇到需要把彩色图像到灰度图像的变换的问题,采集卡过来的图像为彩色图像,为加快处理速度,要把彩色图像转换为黑白图象,这个问题比较好解决,一般情况下彩色图像每个像素用三个字节表示,每个字节对应着R、G、B分量的亮度(红、绿、蓝),转换后的黑白图像的一个像素用一个字节表示该点的灰度值,它的值在0~255之间,数值越大,该点越白,既越亮,越小则越黑。
转换公式为Gray(i,j)=0.11*R(i,j)+0.59*G(i,j)+0.3*B(i,j),其中Gray(i,j)为转换后的黑白图像在(i,j)点处的灰度值,我们可以观察该式,其中绿色所占的比重最大,所以转换时可以直接使用G值作为转换后的灰度。
至于灰度图像转换为彩色图像,技术上称为灰度图像的伪彩色处理,这是一种视觉效果明显而技术又不是很复杂的图像增强技术。
灰度图像中,如果相邻像素点的灰度相差不大,但包含了丰富的信息的话,人眼则无法从图像中提取相应的信息,因为人眼分辨灰度的能力很差,一般只有几十个数量级,但是人眼对彩色信号的分辨率却很强,这样将黑白图像转换为彩色图像人眼可以提取更多的信息量。
在转换过程中,经常采用的技术是灰度级-彩色变换,意思就是对黑白图像上的每一个像素点,取得该点的灰度值并送入三个通道经过实施不同的变换,产生相应的R、G、B的亮度值,即所求彩色图像对应像素点的彩色值,具体变换公式很多,我采用的是最常用的一种,变换曲线图如下:上图中,三个图分别代表了三个变换通道,R、G、B指的是变换后对应点的R、G、B分量值,L指的是各个分量的最大值为255,G(x,y)为相应点的灰度值。
理论上就这些,下面是我用VC实现的源代码,图一为我的灰度位图,图二为伪彩色处理后的结果图。
我这个实现函数中是如何得到灰度位图的数据的就不多讲了,有兴趣的朋友可参考我在天极网上九月十号发表的《VC灰度位图处理》一文,那里应该讲的很清楚了。
需要读者注意的是彩色图像中每个象素中的三个字节分别代表的分量,第一个字节为B,第二个为G值、最后一个为R值,这个顺序不要搞错了。
代码实现如下:void CDibView::OnMenuchange() file://图像转换实现函数{// TODO: Add your command handler code hereHANDLE data1handle;LPBITMAPINFOHEADER lpBi;BITMAPINFO *m_pBMI;CDibDoc *pDoc=GetDocument();HDIB hdib;unsigned char *hData;unsigned char *data;hdib=pDoc->GetHDIB();//得到位图数据的句柄,其中包含图像信息头BeginWaitCursor();lpBi=(LPBITMAPINFOHEADER)GlobalLock((HGLOBAL)hdib);hData=(unsigned char*)FindDIBBits((LPSTR)lpBi);m_pBMI=new BITMAPINFO;//生成彩色图像的信息头m_pBMI->bmiHeader.biBitCount=24;m_pBMI->bmiHeader.biClrImportant=0;m_pBMI->bmiHeader.biClrUsed=0;m_pBMI->bmiHeader.biCompression=BI_RGB;m_pBMI->bmiHeader.biHeight=lpBi->biHeight;m_pBMI->bmiHeader.biWidth=lpBi->biWidth;m_pBMI->bmiHeader.biPlanes=1;m_pBMI->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);m_pBMI->bmiHeader.biXPelsPerMeter=0;m_pBMI->bmiHeader.biYPelsPerMeter=0;m_pBMI->bmiHeader.biSizeImage=WIDTHBYTES(lpBi->biWidth*8)*lpBi->biHeight*3;file://data=hData;int R,G,B,i,j;data1handle=GlobalAlloc(GMEM_SHARE,WIDTHBYTES(lpBi->biWidth*8)*lpBi->biHeight*3);file://生成存储彩色图象数据的缓冲区data=(unsigned char*)GlobalLock((HGLOBAL)data1handle);for(i=0;i biHeight;i++)//实现灰度到彩色变换for(j=0;jbiWidth*8);j++){if(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)<=64){R=0;G=(int)4*(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j));B=255;}if(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)>64&& *(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)<=128){R=0;G=255;B=(int)4*(128-*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j));}if(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)>128&& *(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)<=192){R=(int)4*(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)-128);G=255;B=0;}if(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)>192&& *(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)<=255){R=255;G=(int)4*(255-*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j));B=0;}file://将生成的R、G、B分量存入目标缓冲区*(data+i*WIDTHBYTES(lpBi->biWidth*8)*3+j*3)=B;*(data+i*WIDTHBYTES(lpBi->biWidth*8)*3+j*3+1)=G;*(data+i*WIDTHBYTES(lpBi->biWidth*8)*3+j*3+2)=R;}GlobalUnlock((HGLOBAL)hdib);GlobalUnlock(data1handle);EndWaitCursor();CClientDC pDC(this);file://显示真彩色图像StretchDIBits(pDC.GetSafeHdc(),0,0,lpBi->biWidth,lpBi->biHeight,0,0,lpBi->biWidth, lpBi->biHeight,data,m_pBMI,DIB_RGB_COLORS,SRCCOPY);delete m_pBMI;}VC++ 灰度位图处理图像处理技术已经渗透到人类生活的各个领域并得到越来越多的应用,图像处理所涉及的图像格式有很多种,如TIF、JEMP、BMP等等,工程应用中经常要处理256级的灰度BMP图像,如通过黑白采集卡采集得到的图像。
BMP灰度图像作为Windows环境下主要的图像格式之一,以其格式简单,适应性强而倍受欢迎。
在进行图像处理时,操作图像中的像素值就要得到图像阵列;经过处理后的图像的像素值存储起来;显示图像时要正确实现调色板,结合这些问题,文章针对性的给出了操作灰度BMP图像时的部分函数实现代码及注释。
一、BMP位图操作BMP位图包括位图文件头结构BITMAPFILEHEADER、位图信息头结构BITMAPINFOHEADER、位图颜色表RGBQUAD和位图像素数据四部分。
处理位图时要根据文件的这些结构得到位图文件大小、位图的宽、高、实现调色板、得到位图像素值等等。
对于256级灰度图像每个像素用8bit表示颜色的索引值,这里要注意的一点是在BMP位图中,位图的每行像素值要填充到一个四字节边界,即位图每行所占的存储长度为四字节的倍数,不足时将多余位用0填充。
在处理图像应用程序的文档类(CdibDoc.h)中声明如下宏及公有变量:#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)//计算图像每行象素所占的字节数目HANDLE m_hDIB;//存放位图数据的句柄CPalette* m_palDIB;//指向调色板Cpalette类的指针CSize m_sizeDoc; file://初始化视图的尺寸1、读取灰度BMP位图根据BMP位图文件的结构,操作BMP位图文件读入数据,重载了文挡类的OnOpenDocument函数如下:BOOL CDibDoc::OnOpenDocument(LPCTSTR lpszPathName){CFile file;CFileException fe;if (!file.Open(lpszPathName, CFile::modeRead | CFile::shareDenyWrite, &fe)){AfxMessageBox("文件打不开");return FALSE;}//打开文件DeleteContents();//删除文挡BeginWaitCursor();BITMAPFILEHEADER bmfHeader;//定义位图文件头结构DWORD dwBitsSize;HANDLE hDIB;LPSTR pDIB;BITMAPINFOHEADER *bmhdr;//指向位图信息头结构的指针dwBitsSize = file.GetLength();//得到文件长度if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) !=sizeof(bmfHeader))return FALSE;if (bmfHeader.bfType != 0x4d42) file://检查是否为BMP文件return FALSE;hDIB=(HANDLE) ::GlobalAlloc(GMEM_MOVEABLE |GMEM_ZEROINIT, dwBitsSize);file://申请缓冲区if (hDIB == 0){return FALSE;}pDIB = (LPSTR) ::GlobalLock((HGLOBAL)hDIB);file://得到申请的缓冲区的指针if (file.ReadHuge(pDIB, dwBitsSize - sizeof(BITMAPFILEHEADER)) !=dwBitsSize - sizeof(BITMAPFILEHEADER) ){::GlobalUnlock((HGLOBAL)hDIB);hDIB=NULL;return FALSE;}//读数据,包括位图信息、位图颜色表、图像像素的灰度值bmhdr=(BITMAPINFOHEADER*)pDIB;//为指向位图信息头结构的指针付值::GlobalUnlock((HGLOBAL)hDIB);if ((*bmhdr).biBitCount!=8) file://验证是否为8bit位图return FALSE;m_hDIB=hDIB;InitDIBData();file://自定义函数,根据读入的数据得到位图的宽、高、颜色表file:// 来得到初始化视的尺寸、生成调色板EndWaitCursor();SetPathName(lpszPathName);//设置存储路径SetModifiedFlag(FALSE); // 设置文件修改标志为FALSEreturn TRUE;}2、灰度位图数据的存储为了将图像处理后所得到的像素值保存起来,重载了文档类的OnSaveDocument函数,其具体实现如下:BOOL CDibDoc::OnSaveDocument(LPCTSTR lpszPathName){CFile file;CFileException fe;BITMAPFILEHEADER bmfHdr; // 位图文件头结构LPBITMAPINFOHEADER lpBI; file://指向位图信息结构的指针DWORD dwDIBSize;if (!file.Open(lpszPathName, CFile::modeCreate |CFile::modeReadWrite | CFile::shareExclusive, &fe)){AfxMessageBox("文件打不开");}//打开文件BOOL bSuccess = FALSE;BeginWaitCursor();lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) m_hDIB);if (lpBI == NULL)return FALSE;dwDIBSize = *(LPDWORD)lpBI + 256*sizeof(RGBQUAD);// Partial CalculationDWORD dwBmBitsSize;//BMP文件信息结构所占的字节数dwBmBitsSize=WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount)) *lpBI->biHei ght;// 存储时位图所有像素所占的总字节数dwDIBSize += dwBmBitsSize;lpBI->biSizeImage = dwBmBitsSize; // 位图所有像素所占的总字节数file://以下五句为文件头结构填充值bmfHdr.bfType =0x4d42; // 文件为"BMP"类型bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);//文件总长度bmfHdr.bfReserved1 = 0;bmfHdr.bfReserved2 = 0;bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize+ 256*sizeof(RGBQUAD);file://位图数据距问件头的偏移量file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER));//写文件头file.WriteHuge(lpBI, dwDIBSize);file://将位图信息(信息头结构、颜色表、像素数据)写入文件::GlobalUnlock((HGLOBAL) m_hDIB);EndWaitCursor();SetModifiedFlag(FALSE); // back to unmodifiedreturn TRUE;}二、调色板的操作灰度图像要正确显示,必须实现逻辑调色板和系统调色板,通过在主框架类中处理Windows定义的消息WM_QUERYNEWPALETTE 、WM_PALETTECHANGED及视图类中处理自定义消息WM_DOREA LIZE(该消息在主框架窗口定义如下:#define WM_REALIZEPAL (WM_USER+100))来实现调色板的操作。