wiki page:
https://en.wikipedia.org/wiki/Floyd–Steinberg_dithering
youtube tutorial (thank you, good job!) :
https://www.youtube.com/watch?v=0L2n8Tg2FwI&t=0s&list=WL&index=151
https://www.youtube.com/watch?v=0L2n8Tg2FwI&t=0s&list=WL&index=151
In the source code, there are two functions those are :
dithering_gray, dithering_color
One is for Gary image (1 channel), other is for color (3 channel).
It's very easy to use, just call function~ ^^
import cv2
import numpy as np
def minmax(v):
if v > 255:
v = 255
if v < 0:
v = 0
return v
def dithering_gray(inMat, samplingF):
#https://en.wikipedia.org/wiki/Floyd–Steinberg_dithering
#https://www.youtube.com/watch?v=0L2n8Tg2FwI&t=0s&list=WL&index=151
#input is supposed as color
# grab the image dimensions
h = inMat.shape[0]
w = inMat.shape[1]
# loop over the image
for y in range(0, h-1):
for x in range(1, w-1):
# threshold the pixel
old_p = inMat[y, x]
new_p = np.round(samplingF * old_p/255.0) * (255/samplingF)
inMat[y, x] = new_p
quant_error_p = old_p - new_p
# inMat[y, x+1] = minmax(inMat[y, x+1] + quant_error_p * 7 / 16.0)
# inMat[y+1, x-1] = minmax(inMat[y+1, x-1] + quant_error_p * 3 / 16.0)
# inMat[y+1, x] = minmax(inMat[y+1, x] + quant_error_p * 5 / 16.0)
# inMat[y+1, x+1] = minmax(inMat[y+1, x+1] + quant_error_p * 1 / 16.0)
inMat[y, x+1] = minmax(inMat[y, x+1] + quant_error_p * 7 / 16.0)
inMat[y+1, x-1] = minmax(inMat[y+1, x-1] + quant_error_p * 3 / 16.0)
inMat[y+1, x] = minmax(inMat[y+1, x] + quant_error_p * 5 / 16.0)
inMat[y+1, x+1] = minmax(inMat[y+1, x+1] + quant_error_p * 1 / 16.0)
# quant_error := oldpixel - newpixel
# pixel[x + 1][y ] := pixel[x + 1][y ] + quant_error * 7 / 16
# pixel[x - 1][y + 1] := pixel[x - 1][y + 1] + quant_error * 3 / 16
# pixel[x ][y + 1] := pixel[x ][y + 1] + quant_error * 5 / 16
# pixel[x + 1][y + 1] := pixel[x + 1][y + 1] + quant_error * 1 / 16
# return the thresholded image
return inMat
def dithering_color(inMat, samplingF):
#https://en.wikipedia.org/wiki/Floyd–Steinberg_dithering
#https://www.youtube.com/watch?v=0L2n8Tg2FwI&t=0s&list=WL&index=151
#input is supposed as color
# grab the image dimensions
h = inMat.shape[0]
w = inMat.shape[1]
# loop over the image
for y in range(0, h-1):
for x in range(1, w-1):
# threshold the pixel
old_b = inMat[y, x, 0]
old_g = inMat[y, x, 1]
old_r = inMat[y, x, 2]
new_b = np.round(samplingF * old_b/255.0) * (255/samplingF)
new_g = np.round(samplingF * old_g/255.0) * (255/samplingF)
new_r = np.round(samplingF * old_r/255.0) * (255/samplingF)
inMat[y, x, 0] = new_b
inMat[y, x, 1] = new_g
inMat[y, x, 2] = new_r
quant_error_b = old_b - new_b
quant_error_g = old_g - new_g
quant_error_r = old_r - new_r
inMat[y, x+1, 0] = minmax(inMat[y, x+1, 0] + quant_error_b * 7 / 16.0)
inMat[y, x+1, 1] = minmax(inMat[y, x+1, 1] + quant_error_g * 7 / 16.0)
inMat[y, x+1, 2] = minmax(inMat[y, x+1, 2] + quant_error_r * 7 / 16.0)
inMat[y+1, x-1, 0] = minmax(inMat[y+1, x-1, 0] + quant_error_b * 3 / 16.0)
inMat[y+1, x-1, 1] = minmax(inMat[y+1, x-1, 1] + quant_error_g * 3 / 16.0)
inMat[y+1, x-1, 2] = minmax(inMat[y+1, x-1, 2] + quant_error_r * 3 / 16.0)
inMat[y+1, x, 0] = minmax(inMat[y+1, x, 0] + quant_error_b * 5 / 16.0)
inMat[y+1, x, 1] = minmax(inMat[y+1, x, 1] + quant_error_g * 5 / 16.0)
inMat[y+1, x, 2] = minmax(inMat[y+1, x, 2] + quant_error_r * 5 / 16.0)
inMat[y+1, x+1, 0] = minmax(inMat[y+1, x+1, 0] + quant_error_b * 1 / 16.0)
inMat[y+1, x+1, 1] = minmax(inMat[y+1, x+1, 1] + quant_error_g * 1 / 16.0)
inMat[y+1, x+1, 2] = minmax(inMat[y+1, x+1, 2] + quant_error_r * 1 / 16.0)
# quant_error := oldpixel - newpixel
# pixel[x + 1][y ] := pixel[x + 1][y ] + quant_error * 7 / 16
# pixel[x - 1][y + 1] := pixel[x - 1][y + 1] + quant_error * 3 / 16
# pixel[x ][y + 1] := pixel[x ][y + 1] + quant_error * 5 / 16
# pixel[x + 1][y + 1] := pixel[x + 1][y + 1] + quant_error * 1 / 16
# return the thresholded image
return inMat
#read image
inMat = cv2.imread('iu.jpg') #lena.png')
#color ditering
outMat_color = dithering_color(inMat.copy(), 1)
cv2.imwrite('out_color.jpg', outMat_color)
#gray ditering
grayMat = cv2.cvtColor(inMat, cv2.COLOR_BGR2GRAY)
outMat_gray = dithering_gray(grayMat.copy(), 1)
cv2.imwrite('out_gray.jpg', outMat_gray)
Amazing experience on reading your article. It is really nice and informative.
ReplyDeletePython Training in Chennai
Python course in Chennai
Big data training in chennai
JAVA Training in Chennai
Selenium Training in Chennai
Python Training in Chennai
Python Course in Chennai
I like the blog format as you create user engagement in the complete article. Thanks for the informative posts.
ReplyDeleteBig Data Hadoop Training In Chennai | Big Data Hadoop Training In anna nagar | Big Data Hadoop Training In omr | Big Data Hadoop Training In porur | Big Data Hadoop Training In tambaram | Big Data Hadoop Training In velachery
great job. really appreciate it.
ReplyDelete