[영상통신] 압축 기술

압축 기술

문제 1 : 차분 데이터의 Histogram

1. Grayscale Lenna에서 차분 값 Δ=X-(A+C)/2를 구한다.

2. Δ는 음수값이 나오므로 +128을 add 한다. 다음에 음수값은 0으로, 255를 초과하면 255로 clipping 해야 함.

3. 차분 데이터의 histogram을 출력한다.

 

정답 코드

#include <iostream>

// ...

int main(void)
{
	// ...

	int histogram[256];
	for (int i = 0; i < 256; i++) // 초기화
		histogram[i] = 0;

	for (int i = 1; i < Height - 1; i++) {
		for (int j = 1; j < Width - 1; j++) {
			int sum = *(YBuf + i * Width + j) - ((*(YBuf + i * Width + j - 1) + *(YBuf + (i - 1) * Width + j)) / 2);
			sum = sum + 128;
			if (sum > 255) sum = 255;
			if (sum < 0) sum = 0;
			histogram[sum]++;
		}
	}

	printf(" Y frequency \n");
	for (int x = 0; x < 256; x++)
		printf(" %d : %d \n", x, histogram[x]);

	int total = 0;
	for (int i = 0; i < 256; i++)
		total += histogram[i];


	printf(" total : %d \n", total);

	// ...
}

 

 

결과

더보기

Y frequency
 0 : 0
 1 : 0
 2 : 0
 3 : 0
 4 : 0
 5 : 0
 6 : 0
 7 : 0
 8 : 0
 9 : 0
 10 : 0
 11 : 0
 12 : 0
 13 : 0
 14 : 0
 15 : 0
 16 : 0
 17 : 0
 18 : 0
 19 : 0
 20 : 0
 21 : 0
 22 : 0
 23 : 0
 24 : 0
 25 : 0
 26 : 0
 27 : 0
 28 : 0
 29 : 0
 30 : 0
 31 : 0
 32 : 0
 33 : 0
 34 : 0
 35 : 1
 36 : 1
 37 : 1
 38 : 0
 39 : 0
 40 : 0
 41 : 3
 42 : 1
 43 : 4
 44 : 3
 45 : 1
 46 : 2
 47 : 3
 48 : 1
 49 : 6
 50 : 6
 51 : 2
 52 : 5
 53 : 4
 54 : 8
 55 : 6
 56 : 5
 57 : 7
 58 : 6
 59 : 8
 60 : 11
 61 : 12
 62 : 8
 63 : 9
 64 : 10
 65 : 13
 66 : 6
 67 : 15
 68 : 10
 69 : 12
 70 : 14
 71 : 10
 72 : 12
 73 : 12
 74 : 12
 75 : 12
 76 : 15
 77 : 24
 78 : 17
 79 : 19
 80 : 23
 81 : 29
 82 : 29
 83 : 37
 84 : 26
 85 : 34
 86 : 34
 87 : 47
 88 : 47
 89 : 56
 90 : 61
 91 : 57
 92 : 80
 93 : 83
 94 : 95
 95 : 105
 96 : 95
 97 : 122
 98 : 138
 99 : 132
 100 : 143
 101 : 203
 102 : 216
 103 : 239
 104 : 258
 105 : 284
 106 : 308
 107 : 385
 108 : 360
 109 : 469
 110 : 480
 111 : 592
 112 : 659
 113 : 739
 114 : 956
 115 : 997
 116 : 1246
 117 : 1482
 118 : 1776
 119 : 2221
 120 : 2948
 121 : 4001
 122 : 5686
 123 : 7914
 124 : 11208
 125 : 15657
 126 : 20329
 127 : 24834
 128 : 27041
 129 : 26441
 130 : 23124
 131 : 18222
 132 : 13466
 133 : 9821
 134 : 7095
 135 : 5112
 136 : 3702
 137 : 2933
 138 : 2207
 139 : 1789
 140 : 1448
 141 : 1179
 142 : 992
 143 : 856
 144 : 732
 145 : 666
 146 : 594
 147 : 501
 148 : 426
 149 : 373
 150 : 316
 151 : 300
 152 : 239
 153 : 259
 154 : 215
 155 : 174
 156 : 148
 157 : 143
 158 : 147
 159 : 124
 160 : 123
 161 : 101
 162 : 96
 163 : 94
 164 : 68
 165 : 62
 166 : 60
 167 : 58
 168 : 55
 169 : 42
 170 : 41
 171 : 39
 172 : 34
 173 : 24
 174 : 19
 175 : 20
 176 : 18
 177 : 12
 178 : 10
 179 : 9
 180 : 19
 181 : 13
 182 : 5
 183 : 6
 184 : 2
 185 : 3
 186 : 4
 187 : 3
 188 : 1
 189 : 2
 190 : 2
 191 : 1
 192 : 2
 193 : 1
 194 : 0
 195 : 1
 196 : 2
 197 : 2
 198 : 2
 199 : 0
 200 : 1
 201 : 0
 202 : 0
 203 : 0
 204 : 1
 205 : 0
 206 : 0
 207 : 0
 208 : 0
 209 : 0
 210 : 0
 211 : 0
 212 : 0
 213 : 0
 214 : 0
 215 : 0
 216 : 0
 217 : 0
 218 : 0
 219 : 0
 220 : 0
 221 : 0
 222 : 0
 223 : 0
 224 : 0
 225 : 0
 226 : 0
 227 : 0
 228 : 0
 229 : 0
 230 : 0
 231 : 0
 232 : 0
 233 : 0
 234 : 0
 235 : 0
 236 : 0
 237 : 0
 238 : 0
 239 : 0
 240 : 0
 241 : 0
 242 : 0
 243 : 0
 244 : 0
 245 : 0
 246 : 0
 247 : 0
 248 : 0
 249 : 0
 250 : 0
 251 : 0
 252 : 0
 253 : 0
 254 : 0
 255 : 0
 total : 260100

테두리 처리를 안 했기에 Total이 512*512가 나오지 않고 더 작은 값이 나온다.

 

문제 2 : 상관성 (Correlation) 계산

Grayscale Lenna의 상관성을 영상으로 저장해라.

CORR=[0,1]이므로, [0, 255]를 만들기 위해서, 255를 곱해서 영상을 만들면 된다.

 

 

정답 코드

#include <iostream>

// ...

int main(void)
{
	// ...

	for (int i = 1; i < Height; i++) {
		for (int j = 1; j < Width; j++) {
			float corr = 1.0 / (1 + abs(*(YBuf + i * Width + j) - *(YBuf + i * Width + j - 1)));
			corr = corr * 255;
			*(Out + i * Width + j) = (BYTE)corr;
		}
	}

	// ...
}

 

결과

 

 

문제 3 : JPEG 구현

전체 image가 아닌, 8x8 image block으로 실습한다.

(A) FDCT (Forward DCT)

(B) F(u, v)를 양자화 (Quantization)

(C) QDCT을 zigzag scan → 1-D Linearized Vector를 만듦

정답 코드

#include <iostream>

// ...

int main(void)
{
	// ...

	// 8x8 Y pixel value
	BYTE fblock[8][8] = { {137, 139, 139, 136, 134, 137, 145, 152 },
				{137, 137, 138, 138, 135, 136, 143, 152 },
				{137, 139 ,140, 139 ,134, 144, 145, 150 },
				{134, 140, 140, 138 ,140, 144, 145, 146},
				{137, 139, 141 ,136 ,134, 137, 145, 140 },
				{137, 139, 140, 140 ,144, 146, 144, 133},
				{140, 140, 142, 146, 148, 143, 134 ,128 },
			 	{142, 139, 139, 145, 149, 143, 132, 128 } };



	// Quantization Table
	static BYTE QTable[8][8] = { {16, 11, 10, 16, 24, 40, 51, 61 },
					{12, 12, 14, 19, 26, 58, 60, 55 },
					{14, 13 ,16, 24 ,40, 57, 69, 56 },
				   	{14, 17, 22, 29 ,51, 87, 80, 62},
				   	{18, 22, 37 ,56 ,68, 109, 103, 77 },
					{23, 35, 55, 64 ,81, 101, 113, 92},
				  	{49, 64, 78, 87, 103, 121, 120 ,101 },
					{72, 92, 95, 98, 112, 100, 103, 99 } };

	static BYTE zigzag[8][8] = {
	0, 1, 5, 6,14,15,27,28,
	2, 4, 7,13,16,26,29,42,
	3, 8,12,17,25,30,41,43,
	9,11,18,24,31,40,44,53,
	10,19,23,32,39,45,52,54,
	20,22,33,38,46,51,55,60,
	21,34,37,47,50,56,59,61,
	35,36,48,49,57,58,62,63 };

	// ================= A =================
	printf("\n ================= A ================= \n");
	double F[8][8] = { 0.0, };
	#define PI (3.14)

	for (int u = 0; u < 8; u++)
	{
		for (int v = 0; v < 8; v++)
		{
			for (int i = 0; i < 8; i++)
			{
				for (int j = 0; j < 8; j++)
				{
					F[u][v] += fblock[i][j] * cos(((2 * i + 1) * u * PI) / (2 * 8)) * cos(((2 * j + 1) * v * PI) / (2 * 8));
				}
			}
		}
	}

	printf("\n");
	for (int u = 0; u < 8; u++)
	{
		for (int v = 0; v < 8; v++)
		{
			printf("%0.2f ", F[u][v]);
		}
		printf("\n");
	}


	// ================= B =================
	printf("\n ================= B ================= \n");
	int QDCT[8][8] = { 0.0, };

	for (int u = 0; u < 8; u++)
	{
		for (int v = 0; v < 8; v++)
		{
			QDCT[u][v] = (int)(F[u][v] / QTable[u][v] + 0.5);
		}
	}

	printf("\n");
	for (int u = 0; u < 8; u++)
	{
		for (int v = 0; v < 8; v++)
		{
			printf("%d ", QDCT[u][v]);
		}
		printf("\n");
	}


	// ================= C =================
	printf("\n ================= C ================= \n");
	int DCT_coeff_zizag[64] = { 0, };

	for (int u = 0; u < 8; u++)
	{
		for (int v = 0; v < 8; v++)
		{
			DCT_coeff_zizag[zigzag[u][v]] = QDCT[u][v];
		}
	}

	for (int i = 0; i < 64; i++)
		printf("%d ", DCT_coeff_zizag[i]);
	printf("\n===========================================\n");


	// ...
}

 

 

결과

 

문제 4 : 엔트로피(Entropy) 계산

1. Symbol s1, s2, s3, s4의 확률 p는 각각 0.45, 0.25, 0.1, 0.2이다. Entropy H을 구하세요.

2. 확률값을 배열(array)에 저장한 후에 코딩할 것.

3. 정답 H = 1.814 bits

 

정답 코드

#include <iostream>

// ...

int main(void)
{
	// ...

	double Symbol[4] = { 0.45, 0.25, 0.1, 0.2 };
	double H = 0;
	for (int i = 0; i < 4; i++)
	{
		H += Symbol[i] * (log10(Symbol[i]) / log10(2));
	}
	printf(" H : %lf\n", -H);
    
	// ...
}

 

결과

'공부 > 영상통신' 카테고리의 다른 글

[영상통신] Bitwise Operation  (0) 2024.12.15
[영상통신] 영역처리  (0) 2024.12.15
[영상통신] Pixel 처리  (0) 2024.12.15