Skip to content

Instantly share code, notes, and snippets.

@onatbas
Last active April 21, 2019 16:27
Show Gist options
  • Save onatbas/cef34e55864dc18af3ac40f9440382fb to your computer and use it in GitHub Desktop.
Save onatbas/cef34e55864dc18af3ac40f9440382fb to your computer and use it in GitHub Desktop.
floyd-steinberg dithering samples
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from matplotlib import pyplot as plt\n",
"import cv2\n",
"\n",
"def getDimensions(copy):\n",
" return len(copy), len(copy[0])\n",
"\n",
"def find_closest_palette_color(y,x,copy):\n",
" return 255 if copy[y][x] > 127 else 0\n",
"\n",
"def add(y,x,color,copy):\n",
" ly, lx = getDimensions(copy)\n",
" if x >= 0 and x < lx and y >= 0 and y < ly:\n",
" copy[y][x] = max(0, min(copy[y][x] + int(color), 255))\n",
" \n",
"def show(image, name):\n",
" plt.imshow(image)\n",
" plt.title(name)\n",
" plt.show()\n",
"\n",
"def writeImage(image, name):\n",
" cv2.imwrite(name, image);\n",
"\n",
"def loadAndResize(name):\n",
" img = cv2.cvtColor(cv2.imread(name), cv2.COLOR_BGR2GRAY)\n",
"\n",
" height, width = img.shape\n",
" scale = min(1, 9999 / max(height, width))\n",
"\n",
" return cv2.resize(img, (int(width * scale), int(height * scale)))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def dither(copy):\n",
" ly, lx = getDimensions(copy)\n",
"\n",
" for y in range(0, ly):\n",
" for x in range(0, lx):\n",
"\n",
" oldpixel = copy[y][x]\n",
" newpixel = find_closest_palette_color(y, x, copy)\n",
" copy[y][x] = newpixel\n",
" quant_error = oldpixel - newpixel\n",
" add(y, x+1, quant_error * 7 / 16, copy);\n",
" add(y+1, x+1, quant_error * 1 / 16, copy);\n",
" add(y+1, x, quant_error * 5 / 16, copy);\n",
" add(y+1, x-1, quant_error * 3 / 16, copy);"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def process(path, extension):\n",
" \n",
" img = loadAndResize(path + extension)\n",
"\n",
" show(img, path)\n",
" dither(img)\n",
" show(img, path + \" (DITHERED)\")\n",
" \n",
" writeImage(img, path + \"_2\" + extension)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"list = [[\"/Users/onatbas/Desktop/diffuse/IMG_0137\", \".JPG\"],\n",
" [\"/Users/onatbas/Desktop/diffuse/dave\", \".jpg\"],\n",
" [\"/Users/onatbas/Desktop/diffuse/g\", \".bmp\"],\n",
" [\"/Users/onatbas/Desktop/diffuse/ikili\", \".jpg\"],\n",
" [\"/Users/onatbas/Desktop/diffuse/prof\", \".jpg\"],\n",
" [\"/Users/onatbas/Desktop/diffuse/IMG_7379\", \".JPG\"],\n",
" [\"/Users/onatbas/Desktop/diffuse/gard\", \".jpeg\"],\n",
" [\"/Users/onatbas/Desktop/diffuse/onat\", \".jpg\"]]\n",
"\n",
"for name in list:\n",
" process(name[0], name[1]);"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment