Skip to content

Commit

Permalink
Merge pull request #75 from litlnemo/Atkinson
Browse files Browse the repository at this point in the history
  • Loading branch information
rbaron authored Aug 26, 2024
2 parents 001863d + 73f3c47 commit f99c610
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 4 deletions.
38 changes: 35 additions & 3 deletions catprinter/img.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@


def floyd_steinberg_dither(img):
'''Applies the Floyd-Steinberf dithering to img, in place.
'''Applies the Floyd-Steinberg dithering to img, in place.
img is expected to be a 8-bit grayscale image.
Algorithm borrowed from wikipedia.org/wiki/Floyd%E2%80%93Steinberg_dithering.
Expand All @@ -29,9 +29,36 @@ def adjust_pixel(y, x, delta):
adjust_pixel(y + 1, x + 1, err * 1/16)
return img

def atkinson_dither(img):
'''
Applies the Atkinson dithering to img, in place.
img is expected to be a 8-bit grayscale image.
Algorithm from https://tannerhelland.com/2012/12/28/dithering-eleven-algorithms-source-code.html
'''
h, w = img.shape

def adjust_pixel(y, x, delta):
if y < 0 or y >= h or x < 0 or x >= w:
return
img[y][x] = min(255, max(0, img[y][x] + delta))

for y in range(h):
for x in range(w):
new_val = 255 if img[y][x] > 127 else 0
err = img[y][x] - new_val
img[y][x] = new_val
adjust_pixel(y, x + 1, err * 1/8)
adjust_pixel(y, x + 2, err * 1/8)
adjust_pixel(y + 1, x - 1, err * 1/8)
adjust_pixel(y + 1, x, err * 1/8)
adjust_pixel(y + 1, x + 1, err * 1/8)
adjust_pixel(y + 2, x, err * 1/8)
return img


def halftone_dither(img):
'''Applies Haltone dithering using different sized circles
'''Applies Halftone dithering using different sized circles
Algorithm is borrowed from https://github.com/GravO8/halftone
'''
Expand Down Expand Up @@ -106,7 +133,12 @@ def read_img(
),
interpolation=cv2.INTER_AREA)

if img_binarization_algo == 'floyd-steinberg':
if img_binarization_algo == 'atkinson':
logger.info('⏳ Applying Atkinson dithering to image...')
resized = atkinson_dither(resized)
logger.info('✅ Done.')
resized = resized > 127
elif img_binarization_algo == 'floyd-steinberg':
logger.info('⏳ Applying Floyd-Steinberg dithering to image...')
resized = floyd_steinberg_dither(resized)
logger.info('✅ Done.')
Expand Down
2 changes: 1 addition & 1 deletion print.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def parse_args():
choices=['debug', 'info', 'warn', 'error'], default='info')
args.add_argument('-b', '--img-binarization-algo', type=str,
choices=['mean-threshold',
'floyd-steinberg', 'halftone', 'none'],
'floyd-steinberg', 'atkinson', 'halftone', 'none'],
default='floyd-steinberg',
help=f'Which image binarization algorithm to use. If \'none\' \
is used, no binarization will be used. In this case the \
Expand Down

0 comments on commit f99c610

Please sign in to comment.