一、介绍
大部分的彩色图像都是采用RGB颜色模式,处理图像的时候,要分别对RGB三种分量进行处理,实际上RGB并不能反映图像的形态特征,只是从光学的原理上进行颜色的调配。 现在有很多其他的颜色模式,例如HSI模式,HSI是由色调,饱和度,亮度三个分量来表示颜色。HSI比RGB更符合人的视觉特性。
但是HSI也是三通道,真正反映图像特征的变量是I,其他都是色彩的反映。
所以我们经常要把图像弄成8位的灰度值图像直接进行处理,可以通过直方图,灰度变化,还有正交变换之类的进行处理。甚至经常把图像分割之后变成二值图像处理。 灰度化,在RGB模型中,如果R=G=B时,则彩色表示一种灰度颜色,其中R=G=B的值叫灰度值,因此,灰度图像每个像素只需一个字节存放灰度值(又称强度值、亮度值),灰度范围为0-255。
一般有分量法、最大值法、平均值法、加权平均法四种方法对彩色图像进行灰度化。
1. 分量法
将彩色图像中的三分量的亮度作为三个灰度图像的灰度值,可根据应用需要选取一种灰度图像。
f1(i,j)=R(i,j)f2(i,j)=G(i,j)f3(i,j)=B(i,j)
其中fk(i,j)(k=1,2,3)为转换后的灰度图像在(i,j)处的灰度值。
2. 最大值法
将彩色图像中的三分量亮度的最大值作为灰度图的灰度值。
f(i,j)=max(R(i,j),G(i,j),B(i,j))
3. 平均值法
将彩色图像中的三分量亮度求平均得到一个灰度值。
f(i,j)=(R(i,j)+G(i,j)+B(i,j)) /3
4.加权平均法
根据重要性及其它指标,将三个分量以不同的权值进行加权平均。由于人眼对绿色的敏感最高,对蓝色敏感最低,因此,按下式对RGB三分量进行加权平均能得到较合理的灰度图像。
f(i,j)=0.30R(i,j)+0.59G(i,j)+0.11B(i,j)
(摘自百度百科)
灰度化与二值化不同,二值化是每个像素值设置为0或255.
二、使用OpenCV 灰度化
# -*- coding: utf-8 -*- import cv2 fn = "test.jpg" if __name__ == '__main__': print('loading %s' % fn) img = cv2.imread(fn) sp = img.shape print(sp) # 获取图像大小 sz1 = sp[0] sz2 = sp[1] print('width:%d\nheight:%d' % (sz2, sz1)) # 复制并转换为灰度化图像并显示 myimg1 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) cv2.imshow('myimg1',myimg1) cv2.waitKey() cv2.destroyAllWindows()
三、使用PIL库实现灰度化
# -*- coding: utf-8 -*- from PIL import Image import matplotlib.pyplot as plt fn = "test.jpg" def showimg(img, isgray=False): plt.axis("off") if isgray == True: plt.imshow(img, cmap='gray') else: plt.imshow(img) plt.show() if __name__ == '__main__': image = Image.open(fn) im_gray = image.convert('L') showimg(im_gray, True)
三、使用numpy运算实现灰度化
1. 使用浮点算法 Gray=R0.3+G0.59+B*0.11
# -*- coding: utf-8 -*- from PIL import Image import matplotlib.pyplot as plt import numpy as np fn = "test.jpg" def showimg(img, isgray=False): plt.axis("off") if isgray: plt.imshow(img, cmap='gray') else: plt.imshow(img) plt.show() if __name__ == '__main__': image = Image.open(fn) im = np.array(image) im[:, :, 0] = im[:, :, 0] * 0.3 im[:, :, 1] = im[:, :, 1] * 0.59 im[:, :, 2] = im[:, :, 2] * 0.11 im = np.sum(im, axis=2) showimg(Image.fromarray(im), True)
2. 使用整数算法 Gray=(R30+G59+B*11)/100
# -*- coding: utf-8 -*-
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
fn = "test.jpg"
def showimg(img, isgray=False):
plt.axis("off")
if isgray:
plt.imshow(img, cmap='gray')
else:
plt.imshow(img)
plt.show()
if __name__ == '__main__':
image = Image.open(fn)
im = np.array(image, dtype=np.float32)
im[..., 0] = im[..., 0] * 30.0
im[..., 1] = im[..., 1] * 59.0
im[..., 2] = im[..., 2] * 11.0
im = np.sum(im, axis=2)
im[..., :] = im[..., :] / 100.0
showimg(Image.fromarray(im), True)
3. 使用平均值法
im = np.array(image, dtype=np.float32) im = np.sum(im, axis=2) im[...,:] = im[...,:]/3.0
4. 使用移位法
# -*- coding: utf-8 -*-
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
fn = "test.jpg"
def showimg(img, isgray=False):
plt.axis("off")
if isgray:
plt.imshow(img, cmap='gray')
else:
plt.imshow(img)
plt.show()
if __name__ == '__main__':
image = Image.open(fn)
im = np.array(image, dtype=np.int32)
im[..., 0] = im[..., 0] * 28.0
im[..., 1] = im[..., 1] * 151.0
im[..., 2] = im[..., 2] * 76.0
im = np.sum(im, axis=2)
arr = [np.right_shift(y.item(), 8) for x in im for y in x]
arr = np.array(arr)
arr.resize(im.shape)
showimg(Image.fromarray(arr), True)
5. 单通道法(只取绿色通道)
# -*- coding: utf-8 -*- from PIL import Image import matplotlib.pyplot as plt import numpy as np fn = "test.jpg" def showimg(img, isgray=False): plt.axis("off") if isgray: plt.imshow(img, cmap='gray') else: plt.imshow(img) plt.show() if __name__ == '__main__': image = Image.open(fn) im = np.array(image, dtype=np.int32) im[..., 0] = 0 im[..., 2] = 0 im = np.sum(im, axis=2) showimg(Image.fromarray(im), True)
本文暂时没有评论,来添加一个吧(●'◡'●)