- 평활화(Equalization)
- 이미지를 좀 더 선명하게 만들어준다
- 이미지의 히스토그램을 전체적으로 골고루 분포하도록 만들어준다
opencv는 equalizeHist()
라는 평활화 라이브러리를 제공한다
평활화 하기 전 이미지와 평활화 한 이미지를 비교하고
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;
}
평활화를 하기 전 이미지와 비교했을 때 더 선명해진 모습을 볼 수 있다.
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% 일치하지 않는다
평활화 전후 비교 하기