히스토그램이다.
오랜만이네. 반갑다.
통계학과 대표적으로 다른 점은 bin을 1로 설정하는 것이네.
영상의 픽셀값 분포를 그래프의 형태로 표현한 것
픽셀값의 위치 정보는 표현하지 못한다.
정규화 히스토그램
각 픽셀의 개수를 영상 전체 픽셀 개수로 나눈 것으로, 해당 그레이스케일 값을 갖는 픽셀의 비율 또는 확률
수식
calcHist()
: OpenCV 히스토그램 계산 함수
void calcHist(const Mat* images, int nimages, const int* channels,
InputArray mask, OutputArray hist,
int dims, const int* histSize, const float** ranges,
bool uniform = true, bool accumulate = false);
항목 | 설명 |
---|---|
Images | 입력 영상의 배열 또는 입력 영상의 주소. 영상의 배열인 경우, 모두 크기와 깊이가 같아야 함 |
nimages | 입력 영상의 개수 |
Channels | 히스토그램을 구할 채널을 나타내는 정수형 배열 |
mask | 마스크 영상. 입력 영상 전체에서 히스토그램을 구하려면 Mat() 또는 noArray() 지정 |
hist | (출력) 히스토그램. 보통 Mat 클래스 형식의 변수 이름을 지정함 |
dims | 출력 히스토그램 차원 |
histSize | 히스토그램 각 자원의 크기를 나타내는 배열 |
ranges | 히스토그램 각 자원의 최솟값과 최댓값을 원소로 갖는 배열의 배열 (uniform = true인 경우) |
uniform | 히스토그램 빈의 간격이 균등한지를 나타내는 플래그 |
accumulate | 누적 플래그. 이 값이 true이면 hist 배열을 초기화하지 않고 누적하여 히스토그램을 계산함 |
calcHist()
는 인자가 많아 사용하기 번거롭기 때문에 아래와 같이 랩핑하는 함수를 따로 만들어서 사용한다.
// 히스토그램을 반환
Mat calcGrayHist(const Mat& img)
{
CV_Assert(img.type() == CV_8UC1);
Mat hist;
int channels[] = { 0 };
int dims = 1;
const int histSize[] = { 256 };
float graylevel[] = { 0, 256 };
const float* ranges[] = {graylevel};
// &img: img 변수의 주소
// 1: 영상 1장
// channels: 값으로 0 하나를 가지는 배열
// Mat(): 마스크가 없기 때문에 영상 전체에 대해서 히스토그램을 계산
// hist: 비어있는 Mat 객체의 이름 -> 256x1 CV_32FC1의 2차원 행렬이 만들어짐
// dims: 출력 히스토그램의 차원
// histSize: 그레이스케일 값의 단계, 256 값을 가지는 배열의 이름
// ranges: 0번 채널의 최솟값/최댓값을 가지는 배열의 이름을 인자로 받는 배열의 이름
calcHist(&img, 1, channels, Mat(), hist, dims, histSize, ranges);
return hist;
}
히스토그램 그리기
// 히스토그램 영상을 반환
Mat getGrayHistImage(const Mat& hist)
{
CV_Assert(hist.type() == CV_32FC1);
CV_Assert(hist.size() == Size(1, 256));
double histMax = 0.;
minMaxLoc(hist, 0, &histMax);
Mat imgHist(100, 256, CV_8UC1, Scalar(255));
for (int i = 0; i < 256; i++) {
line(imgHist, Point(i, 100),
Point(i, 100 - cvRound(hist.at<float>(i) * 100 / histMax)), 0);
}
return imgHist;
}
📙강의 - 강사 황선규