10/26/2018

Dithering python opencv source code (Floyd–Steinberg dithering)

This is dithering example, it make image like a stippling effect.


I referenced to blew website.
wiki page:
https://en.wikipedia.org/wiki/Floyd–Steinberg_dithering 
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)




5 comments:

  1. Replies
    1. I am glad that I saw this post. It is informative blog for us and we need this type of blog thanks for share this blog, Keep posting such instructional blogs and I am looking forward for your future posts. Python Projects for Students Data analytics is the study of dissecting crude data so as to make decisions about that data. Data analytics advances and procedures are generally utilized in business ventures to empower associations to settle on progressively Python Training in Chennai educated business choices. In the present worldwide commercial center, it isn't sufficient to assemble data and do the math; you should realize how to apply that data to genuine situations such that will affect conduct. In the program you will initially gain proficiency with the specialized skills, including R and Python dialects most usually utilized in data analytics programming and usage; Python Training in Chennai at that point center around the commonsense application, in view of genuine business issues in a scope of industry segments, for example, wellbeing, promoting and account. Project Center in Chennai

      Delete
  2. great job. really appreciate it.

    ReplyDelete
  3. wonderful article contains lot of valuable information. Very interesting to read this article.I would like to thank you for the efforts you had made for writing this awesome article.
    This article resolved my all queries.good luck an best wishes to the team members.learn digital marketing use these following link
    Digital Marketing Course in Chennai

    ReplyDelete