本站消息

站长简介/公众号


站长简介:逗比程序员,理工宅男,前每日优鲜python全栈开发工程师,利用周末时间开发出本站,欢迎关注我的微信公众号:幽默盒子,一个专注于搞笑,分享快乐的公众号

  价值13000svip视频教程,python大神匠心打造,零基础python开发工程师视频教程全套,基础+进阶+项目实战,包含课件和源码

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2020-08(26)

2020-09(57)

Python:字符画.2021-06-03

发布于2021-06-12 12:25     阅读(911)     评论(0)     点赞(1)     收藏(0)



1.方案一

  1. # -*- coding:utf-8 -*-
  2. from PIL import Image
  3. IMG = 'd516871d0f6596ad0a85ade5d1af12f0.jpeg'
  4. WIDTH = 160
  5. HEIGHT = 90
  6. #图片来源,长宽设定
  7. ascii_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. ")
  8. # 灰度值:指黑白图像中点的颜色深度,范围一般从0到255,白色为255,黑色为0,故黑白图片也称灰度图像
  9. # 将256灰度映射到70个字符上
  10. def get_char(r, g, b, alpha=256): # alpha透明度
  11. if alpha == 0:
  12. return ' '
  13. length = len(ascii_char)
  14. gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b) # 将像素的RGB值转换成灰度值
  15. unit = (256.0 + 1) / length
  16. return ascii_char[int(gray / unit)]
  17. # 不同的字符代表不同的灰度值,字符的种类和数量可以根据自己需要的效果进行调整,
  18. # 最好从前往后可以看到明显的变化,最后一个字符为空格符最佳
  19. # 通过灰度来区分色块
  20. if __name__ == '__main__':
  21. im = Image.open(IMG)
  22. im = im.resize((WIDTH, HEIGHT), Image.NEAREST)
  23. txt = ""
  24. for i in range(HEIGHT):
  25. for j in range(WIDTH):
  26. txt += get_char(*im.getpixel((j, i)))
  27. txt += '\n'
  28. print(txt)
  29. # 写入文件
  30. with open("output.txt", 'w') as f:
  31. f.write(txt)

resource

run

2.方案二

  1. """
  2. 利用 聚类 将像素信息聚为3或5类,颜色最深的一类用数字密集地表示,
  3. 阴影的一类用“-”横杠表示,明亮部分空白表示。
  4. ---------------------------------
  5. frame:需要传入的图片信息。
  6. 可以是opencv的cv2.imread()得到的数组,也可以是Pillow的Image.read()。
  7. K:聚类数量,推荐的K为3或5。根据经验,3或5时可以较为优秀地处理很多图像了。
  8. 若默认的K=5无法很好地表现原图,请修改为3进行尝试。
  9. 若依然无法很好地表现原图,请换图尝试。 ( -_-|| )
  10. ---------------------------------
  11. 聚类数目理论可以取大于等于3的任意整数。
  12. 但水平有限,无法自动判断当生成的字符画可以更好地表现原图细节时,
  13. “黑暗”、“阴影”、”明亮“之间边界在哪。
  14. 所以说由于无法有效利用更大的聚类数量,那么便先简单地限制聚类数目为3和5。
  15. """
  16. import random
  17. import numpy as np
  18. import cv2
  19. def img2strimg(frame, K=5):
  20. if type(frame) != np.ndarray:
  21. frame = np.array(frame)
  22. height, width, *_ = frame.shape # 有时返回两个值,有时三个值
  23. frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
  24. frame_array = np.float32(frame_gray.reshape(-1))
  25. # 设置相关参数。
  26. criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
  27. flags = cv2.KMEANS_RANDOM_CENTERS
  28. # 得到labels(类别)、centroids(矩心)。
  29. # 如第一行6个像素labels=[0,2,2,1,2,0],则意味着6个像素分别对应着 第1个矩心、第3个矩心、第3231个矩心。
  30. compactness, labels, centroids = cv2.kmeans(frame_array, K, None, criteria, 10, flags)
  31. centroids = np.uint8(centroids)
  32. # labels的数个矩心以随机顺序排列,所以需要简单处理矩心.
  33. centroids = centroids.flatten()
  34. centroids_sorted = sorted(centroids)
  35. # 获得不同centroids的明暗程度,0最暗
  36. centroids_index = np.array([centroids_sorted.index(value) for value in centroids])
  37. bright = [abs((3 * i - 2 * K) / (3 * K)) for i in range(1, 1 + K)]
  38. bright_bound = bright.index(np.min(bright))
  39. shadow = [abs((3 * i - K) / (3 * K)) for i in range(1, 1 + K)]
  40. shadow_bound = shadow.index(np.min(shadow))
  41. labels = labels.flatten()
  42. # 将labels转变为实际的明暗程度列表,0最暗。
  43. labels = centroids_index[labels]
  44. # 列表解析,每2*2个像素挑选出一个,组成(height*width*灰)数组。
  45. labels_picked = [labels[rows * width:(rows + 1) * width:2] for rows in range(0, height, 2)]
  46. canvas = np.zeros((3 * height, 3 * width, 3), np.uint8)
  47. canvas.fill(255) # 创建长宽为原图三倍的白色画布。
  48. # 因为 字体大小为0.45时,每个数字占6*6个像素,而白底画布为原图三倍
  49. # 所以 需要原图中每2*2个像素中挑取一个,在白底画布中由6*6像素大小的数字表示这个像素信息。
  50. y = 8
  51. for rows in labels_picked:
  52. x = 0
  53. for cols in rows:
  54. if cols <= shadow_bound:
  55. cv2.putText(canvas, str(random.randint(2, 9)),
  56. (x, y), cv2.FONT_HERSHEY_PLAIN, 0.45, 1)
  57. elif cols <= bright_bound:
  58. cv2.putText(canvas, "-", (x, y),
  59. cv2.FONT_HERSHEY_PLAIN, 0.4, 0, 1)
  60. x += 6
  61. y += 6
  62. return canvas
  63. if __name__ == '__main__':
  64. fp = r"d4de43ab358fff76e1cd50e727e7a5ee (1).jpeg"
  65. img = cv2.imread(fp)
  66. # 若字符画结果不好,可以尝试更改K为3。若依然无法很好地表现原图,请换图尝试。 -_-||
  67. str_img = img2strimg(img,K=5)
  68. cv2.imwrite("result-k5.jpg", str_img)

resource

run

分别为 k=3  k=5 的输出结果

参考:

超清字符画——Python代码 - 知乎

python实现图片转字符画_Flye的博客-CSDN博客_python 图片转字符画






所属网站分类: 技术文章 > 博客

作者:短发越来越短

链接:https://www.pythonheidong.com/blog/article/984183/022da003ac05499e4214/

来源:python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

1 0
收藏该文
已收藏

评论内容:(最多支持255个字符)