히스토그램이란?

이미지에서 픽셀들이 가지는 값들의 출현빈도를 히스토그램이라한다.

GRAY이미지에서는 0~255값을 가진다.

이미지의 크기를 400 x 400이라고 한다면, 총 160,000개의 픽셀들을 0 ~ 255값에 따라 분류하여

각 개별값을 갖는 픽셀들이 몇개인지 알아낸 것이 히스토그램이다.

calcHist()

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 : Histogram을 계산할 채널 번호의 배열. 

예를 들어 아래 그림과 같이 BGR이미지 2장에 대해, img1은 B채널, img2는 G채널에 대해서   히스토그램을 구하고자 한다면 {0,4}를 배열에 넣어 전달해야한다.



mask : 히스토그램을 계산할 영역을 지정할 수 있다. Mat()을 전달하면 아무것도 하지않는다.

hist : 히스토그램을 계산한 결과를 저장한다.

dims : 히스토그램 계산 결과를 저장한 hist의 차원

histSize : 빈도수를 분류할 칸의 개수

ranges : 각 차원의 분류 bin의 최소, 최대값을 의미한다.




minMaxLoc()

배열에서 가장 큰값과 작은 값을 찾는 함수

C++ : 
void minMaxLoc(
    InputArray src,
    double* minVal,
    double* maxVal=0,
    Point* minLoc=0,
    Point* maxLoc=0,
)



코드

#include<iostream>

#include<opencv2\core.hpp>

#include<opencv\cv.h>

#include<opencv2\highgui.hpp>

#include<opencv2\imgproc.hpp>


using namespace cv;



int histSize[1];

float hranges[2];

const float* ranges[1];

int channels[1]; 



MatND getHistogram(const Mat &image) {


histSize[0] = 256;

hranges[0] = 0.0; //히스토그램 최소 값

hranges[1] = 255.0; //히스토그램 최대 값

ranges[0] = hranges;

channels[0] = 0;


MatND hist;

calcHist(&image, 1, channels, Mat(), hist, 1, histSize, ranges);

return hist;

}





Mat getHistogramImage(const Mat &image) {


histSize[0] = 256;

hranges[0] = 0.0;

hranges[1] = 255.0;

ranges[0] = hranges;

channels[0] = 0;

// 만약 BGR값을 위한 히스토 그램을 만들고 싶다면, 

// channels[0] = {0}; //blue

// channels[0] = {1}; //green

// channels[0] = {2}; //red 를 해주면된다.


MatND hist = getHistogram(image); // 히스토그램 계산


double maxVal = 0; // 최대 빈도수

double minVal = 0; // 최소 빈도수

minMaxLoc(hist, &minVal, &maxVal, 0, 0);


Mat histImg(histSize[0], histSize[0], CV_8U, Scalar(255));


int hpt = static_cast<int>(0.9*histSize[0]);


//그래프 그리기

for (int h = 0; h < histSize[0]; h++) {

float binVal = hist.at<float>(h);

int intensity = static_cast<int> (binVal*hpt / maxVal);

line(histImg, Point(h, histSize[0]), Point(h, histSize[0] - intensity), Scalar::all(0));

}

return histImg;

}


int main() {


Mat image = imread("image/humming_bird.jpg", 0);

Mat thresholded;

Mat eqHist;


if (!image.data)

{

std::cout << "open failed" << std::endl;

return 0;

}


//원본

namedWindow("Image");

imshow("Image", image);


//원본 히스토그램

MatND histo = getHistogram(image);

namedWindow("Histogram");

imshow("Histogram", getHistogramImage(image));



//히스토그램 이퀄라이제이션한 영상

equalizeHist(image, eqHist);

imshow("Image_EQ", eqHist);


//imwrite시에 영상의 퀄리티 정도를 지정해줄수있다.

imwrite("Image_Histogram EQ.jpg", eqHist, { CV_IMWRITE_JPEG_QUALITY , 50 });



//히스토그램 이퀄라이제이션 히스토그램 출력

imshow("Histogram_EQ", getHistogramImage(eqHist));



//영상 이진화

threshold(image, thresholded, 100, 255, THRESH_BINARY);

namedWindow("Binary Image");

imshow("Binary Image", thresholded);


imwrite("Image_Histogram threshold.jpg", thresholded, { CV_IMWRITE_JPEG_QUALITY , 50});




waitKey(0);


return 0;

}



결과 영상



'Programming > openCV' 카테고리의 다른 글

6. 디졸브와 트랙바  (0) 2017.04.04
5. 영상 디졸브  (0) 2017.04.04
4. Threshold 와 트랙바  (0) 2017.04.04
2. 컬러이미지 그레이 이미지로 변환하기  (0) 2017.04.04
1. 사진에 글자적기 / 도형 그리기  (0) 2017.04.04

#include <iostream>

#include <opencv2/opencv.hpp>


#include <stdlib.h>

#include <stdio.h>


using namespace std;

using namespace cv;



int main()

{

Mat image, image_gray;

image = cv::imread("image/humming_bird.jpg", CV_LOAD_IMAGE_COLOR);


if (!image.data) { return -1; }


cvtColor(image, image_gray, CV_RGB2GRAY);


namedWindow("Image Grayed", CV_WINDOW_AUTOSIZE);

imshow("Image Grayed", image_gray);

waitKey();


return 0;

}


#include <iostream>

#include <opencv2/opencv.hpp>


#include <stdlib.h>

#include <stdio.h>


using namespace std;

using namespace cv;


int main(void) {


char* path = "image/humming_bird.jpg";

Mat img = imread(path, CV_LOAD_IMAGE_COLOR);


//텍스트 입력

putText(img, "Hello Bird!", cvPoint(150, 50), CV_FONT_BLACK, 1, Scalar(255,255,255));

//사각형 입력

rectangle(img, cvPoint(320, 70), cvPoint(150,10), Scalar(0, 0, 255),1);


namedWindow("Image", CV_WINDOW_AUTOSIZE);

imshow("Image", img);


waitKey();


return 0;

}





+ Recent posts