骰子作画的算法

简介:

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

他用黑底白点的骰子。

模拟出一张人像照片。

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

他一共用了2500多颗骰子。

最后的成品就是这样。

任何一张图片都可以用骰子模拟出来,算法非常简单:将图片分成若干个区域,每个区域经过计算以后,用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个白点的多米诺骨牌。

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

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

(完)

目录
相关文章
|
算法
算法提高:计算几何基础 | 详解凸包问题
点集Q的凸包(convex hull)是指一个最小凸多边形,满足Q中的点或者在多边形边上,或者在其内
171 0
算法提高:计算几何基础 | 详解凸包问题
|
机器学习/深度学习 决策智能 计算机视觉
对硬币、销钉、大米进行图像分割(附代码)
对硬币、销钉、大米进行图像分割(附代码)
110 0
|
算法
算法创作|纸牌三角形
算法创作|纸牌三角形
67 0
|
算法 Java C++
蓝桥杯 算法训练 小生物的逃逸(球坐标公式+暴力求解)
蓝桥杯 算法训练 小生物的逃逸(球坐标公式+暴力求解)
|
算法 C++
【每日算法Day 98】慈善赌神godweiyang教你算骰子点数概率!
【每日算法Day 98】慈善赌神godweiyang教你算骰子点数概率!
129 0
|
机器学习/深度学习
排列组合、古典概型、几何概型与伯努利概型
排列组合、古典概型、几何概型与伯努利概型
|
算法 机器人
算法练习题(五)——机器人走方格
算法练习题(五)——机器人走方格
106 0
|
编解码
学习:泰勒级数插值的多光谱马赛克图像复原方法综述
学习:泰勒级数插值的多光谱马赛克图像复原方法综述
332 0
学习:泰勒级数插值的多光谱马赛克图像复原方法综述
|
定位技术
UPC训练第23场——寻路——弗洛伊德
题目描述 明明同学被困在一个荒凉的北极岛屿,他可以用小船乘着海流用1单位时间从一个岛移动到另一个岛。他得到了一个海洋地图,有N(1&lt;=N&lt;=100)条单向海流航线,编号为1…N。 告诉你他的起始位置M(1&lt;=M&lt;=N)和地图,请编程帮助明明确定到达每个岛的最短时间是多少。 输入为一个矩阵C,第r行,第c列的值若为1,则r到c存在海流,值为0则不存在海流。
126 0