骰子算法 php,骰子作画的算法

程序员Scott MacDonald通过2500多颗骰子和简单的算法,将图片矢量量化为1-6的整数表示,再现了人像照片。他将图片分为16x16像素区域,计算每个区域的灰度平均值,对应不同数量的白点模拟骰子面。这项技术源自1981年的多米诺骨牌,如今无需编程,也可在Photoshop中实现。
摘要由CSDN通过智能技术生成

程序员Scott MacDonald做了一个很有趣的项目----骰子作画。

他用黑底白点的骰子。

e65a61676be637402cfdcbecfe4cbb30.png

模拟出一张人像照片。

1c608a7aa818ee233b071601d9be9c1c.png

把图像放大,就可以看得更清楚。

398870dfb920e71cb2e2efef13c53d9b.png

他一共用了2500多颗骰子。

98485dc618a88d5e54c6c694b31156d2.png

最后的成品就是这样。

a900d1539f9186b9e510a48f171c9b6b.png

任何一张图片都可以用骰子模拟出来,算法非常简单:将图片分成若干个区域,每个区域经过计算以后,用1-6之间的一个整数表示,代表骰子的一个面。这种将连续的量转化成不连续的整数的算法,属于vector quantization(矢量量化)的一个应用。

具体来说,

第一步,将图片分割成16像素x16像素的小方块。

for (int i=0; i < (pic_width/16); ++i) {

for (int j=0; j < (pic_height/16); ++j) {

patch = cropped_img.get(i*16, j*16, 16, 16);

}

}

第二步,每个小方块内共有256个像素,将每个像素点的灰度值,存入一个数组。

for (int k=0; k < patch.pixels.length; ++k) {

x[k] = rgb2gray(patch.pixels[k]);

}

int rgb2gray(int argb) {

int _alpha = (argb >> 24) & 0xFF;

int _red = (argb >> 16) & 0xFF;

int _green = (argb >> 8 ) & 0xFF;

int _blue = (argb) & 0xFF;

return int(0.3*_red + 0.59*_green + 0.11*_blue);

}

第三步,计算该数组的平均值,并用1-6之间的一个整数来表示。

int dice_num = six_step_gray(mean(x));

int mean(int[] x) {

float m = 0;

for (int i=0; i < x.length; ++i) {

m += x[i];

}

m = m/x.length;

return int(m);

}

int six_step_gray(int x) {

if (0 <= x && x <= 41) return 1;

if (41 < x && x <= 83) return 2;

if (83 < x && x <= 124) return 3;

if (124 < x && x <= 165) return 4;

if (165 < x && x <= 206) return 5;

if (206 < x && x <= 247) return 6;

else return 6;

}

整数1,表示骰子朝上的一面有1个白点;整数2,表示有2个白点;以此类推。白点越少,表示这个区域越接近全黑;白点越多,表示越接近全白。根据白点值,将骰子依次放入,就能模拟出全图。

这种算法早在1981年就有人提出,当时用的是1~9个白点的多米诺骨牌。

53499d675398438e8adf858f35a287e5.png

如果区域划分得越小,模拟图的生成效果就越好。

e2c87155057518e81473c4aafcf58119.png

3e7d750726bc8039afd6fe43b5cead08.png

9e7252aeedfb85b543f1d51c827775d1.png

5c2f47f2ae7c2857573773390f3756b5.png

d16a8e6eae51673a6ffe984f67a38a94.png

4575134ae15569c46966e69228ecbcdb.png

此外,不用编程,使用Photoshop也可以得到类似效果。

154c682c2936fbf93945a10d7d368f70.png

(完)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值