ISP(with opencv) c++ #2

천동민·2023년 5월 28일
0
  1. 평활화(Equalization)
  • 이미지를 좀 더 선명하게 만들어준다
  • 이미지의 히스토그램을 전체적으로 골고루 분포하도록 만들어준다

opencv는 equalizeHist() 라는 평활화 라이브러리를 제공한다
평활화 하기 전 이미지와 평활화 한 이미지를 비교하고
equalizeHist()와 직접 평활화를 구현하는 코드를 비교해보자

비교할 이미지(gray영역으로 변환)

equalizeHist() 라이브러리

#include "../Common/Common.h"


void main()
{
	string fileDir = "../thirdparty/opencv_470/sources/samples/data/";
	string fileName = fileDir + "lena.jpg";
	Mat color_img = cv::imread(fileName, cv::ImreadModes::IMREAD_COLOR);	
	Mat gray_img, gray_img_eq;
	cvtColor(color_img, gray_img, COLOR_BGR2GRAY);
	cv::equalizeHist(gray_img, gray_img_eq);
	return;
}

평활화를 하기 전 이미지와 비교했을 때 더 선명해진 모습을 볼 수 있다.

평활화(Equalization) 코드 직접 구현

1.이미지의 히스토그램을 구한다
2.누적밀도함수를 이용하여 대응 화소값 생성한다
3.대응화소 값으로 매핑

#include "../Common/Common.h"

void Convert_BGR2GRAY(uchar* pDataBGR, size_t& w, size_t& h, uchar* pY)
{
	/*
	Y=0.299R+0.587G+0.114B
	color를 gray로 변환
	*/

	for (size_t row = 0; row < h; row++)
	{
		for (size_t col = 0; col < w; col++)
		{
			int index = row * w + col;
			index *= 3;
			int b = pDataBGR[index + 0];
			int g = pDataBGR[index + 1];
			int r = pDataBGR[index + 2];
			int band_index = row * w + col;
			pY[band_index] = 0.299 * r + 0.587 * g + 0.144 * b;
		}
	}
}

void Get_Histogram(uchar* pDataGray, size_t& length, int* pHisto)
{
	for (size_t i = 0; i < length; i++)
	{
		pHisto[pDataGray[i]]++;
	}
}

void cumulative_f(int* histo_b, int* cumul_b)
{
	for (int i = 0; i < 256; i++)
	{
		
		if (i == 0)
		{
			cumul_b[i] = histo_b[i];

		}
		else
		{
			cumul_b[i] = histo_b[i] + cumul_b[i - 1];
			cout << int(histo_b[i]) << " " << int(cumul_b[i]) << endl;

		}

	}

}

void main()
{
	string fileDir = "../thirdparty/opencv_470/sources/samples/data/";
	string fileName = fileDir + "lena.jpg";
	Mat color_img = cv::imread(fileName, cv::ImreadModes::IMREAD_COLOR);
	uchar* pData = color_img.data;
	size_t width = color_img.cols;
	size_t height = color_img.rows;
	//#1. Convert Color to gray
	Mat gray_img = Mat::zeros(height, width, CV_8UC1);
	Mat gray_img_histoEq = Mat::zeros(height, width, CV_8UC1);
	uchar* pDataGray = gray_img.data;
	Convert_BGR2GRAY(pData, width, height, pDataGray);
	int histo[256] = { 0, };
	int Bcumulative[256] = {0,};
	size_t length = width * height;
	Get_Histogram(pDataGray, length, histo);
	cumulative_f(histo, Bcumulative);
	//#4. 영상의 각 화소 값들로부터 대응화소값으로의 매핑\

	int new_gray[256] = { 0, };
	size_t N = length;
	for (size_t i = 0; i < 256; i++)
	{
		new_gray[i] = 1.0 * (Bcumulative[i] * 255) / N;
	}
	for (size_t i = 0; i < N; i++)
	{
		gray_img_histoEq.data[i] = new_gray[gray_img.data[i]];
	}	
	return;
}

비교

라이브러리를 이용한 것과 코드화 한 것은 100% 일치하지 않는다

평활화 전후 비교 하기

0개의 댓글