# 弗洛伊德-斯坦伯格抖动算法

python 同时被 2 个专栏收录
30 篇文章 0 订阅
5 篇文章 0 订阅

## 算法实现

 import numpy as np from PIL import Image from requests import get from bokeh.plotting import figure, show, output_notebook from bokeh.layouts import layout from bokeh.palettes import gray output_notebook() def image_dither(path, black='#000000', white='#ffffff'):     image_rgb = read_image(path)     image_gray = grayscale(image_rgb)     image_bw = floyd_steinberg(image_gray)     show(layout([[         plot(image_gray, palette=gray(256)),         plot(image_bw, palette=[black, white])             ]])) def floyd_steinberg(image):     image = image.copy()     distribution = np.array([7, 3, 5, 1], dtype=float) / 16     u = np.array([0, 1, 1, 1])     v = np.array([1, -1, 0, 1])          for y in range(image.shape[0] - 1):         for x in range(image.shape[1] - 1):             value = np.round(image[y, x])             error = image[y, x] - value             image[y, x] = value             image[y + u, x + v] += error * distribution                  image[:, -1] = 1     image[-1, :] = 1     return image def grayscale(image):     height, width, _ = image.shape          image = np.array(image, dtype=np.float32) / 255     image = image[:, :, 0] * .21 + \             image[:, :, 1] * .72 + \             image[:, :, 2] * .07          return image.reshape(height, width) def read_image(path, size=400):     if path.startswith('https://'):         image = Image.open(get(path, stream=True).raw)     else:         image = Image.open(path) width, height = image.size width, height = size, int(size * height / width) image = image.resize((width, height), Image.ANTIALIAS) data = image.getdata() assert data.bands in [3, 4], 'RGB or RGBA image is required' raw = np.array(data, dtype=np.uint8) return raw.reshape(height, width, data.bands) def plot(image, palette): y, x = image.shape plot = figure(x_range=(0, x), y_range=(0, y), plot_width=x, plot_height=y) plot.axis.visible = False plot.toolbar_location = None plot.min_border = 0 plot.image([np.flipud(image)], x=0, y=0, dw=x, dh=y, palette=palette) return plot

## 测试

 URL = lambda name: 'https://raw.githubusercontent.com/coells/100days/master/resource/day 96 - %s.jpg' % (name,) # URL = lambda name: './resource/day 96 - %s.jpg' % (name,) image_dither('./resource/day 96 - valinka.jpg')
• 5
点赞
• 1
评论
• 5
收藏
• 一键三连
• 扫一扫，分享海报

03-25
04-11 9104

05-18
04-01 8111
07-09
04-05
06-08 473
09-28 5925
01-05 5973
02-01 1478
04-01 1万+
05-28 9313
07-13 308
10-17 86