RGB色转为灰度色算法-img2ascii_char

2024-09-06 03:32

本文主要是介绍RGB色转为灰度色算法-img2ascii_char,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、基础
  对于彩色转灰度,有一个很著名的心理学公式:
Gray = R0.299 + G0.587 + B0.114
二、整数算法
  而实际应用时,希望避免低速的浮点运算,所以需要整数算法。
  注意到系数都是3位精度的没有,我们可以将它们缩放1000倍来实现整数运算算法:
Gray = (R
299 + G587 + B114 + 500) / 1000
  RGB一般是8位精度,现在缩放1000倍,所以上面的运算是32位整型的运算。注意后面那个除法是整数除法,所以需要加上500来实现四舍五入。
  就是由于该算法需要32位运算,所以该公式的另一个变种很流行:
Gray = (R30 + G59 + B11 + 50) / 100
  但是,虽说上一个公式是32位整数运算,但是根据80x86体系的整数乘除指令的特点,是可以用16位整数乘除指令来运算的。而且现在32位早普及了(AMD64都出来了),所以推荐使用上一个公式。
三、整数移位算法
  上面的整数算法已经很快了,但是有一点仍制约速度,就是最后的那个除法。移位比除法快多了,所以可以将系数缩放成 2的整数幂。
  习惯上使用16位精度,2的16次幂是65536,所以这样计算系数:
0.299 * 65536 = 19595.264 ≈ 19595
0.587 * 65536 + (0.264) = 38469.632 + 0.264 = 38469.896 ≈ 38469
0.114 * 65536 + (0.896) = 7471.104 + 0.896 = 7472
  可能很多人看见了,我所使用的舍入方式不是四舍五入。四舍五入会有较大的误差,应该将以前的计算结果的误差一起计算进去,舍入方式是去尾法:
  写成表达式是:
Gray = (R
19595 + G38469 + B7472) >> 16
  2至20位精度的系数:
Gray = (R1 + G2 + B1) >> 2
Gray = (R
2 + G5 + B1) >> 3
Gray = (R4 + G10 + B2) >> 4
Gray = (R
9 + G19 + B4) >> 5
Gray = (R19 + G37 + B8) >> 6
Gray = (R
38 + G75 + B15) >> 7
Gray = (R76 + G150 + B30) >> 8
Gray = (R
153 + G300 + B59) >> 9
Gray = (R306 + G601 + B117) >> 10
Gray = (R
612 + G1202 + B234) >> 11
Gray = (R1224 + G2405 + B467) >> 12
Gray = (R
2449 + G4809 + B934) >> 13
Gray = (R4898 + G9618 + B1868) >> 14
Gray = (R
9797 + G19235 + B3736) >> 15
Gray = (R19595 + G38469 + B7472) >> 16
Gray = (R
39190 + G76939 + B14943) >> 17
Gray = (R78381 + G153878 + B29885) >> 18
Gray = (R
156762 + G307757 + B59769) >> 19
Gray = (R313524 + G615514 + B119538) >> 20
  仔细观察上面的表格,这些精度实际上是一样的:3与4、7与8、10与11、13与14、19与20
  所以16位运算下最好的计算公式是使用7位精度,比先前那个系数缩放100倍的精度高,而且速度快:
Gray = (R
38 + G75 + B15) >> 7
  其实最有意思的还是那个2位精度的,完全可以移位优化:
Gray = (R1 + G2 + B*1) >> 2


from PIL import Imageclass Parse():def __init__(self, path, width=160, height=40):self._path = pathself._width = widthself._height = heightself._text = ""def to_ascii_char(self, r, g, b):""" 将 RGB 转为灰度值,并且返回该灰度值对应的字符标记 """# 存储用于显示图片的字符种类。list 的最后一个元素是空格,表示将使用空格来代替原图片中灰度值最高的像素点# (在灰度图像中,灰度值最高为 255,代表白色,最低为 0,代表黑色)。ascii_char = list(r"$kB%8&WM#*oa&**@qwmZO0QLCJUYXzcvun<rjft/\|()1{}[]?-_+~<>i!lI;:,\ ^`'. ")# RGB 转为灰度值计算公式gray = int((19595 * r + 38469 * g + 7474 * b) >> 16)# ascii_char 中的一个字符所能表示的灰度值区间unit = 256.0 / len(ascii_char)return ascii_char[int(gray / unit)] #(gray/256.0)*len(ascii_char)# (gray/256.0)是ascii_char字符下标的比例系数def output(self):""" 输出结果 """image = Image.open(self._path)image = image.resize((self._width, self._height), Image.NEAREST)for h in range(self._height):for w in range(self._width):# [:3]表示取前三个值 R G Bself._text += self.to_ascii_char(*image.getpixel((w, h))[:3])self._text += '\n'return self._textdef save(self):""" 保存文件到本地 """with open("parse.txt", 'w') as f:f.write(self._text)if __name__ == "__main__":parse = Parse("images\we.jpg")print("\n>> 你会挽着我的衣袖 我会把手揣进裤兜")print(parse.output())

这篇关于RGB色转为灰度色算法-img2ascii_char的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1140874

相关文章

openCV中KNN算法的实现

《openCV中KNN算法的实现》KNN算法是一种简单且常用的分类算法,本文主要介绍了openCV中KNN算法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录KNN算法流程使用OpenCV实现KNNOpenCV 是一个开源的跨平台计算机视觉库,它提供了各

Python获取C++中返回的char*字段的两种思路

《Python获取C++中返回的char*字段的两种思路》有时候需要获取C++函数中返回来的不定长的char*字符串,本文小编为大家找到了两种解决问题的思路,感兴趣的小伙伴可以跟随小编一起学习一下... 有时候需要获取C++函数中返回来的不定长的char*字符串,目前我找到两种解决问题的思路,具体实现如下:

springboot+dubbo实现时间轮算法

《springboot+dubbo实现时间轮算法》时间轮是一种高效利用线程资源进行批量化调度的算法,本文主要介绍了springboot+dubbo实现时间轮算法,文中通过示例代码介绍的非常详细,对大家... 目录前言一、参数说明二、具体实现1、HashedwheelTimer2、createWheel3、n

SpringBoot实现MD5加盐算法的示例代码

《SpringBoot实现MD5加盐算法的示例代码》加盐算法是一种用于增强密码安全性的技术,本文主要介绍了SpringBoot实现MD5加盐算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习... 目录一、什么是加盐算法二、如何实现加盐算法2.1 加盐算法代码实现2.2 注册页面中进行密码加盐2.

Java时间轮调度算法的代码实现

《Java时间轮调度算法的代码实现》时间轮是一种高效的定时调度算法,主要用于管理延时任务或周期性任务,它通过一个环形数组(时间轮)和指针来实现,将大量定时任务分摊到固定的时间槽中,极大地降低了时间复杂... 目录1、简述2、时间轮的原理3. 时间轮的实现步骤3.1 定义时间槽3.2 定义时间轮3.3 使用时

Nginx实现前端灰度发布

《Nginx实现前端灰度发布》灰度发布是一种重要的策略,它允许我们在不影响所有用户的情况下,逐步推出新功能或更新,通过灰度发布,我们可以测试新版本的稳定性和性能,下面就来介绍一下前端灰度发布的使用,感... 目录前言一、基于权重的流量分配二、基于 Cookie 的分流三、基于请求头的分流四、基于请求参数的分

如何通过Golang的container/list实现LRU缓存算法

《如何通过Golang的container/list实现LRU缓存算法》文章介绍了Go语言中container/list包实现的双向链表,并探讨了如何使用链表实现LRU缓存,LRU缓存通过维护一个双向... 目录力扣:146. LRU 缓存主要结构 List 和 Element常用方法1. 初始化链表2.

Java中将异步调用转为同步的五种实现方法

《Java中将异步调用转为同步的五种实现方法》本文介绍了将异步调用转为同步阻塞模式的五种方法:wait/notify、ReentrantLock+Condition、Future、CountDownL... 目录异步与同步的核心区别方法一:使用wait/notify + synchronized代码示例关键

golang字符串匹配算法解读

《golang字符串匹配算法解读》文章介绍了字符串匹配算法的原理,特别是Knuth-Morris-Pratt(KMP)算法,该算法通过构建模式串的前缀表来减少匹配时的不必要的字符比较,从而提高效率,在... 目录简介KMP实现代码总结简介字符串匹配算法主要用于在一个较长的文本串中查找一个较短的字符串(称为

通俗易懂的Java常见限流算法具体实现

《通俗易懂的Java常见限流算法具体实现》:本文主要介绍Java常见限流算法具体实现的相关资料,包括漏桶算法、令牌桶算法、Nginx限流和Redis+Lua限流的实现原理和具体步骤,并比较了它们的... 目录一、漏桶算法1.漏桶算法的思想和原理2.具体实现二、令牌桶算法1.令牌桶算法流程:2.具体实现2.1