赞
踩
在R、G、B图像模型中,当R=G=B(三种颜色分量值相同时),则此时彩色表示一种灰度颜色,其中R=G=B的值叫做灰度值,在灰度图像中,灰度值也可以称为亮度值。灰度值范围0-255
对于一副彩色图像来说,灰度化一般有四种常用方法,分别为分量法
最大值法
平均值法
加权平均法
。
该方法最为简单,即在R、G、B三种颜色分量中,任意选取一种颜色作为灰度值
该方法是先找出每个像素R、G、B三种颜色分量的值,然后找到值最大的那个颜色,然后以此最大值作为灰度值
f
(
x
,
y
)
=
M
a
x
{
R
(
x
,
y
)
,
G
(
x
,
y
)
,
B
(
x
,
y
)
}
f(x,y)=Max\left \{ R(x,y),G(x,y),B(x,y)\right \}
f(x,y)=Max{R(x,y),G(x,y),B(x,y)}
该方法是先找到像素的R、G、B三种颜色的分量值,最后置灰度值为三个分量值的平均值即可。
f
(
x
,
y
)
=
R
(
x
,
y
)
+
G
(
x
,
y
)
+
B
(
x
,
y
)
3
f(x,y)=\frac{R(x,y)+G(x,y)+B(x,y)}{3}
f(x,y)=3R(x,y)+G(x,y)+B(x,y)
因为人眼对每种颜色的敏感度不同,其中人眼对绿色敏感度最高,蓝色敏感度最低,所以我们可以使用加权平均的方法来求灰度值,公式如下
f ( x , y ) = a i R ( i , j ) + b i G ( i , j ) + c i B ( i , j ) f(x,y)=a_iR(i,j)+b_iG(i,j)+c_iB(i,j) f(x,y)=aiR(i,j)+biG(i,j)+ciB(i,j)
因为在图像灰度化的过程都是要对图像进行扫描,至于值的确定,我们可以单独用一个函数来得到,所以把扫描过程独立起来,值的获取独立起来。我们单独使用一个Values()
方法来得到我们所需要的灰度值,参数就是一个含R、G、B值的列表
方法整体很简单,就几行代码。只要把各种计算灰度值的公式用上就行了。剩下的全交给扫描函数就行了
下面就是一个用来处理BMP图像文件的类,将前一节文章里的代码集成起来,可以用来读取8位伪彩色图、24位真彩色图
class BmpManager: def __init__(self,fileName): self.f_size=None self.f_width=None self.f_height=None self.f_ofset=None self.f_bitcount=None self.colorTab=None self.Img=None def Parse(self,fileName): f=open(fileName,'rb') file_type=str(f.read(2),encoding='utf-8') assert file_type=='BM',"文件类型错误" file_size_byte = f.read(4) # 这个可以用来读取文件的大小 需要读取4个字节 f.seek(f.tell() + 4) # 跳过中间无用的四个字节 file_ofset_byte = f.read(4) # 读取位图数据的偏移量 f.seek(f.tell() + 4) # 跳过无用的两个字节 file_wide_byte = f.read(4) # 读取宽度字节 file_height_byte = f.read(4) # 读取高度字节 f.seek(f.tell() + 2) ## 跳过中间无用的两个字节 file_bitcount_byte = f.read(4) # 得到每个像素占位大小 #下面就是将读取的字节转换成指定的类型 self.f_size,=struct.unpack('l',file_size_byte) self.f_ofset,=struct.unpack('l',file_ofset_byte) self.f_width,=struct.unpack('l',file_wide_byte) self.f_height,=struct.unpack('l',file_height_byte) self.f_bitcount,=struct.unpack('i',file_bitcount_byte) # 判断是否有颜色表 if self.f_ofset==1078: self.__256Image__(fileName)#处理伪彩色图像 else: self.__24BImage(fileName) #处理真彩色图像 def __256Image__(self,f_name): '然后来读取颜色表' f=open(f_name,'rb') self.colorTab = np.array([],dtype=int) f.seek(54) # 跳过文件信息头和位图信息头 for i in range(0, 256): b = struct.unpack('B', f.read(1))[0] g = struct.unpack('B', f.read(1))[0] r = struct.unpack('B', f.read(1))[0] alpha = struct.unpack('B', f.read(1))[0] self.colorTab=np.append(self.colorTab,np.array([r,g,b,255])) self.colorTab=self.colorTab.reshape(256,4) '下面部分用来读取BMP位图数据区域,将数据存入numpy数组' # 首先对文件指针进行偏移 f.seek(self.f_ofset) # 因为图像是8位伪彩色图像,所以一个像素点占一个字节,即8位 img = np.empty(shape=[self.f_height, self.f_width, 4], dtype=int) cout = 0 for y in range(0, self.f_height): for x in range(0, self.f_width): cout = cout + 1 index = struct.unpack('B', f.read(1))[0] img[self.f_height - y - 1, x] = self.colorTab[index] while cout % 4 != 0: f.read(1) cout = cout + 1 self.Img=img def __24BImage(self,f_name): f=open(f_name,'rb') f.seek(self.f_ofset) img=np.empty(shape=[self.f_height,self.f_width,3],dtype=int) cout=0 for y in range(0,self.f_height): for x in range(0,self.f_width): BYTES=f.read(3) x1,x2,x3=struct.unpack('BBB',BYTES) cout=cout+3 img[self.f_height - y - 1, x]=np.array([x3,x2,x1]) while cout%4!=0: cout=cout+1 f.read(1) self.Img=img def getHeight(self): return self.f_height def getWidth(self): return self.f_width def getImage(self): return self.Img def getSize(self): return self.f_size def grayScale(self,method='AVG'): #下面对图像进行扫描 for y in range(0,self.f_height): for x in range(0,self.f_width): value=self.Values(method,self.Img[y][x]) self.Img[y][x]=np.array([value,value,value]) def Values(self,methods,v): if methods=='AVG': return np.average(v) if methods=='R': return v[0] if methods=='G': return v[1] if methods=='B': return v[2] if methods=='Max': return np.max(v) if methods=='WAvg': return 0.3*v[0]+0.59*v[1]+0.11*v[2]
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。