본문 바로가기
Image Processing/Project

[Image Processing] 1. Python으로 Dither 만들기: Floyd Steinberg Dithering

by 리미와감자 2023. 11. 15.

1. Python으로 Dither 만들기: Floyd Steinberg Dithering

 

지난 글에 Bit Depth를 줄이는 방법으로 Truncation과 Round 두 가지 방법을 확인했다. 이번에는 실제로 Dither를 만들어 볼 것이다.

 

Floyd Steinberg Dithering 알고리즘을 구현할 것이다.

 

https://rimeestore.tistory.com/entry/Error-Diffusion%EC%9D%B4%EB%9E%80

 

Error Diffusion이란?

Dithering Dithering이란 Bit Depth가 높은 영상데이터를 Bit Depth가 낮은 영상데이터로 바꿀 때 적용하는 알고리즘 중 하나이다. 예를 들어, 12 Bit 영상데이터는 RGB 각각 0 ~ 4095까지 총 4096단계의 밝기 Value

rimeestore.tistory.com

 

위 링크를 따라들어가면 Floyd Steinberg Dithering이 무엇인지 자세히 나와있다.

 


1.1 Floyd Steinberg Dithering

 

Code

import numpy as np
from PIL import Image

img = Image.open('in_img/Lenna.jpg') # Import Image
img_arr = np.array(img) # Image to Array
# print(np.shape(img_arr)) # (height, width, pixel)

img_height = np.shape(img_arr)[0]
img_width = np.shape(img_arr)[1]

fsd_img_arr = img_arr / 64

# Floyd Steinberg Dithering
for i in range(img_height):
    for j in range(img_width):
        old_pix = fsd_img_arr[i][j].copy()
        new_pix = np.round( old_pix )
        fsd_img_arr[i][j] = new_pix
        error = old_pix - new_pix
        if j < img_width - 1:
            fsd_img_arr[i, j + 1] += error * 7 / 16
        if i < img_height - 1:
            if j > 0:
                fsd_img_arr[i + 1, j - 1] += error * 3 / 16
                fsd_img_arr[i + 1, j] += error * 5 / 16
            if j < img_width - 1:
                fsd_img_arr[i + 1, j + 1] += error / 16

fsd_img_arr = np.clip(fsd_img_arr, 0, 3) # Clip (min = 0, max = 3)
fsd_img_arr = fsd_img_arr * 64
fsd_img_arr = fsd_img_arr.astype(np.uint8) # float to int
fsd_img = Image.fromarray(fsd_img_arr) # Array to Image

fsd_img.save('out_img/Lenna_Floyd_Steinberg.jpg') # Save Image
fsd_img.show() # Show Image

 

 


최종 결과

원본 이미지(Lenna, 8bit Image)
Truncation(2bit), Round(2bit), Floyd Steinberg Dithering(2bit)

 

확실히 Floyd Steinberg Dithering이 눈으로 봤을 때는 원본 이미지와 가장 비슷하게 보인다.

댓글