彩色图像是指每个像素由R、G、B分量构成的图像,其中R、G、B是由不同的灰度级来描述的。在一些情况下,由于彩色的图像颜色种类多,数据量较大,需要将彩色图像转化为灰度图像。
因为opencv的函数进行了一些更新,原有的一部分图像操作函数消失了,所以自己总结了一下灰度化的方式。
常用的彩色图像灰度化方法有以下三种:
(1)最大值法: 将彩色图像中的三分量亮度的最大值作为灰度图的灰度值。
(2)平均值法: 将彩色图像中的三分量亮度求平均得到一个灰度值。
(3)加权平均法: 根据重要性及其它指标,将三个分量以不同的权值进行加权平均。由于人眼对绿色的敏感最高,对蓝色敏感最低,因此,按下式对RGB三分量进行加权平均能得到较合理的灰度图像。
Y=0.3R+0.59G+0.11B
一.使用opencv进行灰度化
1.最大值法
代码实现:
import numpy as np
import cv2
# 最大值法 + cv2 进行灰度化
image = cv2.imread('car.jpg')
h, w = image.shape[:2]
gray_img = np.zeros((h, w), dtype=np.uint8) # 创建一个h行w列的二维list
for i in range(h):
for j in range(w):
gray_img[i, j] = max(image[i, j][0], image[i, j][1], image[i, j][2])
cv2.imshow("gray_image", gray_img)
cv2.imwrite("D:/Car_Identify/papers/gray_cv_max.jpg", gray_img)
cv2.waitKey(0)
2.平均值法
import numpy as np
import cv2
# 平均值法 + cv2 进行灰度化
image = cv2.imread('car.jpg')
h, w = image.shape[:2]
gray_img = np.zeros((h,w), dtype=np.uint8)
for i in range(h):
for j in range(w):
gray_img[i, j] = (int(image[i, j][0]) + int(image[i, j][1]) + int(image[i, j][2])) / 3
cv2.imshow("gray_image",gray_img)
cv2.imwrite("D:/Car_Identify/papers/gray_cv_avg.jpg",gray_img)
cv2.waitKey(0)
3.加权平均法
import numpy as np
import cv2
# 加权平均法 + cv2 进行灰度化
image = cv2.imread('car.jpg')
h, w = image.shape[:2]
gray_img = np.zeros((h, w), dtype=np.uint8)
for i in range(h):
for j in range(w):
# Y = 0.3R + 0.59G + 0.11B
# 通过cv格式打开的图片,像素格式为 BGR
gray_img[i, j] = 0.3 * image[i, j][2] + 0.11 * image[i, j][0] + 0.59 * image[i, j][1]
cv2.imshow("gray_image", gray_img)
cv2.imwrite("D:/Car_Identify/papers/gray_cv_weight_avg.jpg", gray_img)
cv2.waitKey(0)
二.使用PIL进行灰度化
1.最大值法
from PIL import Image, ImageDraw
# 最大值法 + PIL 进行灰度化
im01 = Image.open("car.jpg")
im02 = Image.new("L", im01.size)
pixel = im01.load() # cv2的图像读取后可以直接进行操作,而Image打开的图片需要加载
w, h = im01.size
after_table = [[0 for x in range(h)] for x in range(w)]
draw = ImageDraw.Draw(im02)
for i in range(im01.size[0]):
for j in range(im01.size[1]):
after_table[i][j] = max(pixel[i, j][0], pixel[i, j][1], pixel[i, j][2])
try:
for i in range(im01.size[0]):
for j in range(im01.size[1]):
draw.point((i, j), after_table[i][j]) # 通过表来描点画图
except Exception as e:
print(e)
del draw
im01.show()
im02.show()
im02.save('D:/Car_Identify/papers/gray_pil_max.jpg')
2.平均值法
from PIL import Image, ImageDraw
# 平均值法 + PIL 进行灰度化
im01 = Image.open("car.jpg")
im02 = Image.new("L", im01.size)
pixel = im01.load() # cv2的图像读取后可以直接进行操作,而Image打开的图片需要加载
w, h = im01.size
after_table = [[0 for x in range(h)] for x in range(w)]
draw = ImageDraw.Draw(im02)
for i in range(im01.size[0]):
for j in range(im01.size[1]):
after_table[i][j] = int((pixel[i, j][0] + pixel[i, j][1] + pixel[i, j][2]) / 3)
try:
for i in range(im01.size[0]):
for j in range(im01.size[1]):
draw.point((i, j), after_table[i][j]) # 通过表来描点画图
except Exception as e:
print(e)
del draw
im01.show()
im02.show()
im02.save('D:/Car_Identify/papers/gray_pil_avg.jpg')
3.加权平均法
from PIL import Image, ImageDraw
# 加权平均法 + PIL 进行灰度化
im01 = Image.open("car.jpg")
im02 = Image.new("L", im01.size)
pixel = im01.load() # cv2的图像读取后可以直接进行操作,而Image打开的图片需要加载
w, h = im01.size
after_table = [[0 for x in range(h)] for x in range(w)]
draw = ImageDraw.Draw(im02)
for i in range(im01.size[0]):
for j in range(im01.size[1]):
# Y = 0.3R + 0.59G + 0.11B
# 通过Image格式打开的图片,像素格式为 RGB
after_table[i][j] = int(0.3 * pixel[i, j][0] + 0.11 * pixel[i, j][2] + 0.59 * pixel[i, j][1])
try:
for i in range(im01.size[0]):
for j in range(im01.size[1]):
draw.point((i, j), after_table[i][j]) # 通过表来描点画图
except Exception as e:
print(e)
del draw
im01.show()
im02.show()
im02.save('D:/Car_Identify/papers/gray_pil_weight_avg.jpg')
三.结果
原图
最大值法
平均值法
加权平均法
四.参考文献
1.https://blog.csdn.net/L0_o_0f/article/details/80180111
2.https://baike.baidu.com/item/灰度化/3206969?fr=aladdin)
侵删