언어/C

C언어 영상처리 - DPCM

이게될까 2024. 5. 23. 21:07
728x90
728x90

뭉쳐있는 영역은 비슷한 픽셀을 가진다! -> 차이만 전달해서 용량을 줄여보자!

제일 왼쪽 값에서 차이를 구하고, 그걸 5구간으로 나눠서 용량을 줄인다!

코드에서 q가 0 ~ q-1까지를 하나로 본다는 뜻 입니다.

더보기

중간 (128) 있다는 가정 하에 차이(-28) 전송

 

정보 손실 없는 압축 == 무손실 압축

 

여기는 무손실 압축 ( q가 없다)

 

비슷한 값이므로 확률적으로 예측한다.

 

데이터를 깎는다 ==Quantization = 양자화

데이터를 깎아서 적은 양의 데이터를 주고 받게 한다.

작업이 있으면 손실 압축 (q)

 

양자화가 커지면 데이터 손실도 늘어난다.

Prediction Error까지는 무손실 압축

Quantization 손실 압축 - 정수 단위로 바뀐다.

 

손실이 일어난다.

 

두번째는 0 아닌가?

받은 기준으로 오차를 내보낸다.

 

보내는 쪽은 보내는 것과 받는 모두 진행

-> 받는 영상이 존재한다. -> 받는 기준으로 진행

 

인코더 - 압축 + 압축 해제

디코더 - 압축 해제

 

  압축 숫자(q) 바꾸면 (5에서 10으로) 손실이 커지지만 영상 크기도 그만큼 작아진다.

또한 같은 값이 나올 확률이 점점 커진다.

 

-29 q = 30일때 0 된다.

왼쪽에서 진행하는 것과 위에서 진행하는 것의 차이가 크다.

 

현재 것을 비슷하게 만드는 것이 핵심이다.

 

어디서 가져올지 테스트를 해보겠다!

-> 디코더에서는 있는 방법이 없다. 디코더에서는 어디서 정보를 받아 왔는지 방법이 없다.

 

 

RENC == RDEC

이게 맞아야 된다.

 

보낸 비트의 수도 평가 요소이다.

 

PSNR - 복원 영상의 화질

 

두개가 평가 지표이다.

 

 

 

 

 

void DPCMEncoder(double* org, int* prsy, int q, BITMAPFILEHEADER bmpFile, BITMAPINFOHEADER bmpInfo) {
	int width = bmpInfo.biWidth, height = bmpInfo.biHeight, size = bmpInfo.biSizeImage;
	double* pe, *rs;
	pe = (double*)calloc(width * height, sizeof(double));
	rs = (double*)calloc(width * height, sizeof(double));
	for (int j = 0; j < height; j++) {
		for (int i = 0; i < width; i++) {
			if (i == 0) {
				pe[j * width + i] = org[j * width + i] - 128;
				prsy[j * width + i] = (int)(pe[j * width + i] / q);
				rs[j * width + i] = 128 + prsy[j * width + i] * q;
			}
			else {
				pe[j * width + i] = org[j * width + i] - rs[j * width + i - 1];
				prsy[j * width + i] = (int)(pe[j * width + i] / q);
				rs[j * width + i] = rs[j * width + i - 1] + prsy[j * width + i] * q;
			}
			
		}
	}
	makeOutFile(bmpFile, bmpInfo, "DPCMEncoder.bmp", rs);
	free(rs);
	free(pe);
}

void DPCMDecoder(double* out, int* prsy, int q, BITMAPFILEHEADER bmpFile, BITMAPINFOHEADER bmpInfo) {
	int width = bmpInfo.biWidth, height = bmpInfo.biHeight, size = bmpInfo.biSizeImage;
	double * rs;
	rs = (double*)calloc(width * height, sizeof(double));
	for (int j = 0; j < height; j++) {
		for (int i = 0; i < width; i++) {
			if (i == 0) {
				rs[j * width + i] = 128 + prsy[j * width + i] * q;
			}
			else {
				rs[j * width + i] = rs[j * width + i -1] + prsy[j * width + i] * q;

			}

		}
	}
	makeOutFile(bmpFile, bmpInfo, "DPCMDecoder.bmp", rs);
	free(rs);

}

원본
인코더 사진
디코더 사진

원본과의 차이!

인코더와 디코더의 차이는 0

 

728x90