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

相关文章

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

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第