Python OpenCV 和 PIL进行图像灰度化

彩色图像是指每个像素由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 = 03R + 059G + 011B
        # 通过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 = 03R + 059G + 011B
        # 通过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)

侵删

  • 5
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值