当前位置:   article > 正文

python利用wordcloud库来绘制有特殊轮廓的词云(解决图片轮廓提取失败的一种方案)

python利用wordcloud库来绘制有特殊轮廓的词云(解决图片轮廓提取失败的一种方案)

绘制有特殊轮廓的词云 

更新:

解决方法:

复制下述代码

在对应的位置提供原图片扣好的图,词云文本内容 (原谅我的技术水平,大家可以自行学习抠图的代码或者直接找可以在线抠图的网站来抠图,或者等我一段时间,等我学会抠图功能的时候再回来更新内容)

  1. from wordcloud import WordCloud
  2. from PIL import Image
  3. import numpy as np
  4. import matplotlib.pyplot as plt
  5. # 提供抠图后图片小hi().png
  6. image = Image.open("小hi().png").convert("L")
  7. # 二值化处理
  8. threshold = 0
  9. image = image.point(lambda p: 0 if p > threshold else 255)
  10. mask = np.array(image)
  11. # 绘制
  12. text = open(r"附件1.txt", encoding="utf-8").read()
  13. wordcloud = WordCloud(
  14. width=400,
  15. height=800,
  16. background_color="white",
  17. font_path="C:/Windows/Fonts/simkai.ttf",
  18. contour_width=2,
  19. contour_color="white",
  20. mask=mask).generate(text)
  21. # 展示
  22. plt.figure(figsize=(8, 8), facecolor=None)
  23. plt.imshow(wordcloud, interpolation="bilinear")
  24. plt.axis("off")
  25. plt.tight_layout(pad=0)
  26. plt.show()
  27. # 或者保存词云为图像文件
  28. wordcloud.to_file("your_wordcloud.png")

效果:

#############################################################################一下为以往信息,可视作为解决的过程,可以不看。

预期更新:抠图算法,解决库的安装问题(总之就是小白攻略,有空再说)

一、遇到的问题

利用python中的wordcloud库来绘制有特殊轮廓的词云。
但是利用网上的其他解答里面的代码绘制出来的往往是这个
显然矩形不是我们想要的。

你们仔细观察一下自己的代码里面是不是有这个imageio.imread或这个imread
据我判断(瞎猜),错误就是这个函数在高版本py失效引起的

二、解决方案

(在此使用人物形象作为词云轮廓,大家可以根据自己需求选择)
复制下述代码
在对应的位置提供原图片,扣好的图,词云文本内容
(原谅我的技术水平,大家可以自行学习抠图的代码或者直接找可以在线抠图的网站来抠图,或者等我一段时间,等我学会抠图功能的时候再回来更新内容)
  1. from wordcloud import WordCloud
  2. from PIL import Image
  3. import numpy as np
  4. import matplotlib.pyplot as plt
  5. # 导入图片(此处以小hi为例)
  6. image = Image.open("小hi.png").convert("L")
  7. image1 = Image.open("小hi(抠图).png").convert("L")
  8. # 二值化处理
  9. threshold = 200 # 阈值,可根据实际情况调整(一般要大一点)
  10. image = image.point(lambda p: 255 if p > threshold else 0)
  11. threshold = 0 # 阈值,可根据实际情况调整(越小越好)
  12. image1 = image1.point(lambda p: 255 if p > threshold else 0)
  13. # 辗转相减得到词云的轮廓
  14. mask = np.array(image)
  15. mask1 = np.array(image1)
  16. mask -= mask
  17. # 导入词云文本内容
  18. text = open(r"文本.txt", encoding="utf-8").read()
  19. wordcloud = WordCloud(
  20. width=400,
  21. height=800,
  22. background_color="white",
  23. font_path="C:/Windows/Fonts/simkai.ttf",
  24. contour_width=2,
  25. contour_color="white", #轮廓颜色,不想深究原因请忽略
  26. mask=mask).generate(text)
  27. # 词云展示
  28. plt.figure(figsize=(8, 8), facecolor=None)
  29. plt.imshow(wordcloud, interpolation="bilinear")
  30. plt.axis("off")
  31. plt.tight_layout(pad=0)
  32. plt.show()
  33. # 或者保存词云为图像文件
  34. wordcloud.to_file("wordcloud.png")

原图与扣好的图

效果展示

(文本内容是一些动漫的名字)

三、解释

(说实话看了也没啥大用,能解决问题就可以了)

1、理论

利用wordcloud库来绘制词云时我们需要提供词云文本内容和词云的轮廓,一般而言(我瞎臆测)我们先找一张图片然后利用imageio.imread来提取图片中的轮廓,将得到的轮廓以高维数组的形式来储存。然后词云识别高维数组中的轮廓信息将文本内容绘制到轮廓内。

2、测试

我们来测试一下问题出现在哪一个环节(轮廓提取还是内容绘制)

(声明:极化法仅处理轮廓,将图片修改成纯黑纯白像素块)

我们在白色背景下绘制图像的黑色轮廓。

首先是网上大多数的代码方案

  1. from wordcloud import WordCloud
  2. import matplotlib.pyplot as plt
  3. import imageio
  4. mask = imageio.imread('小hi.png')
  5. # 绘制
  6. text = open(r"附件1.txt", encoding="utf-8").read()
  7. wordcloud = WordCloud(
  8. width=400,
  9. height=800,
  10. background_color="white",
  11. font_path="C:/Windows/Fonts/simkai.ttf",
  12. contour_width=2,
  13. contour_color="black",
  14. mask=mask).generate(text)
  15. # 展示
  16. plt.figure(figsize=(8, 8), facecolor=None)
  17. plt.imshow(wordcloud, interpolation="bilinear")
  18. plt.axis("off")
  19. plt.tight_layout(pad=0)
  20. plt.show()
  21. # 或者保存词云为图像文件
  22. wordcloud.to_file("wordcloud.png")

结果是这样的

可见轮廓如有

然后是极化处理后的(和上面的代码一样就是将轮廓颜色改了一下)

结果是这样的

可以看见差异很大,可以断定是轮廓问题了?

但是如果我稍微改一下

(将第一段代码wordcloud中mark参数改成mark1就可以)

就会得到这个东西

你就说有没有轮廓吧

进一步改动极化处理过程(过程应该没人感到好奇,直接放结果)

(从左到右极化处理程度加大)

可见轮廓越来越清晰,词云的面积越来越小

然后,出现了这个报错

Couldn't find space to draw. Either the Canvas size is too small or too much of the image is masked out.

意思就是wordcloud找不到可以绘制词云的空间了!

会有人猜测是因为轮廓占据了空间,但是取消轮廓绘制后,依然报错,所以问题在极化法上。

就在我思考是什么原因时,取消了辗转相减法,得到了一张这个图

可以下结论了,wordcloud在像素点为(0,0,0)的地方(或者说空白的地方)绘制词云,但是imread失效,程序直接使用图片的外形(矩形)作为词云轮廓,于是wordcloud绘制不出特殊轮廓的词云了。但是这时人为将图片分成空白与填充两部分,然后wordcloud就可以绘制出想要的词云了。

3、解决思路

测试结束,问题出现在轮廓上面,我们要做的就是解决轮廓问题。

我的思路就是利用一张扣好的图,利用极化法,将轮廓内部改成空白,其余部分改成填充,然后就可以解决问题了。

在最近至少两个版本的py中imageio.imread失效了(我猜是功能代价太大舍弃掉了或者纯纯就是开发者没有更新版本)(库的安装失效)要不然我也不会瞎折腾。

四、个人感悟

我一开始解决了问题,用了一个很有逻辑(自认为)的方法,然后在写这篇博客的时候复盘了一遍,梳理了逻辑后发现:仅仅需要改两个参数就可以直接解决。

(我被自己蠢到了,但是写了这么多我也不想删,当做成长路上的纪念吧)

最后是本篇博客的诞生背景:
(感谢观看!!!)
社团的老传统(利用python来绘制一个带有轮廓的词云)
主旨为捶打新生信息搜集和学习的能力(bushi)
然而,就在去年我被捶打时,发现这个东东不合适
今年我在捶打新生时(恶劣),发现教的这个东西过时了
可怜去年我啥也不会(哭)
于是我决定,造福学弟学妹,提供这个问题的解决方法
(试图打破传统!!!)(我自己反抗我自己)
本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/一键难忘520/article/detail/899394
推荐阅读
相关标签
  

闽ICP备14008679号