언어/C

C언어 영상처리 - Histogram Equalization

이게될까 2024. 4. 4. 20:25
728x90
728x90

이번에 주어진 이미지 입니다. 과하게 어두워보이죠

히스토그램을 확인해보니 절반이 잘려있습니다.

이제 이 이미지를 잘 복원하여 주관적 화질 평가를 높여봅시다.

히스토그램을 확인해보면 절반만에 다 사용했습니다.

이 픽셀 사용을 아래와 같게 만들어 줄 것입니다.

	// get Histogram
	for (int j = 0; j < height; j++) {
		for (int i = 0; i < width; i++) {
			histogram[(unsigned char)(y[j * width + i] > 255 ? 255 : (y[j * width + i] < 0 ? 0 : y[j * width + i]))]++;
		}
	}
	for (int i = 0; i < 255; i++) {
		histogram[i + 1] += histogram[i];
	}

이 코드를 통해 누적 히스토 그램을 그린 뒤 

	for (int j = 0; j < height; j++) {
		for (int i = 0; i < width; i++) {
			HE[j * stride + 3 * i + 0] = (unsigned char)(255*histogram[(int)y[j*width + i]]/(width*height));
			HE[j * stride + 3 * i + 1] = (unsigned char)(255 * histogram[(int)y[j * width + i]] / (width * height));
			HE[j * stride + 3 * i + 2] = (unsigned char)(255 * histogram[(int)y[j * width + i]] / (width * height));
		}
	}

이렇게만 해서 이미지를 출력해주면 !

이렇게 그림이 복구가 됩니다!

이 그림의 히스토그램은 

이렇게 생겼꼬, 단지 두배만 한 히스토 그램은 아래 있습니다.

단지 두배만 한 히스토그램

psnr은 좋지 않을테지만 주관적으론 사진이 훨씬 괜찮아 보이네요

void CumulativeHisto(int height, int width, double* y, int size, int stride, BITMAPFILEHEADER bmpFile, BITMAPINFOHEADER bmpInfo) {
	double* histogram;
	histogram = (double*)calloc(256, sizeof(double));

	// get Histogram
	for (int j = 0; j < height; j++) {
		for (int i = 0; i < width; i++) {
			histogram[(unsigned char)(y[j * width + i] > 255 ? 255 : (y[j * width + i] < 0 ? 0 : y[j * width + i]))]++;
		}
	}
	for (int i = 0; i < 255; i++) {
		histogram[i + 1] += histogram[i];
	}

	// out Histogram
	double histoMax = 0;
	for (int i = 0; i < 256; i++) {
		if (histogram[i] > histoMax) histoMax = histogram[i];
	}
	unsigned char* outHisto,*HE;
	outHisto = (unsigned char*)calloc(size, sizeof(unsigned char));
	HE = (unsigned char*)calloc(size, sizeof(unsigned char));

	
	for (int j = 0; j < height; j++) {
		for (int i = 0; i < width; i++) {
			HE[j * stride + 3 * i + 0] = (unsigned char)(255*histogram[(int)y[j*width + i]]/(width*height));
			HE[j * stride + 3 * i + 1] = (unsigned char)(255 * histogram[(int)y[j * width + i]] / (width * height));
			HE[j * stride + 3 * i + 2] = (unsigned char)(255 * histogram[(int)y[j * width + i]] / (width * height));
		}
	}
	for (int i = 0; i < 256; i++)histogram[i] = histogram[i] / histoMax * 450;

	for (int j = 0; j < height; j++) {
		for (int i = 0; i < width; i++) {
			if (histogram[i / 2] > j) continue;
			outHisto[j * stride + 3 * i + 0] = 255;
			outHisto[j * stride + 3 * i + 1] = 255;
			outHisto[j * stride + 3 * i + 2] = 255;
		}
	}
	FILE* outputHisto = fopen("OutHisto.bmp", "wb");
	FILE* outputHE = fopen("OutHE.bmp", "wb");
	fwrite(&bmpFile, sizeof(BITMAPFILEHEADER), 1, outputHisto);
	fwrite(&bmpInfo, sizeof(BITMAPINFOHEADER), 1, outputHisto);
	fwrite(&bmpFile, sizeof(BITMAPFILEHEADER), 1, outputHE);
	fwrite(&bmpInfo, sizeof(BITMAPINFOHEADER), 1, outputHE);
	fwrite(outHisto, sizeof(unsigned char), size, outputHisto);
	fwrite(HE, sizeof(unsigned char), size, outputHE);
	
	free(HE);
	free(histogram);
	fclose(outputHisto);
	fclose(outputHE);
	free(outHisto);
}

이번에도 함수 형태로 만들었습니다.

728x90