前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >彩色图变黑白图

彩色图变黑白图

作者头像
不可言诉的深渊
发布2020-04-08 14:37:11
1.2K0
发布2020-04-08 14:37:11
举报

就在昨天,几乎所有网站都从彩色页面变成黑白页面,虽然一行 CSS 就可以解决这个问题,但是彩色页面(彩色图)变黑白页面(黑白图)有很多方法,主要有三种:最大值法、平均值法、加权平均值法,下面我就主要讲解这三种算法的具体逻辑。

图片数据的格式

在进行图像变换之前,先来简单介绍一下图片在计算机中的数据格式,图像在计算机中的数据格式有很多,详见下表:

格式

说明

1

位图,像素 1 位

L

灰度图,像素 8 位

I

像素 int32

F

像素 float32

P

8 位,映射为其他模式

RGB

真色彩,3 通道

RGBA

4 通道,加透明

CMYK

印刷,4 通道

YCbCr

亮色分离,3 通道

一般情况下,彩色图在计算机中是通过 RGB 格式来进行存储的,所以今天彩色图变黑白图这个问题就转化为 RGB 格式的图片转 L 格式的图片,在转化之前先来详细说一下这两个格式。

RGB 格式

RGB 格式的 R 表示 Red,G 表示 Green,B 表示 Blue,也就是光的三原色红绿蓝,这三个元素的数据范围都是 0 到 255 的整数,也就是 8 位无符号整数的表示范围,占用一个字节。上面说的只是一个像素点的数据格式,并不是整个 RGB 格式的图片的数据格式,考虑到一张图片有长度有宽度有很多个像素,那么直接把很多像素构成一个二维数组就完事了,又因为一个像素对应着三个元素,这三个元素也可以放在一个数组,所以 RGB 格式的图片在计算机中的存储格式是一个三维数组,其形状为(长, 宽, 3)。

L 格式

L 格式就是灰度格式,每个像素对应一个灰度值,灰度值取值范围依旧是 0 到 255,所以灰度格式的图片在计算机中的存储格式是一个二维数组,其形状为(长, 宽)。

RGB 格式 转 L 格式

RGB 格式转 L 格式在开头就说了有三种方法,分别是:最大值法、平均值法、加权平均值法。在讲解和实现这三个算法之前先给大家看一下我所使用的图片。

最大值法

先来看一下最大值法,最大值法顾名思义就是取 RGB 格式的三个元素当中的最大值作为灰度值,代码如下:

代码语言:javascript
复制
 from PIL import Image
 import numpy as np
 image_array = np.array(Image.open('row_image.jpg'))
 # max,average,weighted_average
 image_array = np.array(image_array.max(axis=2), dtype='uint8')
 image = Image.fromarray(image_array)
 image.save('converted_image.jpg')

下面看一下转换之后的图片,如图所示。

平均值法

平均值法就是把 RGB 三个元素的值取平均值作为对应像素的灰度值,代码如下:

代码语言:javascript
复制
 from PIL import Image
 import numpy as np
 image_array = np.array(Image.open('row_image.jpg'))
 # max,average,weighted_average
 image_array = np.array(image_array.sum(axis=2)//3, dtype='uint8')
 image = Image.fromarray(image_array)
 image.save('converted_image.jpg')

下面看一下转换之后的图片,如图所示。

加权平均值法

加权平均值法就是给 RGB 三个元素给三个对应的权重,这三个权重暂且记作 WR、WG 和 WB,相乘相加得到灰度图的像素对应取值。在这里考虑到人眼对绿色敏感度最高,红色次之,蓝色最低,所以只要让 WG > WR > WB,即使如此还是有很多取值,目前效果最好的权重参数的值如下表所示。

权重

WR

0.299

WG

0.587

WB

0.114

其对应的代码如下:

代码语言:javascript
复制
 from PIL import Image
 import numpy as np
 image_array = np.array(Image.open('row_image.jpg'))
 # max,average,weighted_average
 a = np.zeros((image_array.shape[0], image_array.shape[1]))
 for i in range(image_array.shape[0]):
     for j in range(image_array.shape[1]):
         a[i, j] = image_array[i, j]@np.array([0.299, 0.587, 0.114])
 a = np.array(a, dtype='uint8')
 image = Image.fromarray(a)
 image.save('converted_image.jpg')

转换后的图片如图所示。

其实加权平均值法在 PIL 中有封装好的,对应逻辑和我自己实现的一模一样,权重都是一样的,调用过程如下:

代码语言:javascript
复制
 from PIL import Image
 image = Image.open('row_image.jpg')
 image = image.convert('L')
 image.save('converted_image.jpg')

结果和上面的一样,我就不给大家看了。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python机器学习算法说书人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档