[OpenCV] 히스토그램 분석

zzwon1212·2023년 10월 28일
0

OpenCV

목록 보기
9/16
post-thumbnail

히스토그램이다.
오랜만이네. 반갑다.
통계학과 대표적으로 다른 점은 bin을 1로 설정하는 것이네.

1. 히스토그램

  • 영상의 픽셀값 분포를 그래프의 형태로 표현한 것

  • 픽셀값의 위치 정보는 표현하지 못한다.

  • 정규화 히스토그램

    • 각 픽셀의 개수를 영상 전체 픽셀 개수로 나눈 것으로, 해당 그레이스케일 값을 갖는 픽셀의 비율 또는 확률

    • 수식

      p(g)=Ngw×hg=0L1p(g)=1p(g) = {N_g \over w \times h} \\ \,\\ \sum_{g=0}^{L-1} p(g) = 1

2. 히스토그램 그리기

  • 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;
    }

3. 히스토그램 분석

  • 영상의 픽셀값 분포를 한눈에 파악할 수 있다.

  • 간단하게 밝기를 조절할 경우 좌우로 시프트된다.
  • 간단하게 명암비를 조절할 경우 히스토그램의 전체적인 폭이 좁아지거나 넓어진다.

📙강의 - 강사 황선규

profile
JUST DO IT.

0개의 댓글