본문 바로가기
Computer Science/영상처리

(C/C++) Histogram

by BaekDaBang 2024. 4. 2.

1. Image Histogram

Pixel 강도 분포의 그래프 표현으로, 각 강도에 대한 픽셀 수이다.

이미지 분석, 이미지 향상과 같은 다양한 목적으로 쓰인다.

void histogram(void)
{
    int I,x,y,n; /* 변수와 배열 선언 */
    char Subf[300];

    for(int i = 0; i < SIZE; i++) 
        hist[i] = LOW; /* initialize 초기화 */
    for(int y = 0 ; y < SIZE ; y++)
    {
        fread(Subf, 1, SIZE, in);   /* read image data line by line 영상을 한줄씩 읽는다 */
        for(int x = 0 ; x < SIZE ; x++)
        {
            hist[Subf[x]]++; /* compute density frequency 농담의 빈도를 카운트 한다 */
        }
    }
}

 

2. Implementation

  • 512×512 (Total 262144 luminance pixels, 8 bit-depth)
  • Pixel value in the horizontal axis (Scaling, 256 to 512)
  • The number of pixels in the vertical axis (Scaling, less than 512)

#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include <math.h>

int main()
{
	BITMAPFILEHEADER bmpFile, bmpFile2;
	BITMAPINFOHEADER bmpInfo, bmpInfo2;
	FILE* inputFile1 = NULL;
	inputFile1 = fopen("AICenterY.bmp", "rb");

	fread(&bmpFile, sizeof(BITMAPFILEHEADER), 1, inputFile1);
	fread(&bmpInfo, sizeof(BITMAPINFOHEADER), 1, inputFile1);

	int width = bmpInfo.biWidth;
	int height = bmpInfo.biHeight;
	int size = bmpInfo.biSizeImage;
	int bitCnt = bmpInfo.biBitCount;
	int stride = (((bitCnt / 8) * width) + 3) / 4 * 4, max;
	printf("width, height, size, bitCnt, stride : ");
	printf("%d, %d, %d, %d, %d\n", width, height, size, bitCnt, stride);

	unsigned char* inputImg1 = NULL, *outputImg1 = NULL;
	inputImg1 = (unsigned char*)calloc(size, sizeof(unsigned char));
	outputImg1 = (unsigned char*)calloc(size, sizeof(unsigned char));
	fread(inputImg1, sizeof(unsigned char), size, inputFile1);

	unsigned char* Y1 = (unsigned char*)calloc(width * height, sizeof(unsigned char));	// Original
	unsigned char* Y2 = (unsigned char*)calloc(width * height, sizeof(unsigned char));	// Histogram
	int* Y3 = (int*)calloc(512 * 512, sizeof(int));	                                    // 누적 Histogram

	// Original Copy
	for (int j = 0; j < height; j++)
	{
		for (int i = 0; i < width; i++)
		{
			Y1[j * width + i] = inputImg1[j * stride + 3 * i];
		}
	}

	// Initialization
	for (int j = 0; j < height; j++)
	{
		for (int i = 0; i < width; i++)
		{
			Y2[j * width + i] = 255;
			if (i == 0 || i == width - 1) Y2[j * width + i] = 128;
			if (j == 0 || j == width - 1) Y2[j * width + i] = 128;
		}
	}

	// Histogram 생성
	for (int i = 0; i < height * width; i++)
	{
		Y2[Y1[i]]++;
	}

	// Histogram으로 누적 Histogram 생성
	int sum = 0;
	int scale_factor = 512 / (height * width);

	for (int i = 0; i < 512; i++)
	{
		sum += Y2[i];
		Y3 = (int)((sum * scale_factor) + 0.5);
	}

	// Output
	for (int j = 0; j < height; j++) {
		for (int i = 0; i < width; i++) {
			outputImg1[j * stride + 3 * i + 0] = (unsigned char)(Y3[j * width + i] > 255 ? 255 : (Y3[j * width + i] < 0 ? 0 : Y3[j * width + i]));
			outputImg1[j * stride + 3 * i + 1] = (unsigned char)(Y3[j * width + i] > 255 ? 255 : (Y3[j * width + i] < 0 ? 0 : Y3[j * width + i]));
			outputImg1[j * stride + 3 * i + 2] = (unsigned char)(Y3[j * width + i] > 255 ? 255 : (Y3[j * width + i] < 0 ? 0 : Y3[j * width + i]));
		}
	}

	FILE* outputFile1 = fopen("Histogram.bmp", "wb");
	fwrite(&bmpFile, sizeof(BITMAPFILEHEADER), 1, outputFile1);
	fwrite(&bmpInfo, sizeof(BITMAPINFOHEADER), 1, outputFile1);
	fwrite(outputImg1, sizeof(unsigned char), size, outputFile1);

	// Free
	free(inputImg1);
	free(outputImg1);
	free(Y1);
	free(Y2);
	fclose(inputFile1);
	fclose(outputFile1);
}

 

3. Histogram Characteristics

4. Image Segmentation

물체와 배경 영역을 나타내는 이진 이미지와 같이, 이미지를 여러 영역으로 분할하고 label을 할당 이미지 처리이다.

임계값, 히스토그램 기반 분할, 클러스터링 등이 있다.

 

5. Image Thresholding

이미지를 여러 영역으로 분할하고,  특정 정보를 추출한다.

void threshold(int *thresh, int *mode)
{
    int I,j; /* 변수 선언 */


    for( i = 0; i < SIZE; i++) { /* SIZE는 영상의 크기 */
    for( j = 0; j < SIZE ; j++) {
        switch(*mode) { /* select mode */
            case 1: /* 경계값을 기준으로 작으면 흰색, 크면 검정색 */
                if((int)image_in[i][j] <= *thresh) image_out[i][j] = HIGH;
                else image_out[i][j] = LOW;
                break;

            case 2: /* 경계값을 기준으로 크면 흰색, 작으면 검정색 */
                if((int)image_in[i][j] >= *thresh) image_out[i][j] = HIGH;
                else image_out[i][j] = LOW;
                break;
            default: 
                break;
        }
    }
}

 

6. Binary Image

Mask와 같은 2단계, 2단계 또는 흑백 이미지로, image thresholding의 결과이다.

 

7. Multilevel Thresholding

 

'Computer Science > 영상처리' 카테고리의 다른 글

(C/C++) Filter (Denoising)  (0) 2024.04.01
(C/C++) Quality Evaluation(PSNR)  (0) 2024.03.27
(C/C++) Pixel Operation  (0) 2024.03.27
(C/C++) Color Model  (0) 2024.03.27
(C/C++) Image Format  (0) 2024.03.27