OpenCV(Cpp)Histogram - minho0315/OpenCV GitHub Wiki

1. 흑백 이미지 히스토그램

히스토그램은 이미지의 밝기 값이 0~255 까지 있을 때, 픽셀들이 얼마나 그 값들을 갖고 있는지 나타내주는 그래프 이다.

OpenCV에서는 이미지의 히스토그램 계산이 쉽도록 함수 calcHist()를 제공한다.

void cv::calcHist(const Mat*    images, // Histogram을 계산할 이미지들에 대한 배열이다.
                  int           nimages, // images 배열에 포함된 이미지의 개수이다.
                  const int*    channels, //Histogram을 계산할 채널 번호들의 배열이다.
                  InputArray    mask, //Histogram을 계산할 영역을 지정할 수 있다.
                  OutputArray   hist, //Histogram 계산결과를 저장한다.
                  int           dims, //Histogram 계산결과를 저장한 hist의 차원으 가리킨다.
                  const int*    histSize, //각 차원의 bin개수, 즉 빈도수를 분류할 칸의 개수를 의미한다.
                  const float** ranges, //각 차원의 분류 bin의 최소값 최대값을 의미한다.
                  bool          uniform =true,
                  bool          accumulate = flase
                 )

실행코드

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main(int ac, char** av) {

	Mat img_1 = imread("Lenna.png", 0);	//이미지를 grayscale로 불러옴

	Mat img_2 = img_1 * 2;
	Mat img_3 = img_1 / 2;
	Mat img_hist;

	MatND histogram;

	const int* channel_numbers = { 0 };
	float channel_range[] = { 0.0, 255.0 };
	const float* channel_ranges = channel_range;
	int number_bins = 255;

	calcHist(&img_1, 1, channel_numbers, Mat(), histogram, 1, &number_bins, &channel_ranges);

	// plot the histogram
	int hist_w = img_1.cols;
	int hist_h = img_1.rows;
	int bin_w = cvRound((double)hist_w / number_bins);

	Mat hist_img(hist_h, hist_w, CV_8UC1, Scalar::all(0));
	normalize(histogram, histogram, 0, hist_img.rows, NORM_MINMAX, -1, Mat());

	for (int i = 1; i < number_bins; i++)
	{
		line(hist_img, Point(bin_w * (i - 1), hist_h - cvRound(histogram.at<float>(i - 1))), Point(bin_w * (i), hist_h - cvRound(histogram.at<float>(i))), Scalar(255, 0, 0), 1, 8, 0);
	}

	imshow("Origianl", img_1);
	imshow("Histogram", hist_img);



	//imshow("original", img_1);
	//imshow("img_mul", img_2);
	//imshow("img_div", img_3);

	waitKey(0);


	return 0;
}


결과

1



2. 컬러 이미지 히스토그램

실행 코드

#include<iostream>
#include<opencv2\core.hpp>
#include<opencv\cv.h>
#include<opencv2\highgui.hpp>
#include<opencv2\imgproc.hpp>
#include <stdio.h>

using namespace cv;
using namespace std;

int main(int ac, char** av) {
	Mat inputImg = imread("Lenna.png", CV_LOAD_IMAGE_COLOR);

	MatND histogramB, histogramG, histogramR;
	int channel_B[] = { 0 };  // Blue
	int channel_G[] = { 1 };  // Green
	int channel_R[] = { 2 };  // Red
	float channel_range[2] = { 0.0 , 255.0 };
	const float* channel_ranges[1] = { channel_range };
	int histSize[1] = { 256 };

	// R, G, B별로 각각 히스토그램을 계산한다.
	calcHist(&inputImg, 1, channel_B, Mat(), histogramB, 1, histSize, channel_ranges);
	calcHist(&inputImg, 1, channel_G, Mat(), histogramG, 1, histSize, channel_ranges);
	calcHist(&inputImg, 1, channel_R, Mat(), histogramR, 1, histSize, channel_ranges);

	// Plot the histogram
	int hist_w = 512; int hist_h = 400;
	int bin_w = cvRound((double)hist_w / histSize[0]);

	Mat histImageB(hist_h, hist_w, CV_8UC3, Scalar(0, 0, 0));
	normalize(histogramB, histogramB, 0, histImageB.rows, NORM_MINMAX, -1, Mat());

	Mat histImageG(hist_h, hist_w, CV_8UC3, Scalar(0, 0, 0));
	normalize(histogramG, histogramG, 0, histImageG.rows, NORM_MINMAX, -1, Mat());

	Mat histImageR(hist_h, hist_w, CV_8UC3, Scalar(0, 0, 0));
	normalize(histogramR, histogramR, 0, histImageR.rows, NORM_MINMAX, -1, Mat());

	for (int i = 1; i < histSize[0]; i++)
	{
		line(histImageB, Point(bin_w * (i - 1), hist_h - cvRound(histogramB.at<float>(i - 1))),
			Point(bin_w * (i), hist_h - cvRound(histogramB.at<float>(i))),
			Scalar(255, 0, 0), 2, 8, 0);

		line(histImageG, Point(bin_w * (i - 1), hist_h - cvRound(histogramG.at<float>(i - 1))),
			Point(bin_w * (i), hist_h - cvRound(histogramG.at<float>(i))),
			Scalar(0, 255, 0), 2, 8, 0);

		line(histImageR, Point(bin_w * (i - 1), hist_h - cvRound(histogramR.at<float>(i - 1))),
			Point(bin_w * (i), hist_h - cvRound(histogramR.at<float>(i))),
			Scalar(0, 0, 255), 2, 8, 0);

	}

	namedWindow("Original", CV_WINDOW_AUTOSIZE);
	namedWindow("HistogramB", CV_WINDOW_AUTOSIZE);
	namedWindow("HistogramG", CV_WINDOW_AUTOSIZE);
	namedWindow("HistogramR", CV_WINDOW_AUTOSIZE);

	moveWindow("Original", 100, 100);
	moveWindow("HistogramB", 110, 110);
	moveWindow("HistogramG", 120, 120);
	moveWindow("HistogramR", 130, 130);

	imshow("Original", inputImg);
	imshow("HistogramB", histImageB);
	imshow("HistogramG", histImageG);
	imshow("HistogramR", histImageR);

	waitKey(0);
	return 0;
}

결과

2



3. 흑백 이미지와 컬러 이미지 히스토그램 그리기의 차이점

흑백이미지는 채널을 하나로 계산하면 되지만 컬러이미지는 B, G, R 채널별로 동일한 작업으로 반복해야 한다.

참고 사이트

⚠️ **GitHub.com Fallback** ⚠️