4-1공부/DIP

[중간고사] 4장 - 양자화 (Quantization)

KGW2027 2023. 3. 31. 21:43
728x90
반응형

※ TV Standards
 화질에 대해 작성할 때 1080p, 1080i 같은 말을 사용한다.
 여기서 앞의 숫자는 세로방향 픽셀 수, p와 i은 scanning mode를 의미한다.

 i는 Interlaceed Scanning Mode로, 짝수번째 줄과 홀수번째 줄을 따로따로 출력한다.
만약, 1080i의 60frame 라면, 실제로는 짝수 30frame, 홀수 30frame으로 60frame이 되고, 실제 장면의 수는 30프레임이다.
착시를 이용한 출력 방법으로, 빠르게 변화하는 영상에서는 방식으로 인한 줄무늬?가 생길 수 있다.

p는 Progressive Scanning Mode로, 모든 라인을 한번에 출력한다.
만약, 1080p의 60frame이라면, 실제 장면의 수는 60프레임이다.

양자화 ( Quantization )
 연속된 신호의 디지털 전송을 위해 이산 신호로 변환(샘플링) 했다.
양자화는 이러한 신호를 압축하여 그 정보를 단순화 시키는 것이 목표이다. ( 손실압축 )
이 때, 전송받은 상대가 다시 원래 신호를 복구 할 수 있어야 하므로, 역-양자화도 가능해야 한다.

균일 양자화 ( Uniform Quantization )
 양자화 출력 값들의 간격이 일정한 경우, 균일 양자화라고 한다.

 

비-균일 양자화 ( Non-Uniform Quantization )
  균일 양자화보다 더 기존 디테일을 잘 유지하면서 양자화하기 위한 기법이다.

1) Lloyd-Max Quantizer ( Optimum Mean Square Quantizer, 로이드-맥스 양자화 )
 : 구간 [t0, tl]에 대해, 가장 MSE를 최소화 할 수 있는 구간으로 양자화를 진행한다.

2) Companding ( 압축 - 균일 양자화 - 확장 )
 : f(x)를 통해 압축한 함수를 Uniform Quantization을 거치고 다시 확장해서 복구하는 방식의 양자화.

False Contouring 
 : 색을 표현하는 레벨 수를 줄이면서(손실압축), 원본에는 없던 윤곽선(Contouring)이 생기는 현상
 -> 이를 해결하기 위해 디더링 기법을 사용한다.

 

Dithering
 : False Contour를 숨기기 위해 고안된 양자화 전/후처리 기법

1) Pseudo-random Noise Quantization 
 :  양자화 하기 이전에 노이즈를 더하고, 역양자화 후에 그 노이즈를 빼는 방법으로 디테일을 유지하는 방법.
1. (M, N) 사이즈의 이미지 I, 그와 같은 사이즈의 노이즈 N이 있다.
2. I+N을 k 비트로 양자화 한다. ( 이 결과를 O라 하자. )
3. O와 N을 전송하고, 수신자는 O를 역양자화하고 거기서 N을 뺀다.

2) Halftone Image Generation
 : 중간 색조인 A를 구하고, 0과 A 사이의 값으로 구성된 노이즈를 이미지에 더하고 1 bit 양자화 한다.
 결과물은 흑과 백 1비트로 나오지만, 사용하는 노이즈 행렬에 따라 흑백이미지의 디테일이 남는다.

가장 좌측은 오리지널 bmp, 왼쪽 사진은 4비트 양자화, 오른쪽 사진은 PRN을 적용한 4비트 양자화
왼쪽 - 1비트 양자화, 중간 - 양자화 결과에서 노이즈를 뺀 것, 오른쪽 - 노이즈 행렬

팔부분을 집중적으로 봤을 때, 기본 양자화는 컨투어링이 보이지만, PRN은 노이즈로 인해 컨투어링이 보이지 않는다.
Halftone을 이용한 1비트 양자화는, 검은색과 흰색만 있음에도, 묘하게 디테일이 살아있는 느낌을 준다.

img = cv2.imread('lenna.bmp', cv2.IMREAD_GRAYSCALE)

# 4-bit Quantizer
quantizer_level = (1 << 4)
quantized = (np.floor_divide(img, 256//qunatizer_level) * (255//(quantizer_level-1))).astype(np.uint8)

# 4-bit Quantizer ( with PRN )
noise = np.random.randint(-quantization_level//2, quantization_level//2, size=img.shape)
noisy_img = img.astype(np.int16) + noise
noisy_img = np.clip(noisy_img, 0, 255).astype(np.uint8)
quantized_img = (np.floor_divide(noisy_img, 256//quantization_level) * (255//(quantization_level-1))).astype(np.uint8)
# Halftone ( 1-bit Quantization )
oversampled_img = cv2.resize(img, (1024, 1024), interpolation=cv2.INTER_CUBIC)

H1 = np.array([[40, 60, 150, 90, 10],
              [80, 170, 240, 200, 110],
              [140, 210, 250, 220, 130],
              [120, 190, 230, 180, 70],
              [20, 100, 160, 50, 30]])
H1 = np.tile(H1, (205, 205))

H2 = np.array([[52, 44, 36, 124, 132, 140, 148, 156],
              [60, 4, 28, 116, 200, 228, 236, 164],
              [68, 12, 20, 108, 212, 252, 244, 172],
              [76, 84, 92, 100, 204, 196, 188, 180],
              [132, 140, 148, 156, 52, 44, 36, 124],
              [200, 228, 236, 164, 60, 4, 28, 116],
              [212, 252, 244, 172, 68, 12, 20, 108],
              [204, 196, 188, 180, 76, 84, 92, 100]])
H2 = np.tile(H2, (128, 128))

h1 = oversampled_img + H1[:1024, :1024]
h2 = oversampled_img + H2

threshold = (1 << 8) >> 1

h1_halftone = np.zeros_like(h1, dtype=np.uint8)
h1_halftone[h1 >= threshold] = 255
h2_halftone = np.zeros_like(h2, dtype=np.uint8)
h2_halftone[h2 >= threshold] = 255

 

벡터 양자화 ( Vector Quantization ) - 2차원 이상에서의 양자화
: 상관도에 따라 클러스터링 하는 방식 ( 비슷한 색을 같은 색으로 합치는 등.. )


색 양자화 ( Color Quantization ) - 크게 다르지 않음.
 : RGB를 각각 양자화 하고 다시 합치는 방식. ( 전처리로 퓨리에변환, 코사인변환, YCbCr 변환 등을 할 수 있다.)

다른 기법 없이, R,G,B 각 채널을 모두 1비트 양자화 하고 합치는 과정 및 결과

 

728x90
반응형

'4-1공부 > DIP' 카테고리의 다른 글

[중간고사] 6장. 영상 개선  (0) 2023.04.13
[중간고사] 5장 - 이미지 변환  (0) 2023.03.31
[중간고사] 3장 - 샘플링  (0) 2023.03.31
[중간고사] 2장 - 광도와 색채  (0) 2023.03.30
[중간고사] 1장 - 인지  (0) 2023.03.30