<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>肖像 on 红旗下的蛋</title><link>https://blog.fallleaf.net/tags/portrait/</link><description>Recent content in 肖像 on 红旗下的蛋</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><copyright>fallleaf</copyright><lastBuildDate>Sun, 30 Jul 2023 15:49:14 +0800</lastBuildDate><atom:link href="https://blog.fallleaf.net/tags/portrait/index.xml" rel="self" type="application/rss+xml"/><item><title>色子肖像--Python程序</title><link>https://blog.fallleaf.net/p/tech-dice-portrait-python/</link><pubDate>Thu, 28 Dec 2017 15:49:14 +0800</pubDate><guid>https://blog.fallleaf.net/p/tech-dice-portrait-python/</guid><description>&lt;p&gt;上一篇色子肖像介绍了把图像变成色子点阵图的基本思路，用python语言采用PIL库写了一个程序，后来发现opencv更加简便合适，就采用numpy以及opencv库，进行了优化。
这是我第一次开始用python语言编写稍微复杂些的程序。对于有一定编程经验的人，采用实现一个功能的方式编程能够很快熟悉该语言，是一种很好的学习方式。&lt;/p&gt;
&lt;p&gt;以下是我编写的程序以及简单的注释。&lt;/p&gt;
&lt;p&gt;由于要对图像进行数值处理，所以采用opencv以及numpy库。首先是加载库，datetime是用于计算程序运行时间，os是用于获得文件路径，sys是用于获得命令行参数，cv2是opencv库，numpy是python的数组库。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;import datetime
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;import os
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;import sys
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;import cv2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;import numpy as np
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;保证程序本身直接执行，而不是被调用，如果直接执行，则调用main()函数。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;if __name__ == &amp;#34;__main__&amp;#34;:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; main()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;一个python文件就可以看作是一个python的模块，这个python模块（.py文件）有两种使用方式：直接运行使用和作为模块被其他模块调用。 每一个模块都有一个内置属性__name__。而__name__的值取决与python模块（.py文件）的使用方式。如果是直接运行使用，那么这个模块的__name__值就是“main”；如果是作为模块被其他模块调用，那么这个模块（.py文件）的__name__值就是该模块（.py文件）的文件名且不带路径和文件扩展名，如果dice_portrait_cv.py被其他python程序import dice_portrait_cv，则__name__为dice_portrait_cv。 main()函数，主要功能流程的执行，分别是：&lt;/p&gt;
&lt;p&gt;1.初始化文件路径&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;def main():
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; start_time = datetime.datetime.now() #设置程序运行开始时间
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; #初始化文件路径
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; EXEC_PATH = os.getcwd()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; DICEPATH = EXEC_PATH + &amp;#39;\\dice_image\\&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; OUTPUTPATH = EXEC_PATH + &amp;#39;\\output\\&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; if not (os.path.exists(OUTPUTPATH)):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; os.mkdir(OUTPUTPATH)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;2.获得命令行参数，调用自定义函数getvalue()，返回输入图片文件名，色子列数，是否旋转&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; imagefile, DICE_WIDTH, ROTATE = getvalue()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;3.读取要渲染的图片及色子图片&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; im = cv2.imread(imagefile, 0)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; dice = getDice(DICEPATH)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;4.调用自定义函数，调整图片大小，返回图片数组&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; im = AjustImage(DICE_WIDTH, im)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;5.定义灰色度数值对应色子1-6点的分组，用了list，也可以用numpy的数组&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; p = [60, 80, 110, 150, 190, 220]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; #使用numpy数组
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; p = np.array([60, 80, 110, 150, 190, 220])
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;6.对图像进行16x16图块分割，并计算灰度，对应色子1-6，并将图片转换成色子点阵图，调用自定义函数，获得处理后的图像以及色子点数文件。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; im, dice_data = calculateDice(im, imagefile, p, dice, ROTATE)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;7.保存图片及色子点数文件&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; write_Dice(im, OUTPUTPATH, imagefile, dice_data)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;8.打印运行时间以及色子图片，按任意键退出&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; end_time = datetime.datetime.now()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; print(&amp;#39;程序运行时间:&amp;#39;, end_time - start_time,&amp;#39;秒&amp;#39;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; cv2.imshow(imagefile, im)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; cv2.waitKey(0)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;下面是自定义函数。 1.获得命令行变量，返回变量：imagefile（输入文件名）, DICE_WIDTH（色子列数）, ROTATE（色子2，3，6是否旋转） def getvalue():&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; if (len(sys.argv) &amp;lt; 2 or len(sys.argv) &amp;gt; 4):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; print(&amp;#34;Error, invalid arguments!&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; print(&amp;#34;Call with &amp;#34; + sys.argv[0] + &amp;#34; inputimage [tile-size] &amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; sys.exit(1)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ROTATE = False
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; DICE_WIDTH = 50
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; if len(sys.argv) == 2:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; imagefile = sys.argv[1]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; elif len(sys.argv) == 3:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; imagefile = sys.argv[1]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; DICE_WIDTH = int(sys.argv[2])
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; if (DICE_WIDTH &amp;gt; 150 or DICE_WIDTH &amp;lt; 30):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; print(&amp;#34;色子列数不正确，应在30-150之间&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; sys.exit(1)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; else:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; imagefile = sys.argv[1]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; DICE_WIDTH = int(sys.argv[2])
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; if (DICE_WIDTH &amp;gt; 150 or DICE_WIDTH &amp;lt; 30):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; print(&amp;#34;Dice quality not avialiabe. It betweet 30 and 150&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; sys.exit(1)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; if (sys.argv[3] == &amp;#39;0&amp;#39; or sys.argv[3] == &amp;#39;1&amp;#39;):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ROTATE = bool(int(sys.argv[3]))
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; else:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; print(&amp;#34;1:色子旋转, 0:色子不旋转&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; sys.exit(1)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; return imagefile, DICE_WIDTH, ROTATE
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;2.调整图片，图片宽度为色子列数*16，返回调整后的图像数组，自定义函数输入变量为DICE_WIDTH（色子列数），image（输入的图像数组）&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;def AjustImage(DICE_WIDTH, image): # 调整图片
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; hight, width = image.shape[:2]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ratio = DICE_WIDTH * 16 / width
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; width = int(width * ratio)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; hight = int(hight * ratio)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; image = cv2.resize(image, (width, hight))
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; return image
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;3.读入色子图形&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;def getDice(DICEPATH): # 读入色子图形文件
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; dice = np.zeros((9, 16, 16),dtype=&amp;#39;u8&amp;#39;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; for i in range(9):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; dice[i] = cv2.imread(&amp;#39;./dice_image/&amp;#39; + str(i + 1) + &amp;#39;w.png&amp;#39;, 0)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; return dice
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;4.对图像进行处理，输入参数：im（图像数组）, imagefile（图片文件名）, p（灰色度分组数组）, dice（色子图片数组）, ROTATE（色子2，3，6是否旋转），返回处理后的图片数组im，以及色子点数数组image_data&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;span class="lnt"&gt;40
&lt;/span&gt;&lt;span class="lnt"&gt;41
&lt;/span&gt;&lt;span class="lnt"&gt;42
&lt;/span&gt;&lt;span class="lnt"&gt;43
&lt;/span&gt;&lt;span class="lnt"&gt;44
&lt;/span&gt;&lt;span class="lnt"&gt;45
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;def calculateDice(im, imagefile, p, dice, ROTATE): # 处理图片
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; x_max = int((im.shape[1]/16))
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; y_max = int((im.shape[0]/16))
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; dice_data = np.arange(y_max * x_max, dtype=&amp;#34;u8&amp;#34;).reshape(y_max, x_max)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; dice2_rotate = False
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; dice3_rotate = False
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; dice6_rotate = False
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; cv2.namedWindow(imagefile, 0)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; cv2.resizeWindow(imagefile, 640, int(640 * y_max / x_max))
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; for j in range(y_max):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; for i in range(x_max):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; # 获得16x16图片的色度平均值mean或中位数median
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; image_data = int(np.mean(im[j * 16:(j + 1) * 16, i * 16:(i + 1) * 16]))
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; # 根据色度值确定色子点数
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; if (image_data &amp;lt; p[0]):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; n = 5
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; if (ROTATE):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; dice6_rotate = not (dice6_rotate)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; if (dice6_rotate):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; n = 8
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; elif (image_data &amp;gt;= p[0]) and (image_data &amp;lt; p[1]):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; n = 4
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; elif (image_data &amp;gt;= p[1]) and (image_data &amp;lt; p[2]):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; n = 3
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; elif (image_data &amp;gt;= p[2]) and (image_data &amp;lt; p[3]):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; n = 2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; if (ROTATE):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; dice3_rotate = not (dice3_rotate)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; if (dice3_rotate):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; n = 7
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; elif (image_data &amp;gt;= p[3]) and (image_data &amp;lt; p[4]):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; n = 1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; if (ROTATE):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; dice2_rotate = not (dice2_rotate)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; if (dice2_rotate):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; n = 6
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; else:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; n = 0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; #将色子图片写入原图片
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; im[j * 16:(j + 1) * 16, i * 16:(i + 1) * 16] = dice[n]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; dice_data[j, i] = n + 1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; #显示色子覆盖原图片步骤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; cv2.imshow(imagefile, im)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; cv2.waitKey(1)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; return im, dice_data
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;5.保存图片及色子点数文件&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;def write_Dice(im, OUTPUTPATH, imagefile, dice_data): # 将色子点数写入文件
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; y_max, x_max = np.shape(dice_data)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; DICE_WIDTH = x_max
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; print(&amp;#34;色子数量&amp;#34;, y_max, &amp;#39;*&amp;#39;, x_max, &amp;#39;=&amp;#39;, x_max * y_max)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; cv2.imwrite(OUTPUTPATH + str(DICE_WIDTH) + &amp;#39;_hist_&amp;#39; + imagefile, im)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; f = open(OUTPUTPATH + str(DICE_WIDTH) + &amp;#39;_hist_&amp;#39; + imagefile + &amp;#39;.txt&amp;#39;, &amp;#39;wt&amp;#39;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; for y in range(y_max):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; f.write((str(y + 1) + &amp;#39;:&amp;#39;))
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; for x in range(x_max):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; f.write(str(dice_data[y, x]) + &amp;#39;,&amp;#39;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; f.write(&amp;#39;\n&amp;#39;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; f.close()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; print(&amp;#39;文件保存完毕!&amp;#39;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; return
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;采用numpy，对数组进行运算非常方便。&lt;/p&gt;
&lt;p&gt;程序放到了GitHub上，也可以直接用&lt;/p&gt;
&lt;p&gt;git clone &lt;a class="link" href="https://github.com/fallleaf/dice_portrait.git" target="_blank" rel="noopener"
&gt;https://github.com/fallleaf/dice_portrait.git&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;图框和色子都准备好了，这将是18年的第一个项目。&lt;/p&gt;</description></item><item><title>色子肖像</title><link>https://blog.fallleaf.net/p/tech-dice-portrait/</link><pubDate>Tue, 12 Dec 2017 10:02:27 +0800</pubDate><guid>https://blog.fallleaf.net/p/tech-dice-portrait/</guid><description>&lt;img src="https://blog.fallleaf.net/p/tech-dice-portrait/cecilia_small.png" alt="Featured image of post 色子肖像" /&gt;&lt;p&gt;2008年Scott MacDonald发表了一篇Blog，用骰子为她制作一副肖像画,他把一幅肖像画量化成不同点数的色子，用色子摆放成了一幅肖像画。如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.fallleaf.net/p/tech-dice-portrait/caroline_portrait.png"
width="512"
height="273"
srcset="https://blog.fallleaf.net/p/tech-dice-portrait/caroline_portrait_hu_c2c495ea3cda6d25.png 480w, https://blog.fallleaf.net/p/tech-dice-portrait/caroline_portrait_hu_f70e9b7b7c26cbf2.png 1024w"
loading="lazy"
alt="caroline_portrait"
class="gallery-image"
data-flex-grow="187"
data-flex-basis="450px"
&gt;&lt;/p&gt;
&lt;p&gt;他用了2560（40x60）个16mm的色子，制作了一个64cmx96cm的色子肖像，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.fallleaf.net/p/tech-dice-portrait/caroline.jpg"
width="529"
height="542"
srcset="https://blog.fallleaf.net/p/tech-dice-portrait/caroline_hu_fbdcc507a223342c.jpg 480w, https://blog.fallleaf.net/p/tech-dice-portrait/caroline_hu_4ade5e8f384b2656.jpg 1024w"
loading="lazy"
alt="caroline"
class="gallery-image"
data-flex-grow="97"
data-flex-basis="234px"
&gt;&lt;/p&gt;
&lt;p&gt;他用的是Prossing语言编写的程序。近期正在学习Python，就尝试用Python来实现这一功能。&lt;/p&gt;
&lt;p&gt;思路是先对图像进行灰度处理，然后把图片分割成16x16像素的单元图块，再对图块中256个点的灰度取平均值，对平均值分组用1-6数值代替。色度值范围0-255，亮度从深到浅，颜色从黑到白。数值1-6对应色子的点数，对于黑底白点的色子，色度值和点数正比例关系，对于白底黑点的色子，色度值和点数反比例关系。最后按色子点数做出图。&lt;/p&gt;
&lt;p&gt;我用了三种16x16的图块，如下：&lt;/p&gt;
&lt;p&gt;灰度色块：
&lt;img src="https://blog.fallleaf.net/p/tech-dice-portrait/graydice.png"
width="96"
height="16"
srcset="https://blog.fallleaf.net/p/tech-dice-portrait/graydice_hu_2a8cd17567e55e06.png 480w, https://blog.fallleaf.net/p/tech-dice-portrait/graydice_hu_9af2030d95ba904e.png 1024w"
loading="lazy"
alt="graydice"
class="gallery-image"
data-flex-grow="600"
data-flex-basis="1440px"
&gt;&lt;/p&gt;
&lt;p&gt;黑底白点色子：
&lt;img src="https://blog.fallleaf.net/p/tech-dice-portrait/blackdice.png"
width="96"
height="16"
srcset="https://blog.fallleaf.net/p/tech-dice-portrait/blackdice_hu_1630946f4df10da0.png 480w, https://blog.fallleaf.net/p/tech-dice-portrait/blackdice_hu_126e36a88e9ee30.png 1024w"
loading="lazy"
alt="blackdice"
class="gallery-image"
data-flex-grow="600"
data-flex-basis="1440px"
&gt;&lt;/p&gt;
&lt;p&gt;白底黑点色子：
&lt;img src="https://blog.fallleaf.net/p/tech-dice-portrait/whitedice.png"
width="96"
height="16"
srcset="https://blog.fallleaf.net/p/tech-dice-portrait/whitedice_hu_6797ae34ca853fb0.png 480w, https://blog.fallleaf.net/p/tech-dice-portrait/whitedice_hu_a220206ef32465ae.png 1024w"
loading="lazy"
alt="whitedice"
class="gallery-image"
data-flex-grow="600"
data-flex-basis="1440px"
&gt;&lt;/p&gt;
&lt;p&gt;利用Python的PIL库（Python Image Library）以及numpy数组库，能够很容易的完成功能。&lt;/p&gt;
&lt;p&gt;首先是加载库文件，打开图片，对图片灰度处理，并计算要分割图块的数量&lt;/p&gt;
&lt;p&gt;#加载库文件&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;from PIL import Image, ImageDraw
import numpy as np
#载入色子图片，1.png-6.png，代表色子点数
dice =[]
for i in range(6):
dice.append(Image.open(str(i+1)+&amp;rsquo;.png&amp;rsquo;))
#载入肖像图片
im = Image.open(&amp;ldquo;cecilia.png&amp;rdquo;)
im=im.convert(&amp;ldquo;L&amp;rdquo;)
width,hight =im.size
x_max = int (width/16)
y_max = int(hight/16)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;分割图片为16x16图块，并计算点的色度平均值&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;image_data = np.ones(y_max&lt;em&gt;x_max).reshape(y_max,x_max)
block_data = np.ones(16&lt;/em&gt;16).reshape(16,16)
dice_data = np.ones(y_max&lt;em&gt;x_max).reshape(y_max,x_max)
for j in range(y_max):
for i in range(x_max):
b=im.crop( (i&lt;/em&gt;16,j*16,(i+1)*16,(j+1)*16))#获得16x16图片
sum_x=0
for ii in range(16):
for jj in range(16):
block_data[jj,ii]=b.getpixel((ii,jj))
image_data[j,i]=int(np.mean(block_data))&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;根据色块的平均值分配色子图块：&lt;/p&gt;
&lt;p&gt;#定义色度分组值&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;p = [45,65,80,95,130,155]
if (image_data[j,i]&amp;lt;p[0]):
n = 5
elif (image_data[j,i]&amp;gt;=p[0]) and (image_data[j,i]&amp;lt;p[1]):
n = 4
elif (image_data[j,i]&amp;gt;=p[1]) and (image_data[j,i]&amp;lt;p[2]):
n = 3
elif (image_data[j,i]&amp;gt;=p[2]) and (image_data[j,i]&amp;lt;p[3]):
n = 2
elif(image_data[j,i]&amp;gt;=p[3]) and (image_data[j,i]&amp;lt;p[4]):
n = 1
else:
n = 0
im.paste(dice[n],(i&lt;em&gt;16,j&lt;/em&gt;16))
dice_data[j,i] = n+1&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这里p1p6是对0255的色度值划分到1-6的分组值。 生成处理后的图片，及显示图片&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;im.save(&amp;lsquo;small_ceciliaw.png&amp;rsquo;)
im.show()&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;将色子点数写入文件&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;f = open(&amp;lsquo;cecilia_dice_data.txt&amp;rsquo;,&amp;lsquo;wt&amp;rsquo;)
for y in range(y_max):
f.write((str(y+1)+&amp;rsquo;:&amp;rsquo;))
for x in range(x_max):
f.write(str(dice_data[y,x])+&amp;rsquo;,&amp;rsquo;)
f.write(&amp;rsquo;\n&amp;rsquo;)
f.close()&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;按以上方法生成了三种处理后的图片，第一个是原图，第二个是灰度色块，第三个是黑底白点，第四个是白底黑点。如下图：
&lt;img src="https://blog.fallleaf.net/p/tech-dice-portrait/cecilia_small.png"
width="1120"
height="1584"
srcset="https://blog.fallleaf.net/p/tech-dice-portrait/cecilia_small_hu_542dd8651340c7dd.png 480w, https://blog.fallleaf.net/p/tech-dice-portrait/cecilia_small_hu_e475395d559590d0.png 1024w"
loading="lazy"
alt="cecilia"
class="gallery-image"
data-flex-grow="70"
data-flex-basis="169px"
&gt;&lt;/p&gt;
&lt;p&gt;所用原始图片的大小为1120x1584，一共生成色子数量为70x99=6930块,若用8mm的色子制作，大小为56cmx79.2cm。 亚洲人的面部没有欧洲人立体感强，选择照片时需挑选立体感强，色差比较鲜明的图片，这样，分辨率可以低一些，色子的数量可以减少一些。另外，1-6的分组值也需要进一步优化。下图是分辨率变化的情况。
&lt;img src="https://blog.fallleaf.net/p/tech-dice-portrait/ceciliag_gif.gif"
width="280"
height="396"
srcset="https://blog.fallleaf.net/p/tech-dice-portrait/ceciliag_gif_hu_5e4c2dfb41ced0d2.gif 480w, https://blog.fallleaf.net/p/tech-dice-portrait/ceciliag_gif_hu_8bfeb71e387b1d48.gif 1024w"
loading="lazy"
alt="ceciliag"
class="gallery-image"
data-flex-grow="70"
data-flex-basis="169px"
&gt;
&lt;img src="https://blog.fallleaf.net/p/tech-dice-portrait/ceciliaw_gif.gif"
width="280"
height="396"
srcset="https://blog.fallleaf.net/p/tech-dice-portrait/ceciliaw_gif_hu_b692e8d90f563c54.gif 480w, https://blog.fallleaf.net/p/tech-dice-portrait/ceciliaw_gif_hu_85051bd5a762ed50.gif 1024w"
loading="lazy"
alt="ceciliaw"
class="gallery-image"
data-flex-grow="70"
data-flex-basis="169px"
&gt;
&lt;img src="https://blog.fallleaf.net/p/tech-dice-portrait/ceciliab_gif.gif"
width="280"
height="396"
srcset="https://blog.fallleaf.net/p/tech-dice-portrait/ceciliab_gif_hu_2bf96734fa72f743.gif 480w, https://blog.fallleaf.net/p/tech-dice-portrait/ceciliab_gif_hu_d881b7438a7385eb.gif 1024w"
loading="lazy"
alt="ceciliab"
class="gallery-image"
data-flex-grow="70"
data-flex-basis="169px"
&gt;&lt;/p&gt;
&lt;p&gt;这个项目正在进行中，等色子及图框到后再把制作的全过程展示一下。&lt;/p&gt;
&lt;p&gt;续：&lt;/p&gt;
&lt;p&gt;购买了2000个色子，用纸盒盖子做框，摆成一个肖像，远看效果好些&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.fallleaf.net/p/tech-dice-portrait/cecilia_dice1.jpg"
width="1080"
height="1440"
srcset="https://blog.fallleaf.net/p/tech-dice-portrait/cecilia_dice1_hu_9afffa2e6bcab57.jpg 480w, https://blog.fallleaf.net/p/tech-dice-portrait/cecilia_dice1_hu_79421af38ba3cd23.jpg 1024w"
loading="lazy"
alt="cecilia1"
class="gallery-image"
data-flex-grow="75"
data-flex-basis="180px"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.fallleaf.net/p/tech-dice-portrait/cecilia_dice2.jpg"
width="1080"
height="1440"
srcset="https://blog.fallleaf.net/p/tech-dice-portrait/cecilia_dice2_hu_3f405b5235b9b71e.jpg 480w, https://blog.fallleaf.net/p/tech-dice-portrait/cecilia_dice2_hu_49d2120084624dfc.jpg 1024w"
loading="lazy"
alt="cecilia2"
class="gallery-image"
data-flex-grow="75"
data-flex-basis="180px"
&gt;&lt;/p&gt;
&lt;p&gt;源代码放到了GitHub上，做了些改动，采用opencv做图像处理。&lt;/p&gt;</description></item></channel></rss>