OpenCV (C#)

히스토그램 #4

질문폭격 2024. 8. 2. 12:02

 도수 분포표중에 하나이며, 구간으로 나눠서 데이터를 시각적으로 표현한 막대그래프이다.

X축은 픽셀의 값이고, Y축은 해당 픽셀의 개수이다.

 

이를 통해서 이미지의 밝은 픽셀과 어두운 픽셀이 어떤 형태로 분포하는지 알 수 있다.

 

히스토그램의 3가지 중요요소

1. 빈도수(BINS)

 히스토그램 X축의 간격이다. 픽셀값의 범위가 0~255이고, 빈도수가 8이면, 0~7, 8~15... 248~255 범위로 총 32개의 막대가 생성 된다.

 

2. 차원수(DIMS)

 채널을 이야기한다. R채널 G채널 B채널 혹은 그레이스케일 채널, 여러 채널에 대해서 분석 할 수 있다.

 

3. 범위(RANGE)

 히스토그램 그래프의 X축 범위이다. 특정 픽셀 값 영역만 분석하는데 사용 된다.

 

 시각적으로도 이미지가 밝은지 어두운지 파악이 되지만, 수치적으로 표현 할 수 없다. 하지만 히스토그램을 확인한다면, 가장 어두운 부분, 가장 밝은 부분을 수치적으로 확인할 수 있으며, 다양한 알고리즘에서 활용도가 높다.

 

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            Mat src = Cv2.ImRead("Image.jpg");
            Mat gray = new Mat();
            Mat hist = new Mat();
            Mat result = Mat.Ones(new Size(256, src.Height), MatType.CV_8UC1);
            Mat dst = new Mat();

            Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY);
            Cv2.CalcHist(new Mat[] { gray }, new int[] { 0 }, null, hist, 1, new int[] { 256 }, new Rangef[] { new Rangef(0, 256) });
            Cv2.Normalize(hist, hist, 0, 255, NormTypes.MinMax);

            for(int i = 0; i < hist.Rows; i++)
            {
                Cv2.Line(result, new Point(i, src.Height), new Point(i, src.Height - hist.Get<float>(i)), Scalar.White);
            }

            Cv2.HConcat(new Mat[] { gray, result }, dst);
            Cv2.ImShow("dst", dst);

            Cv2.WaitKey(0);
            Cv2.DestroyAllWindows();
        }
    }

 

 Cv2.CalcHist 함수를 호출해서 hist 변수에 결과값을 저장하게 된다.

반환값인 hist는 단순한 리턴 값이 아니라, 파생된 멤버나 정적 메서드등을 많이 담고 있다.

 

코드 결과:

 

Syntax: cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])
Parameters:
  • images: list of images as numpy arrays. All images must be of the same dtype and same size.
  • channels: list of the channels used to calculate the histograms.
  • mask: optional mask (8 bit array) of the same size as the input image.
  • histSize: histogram sizes in each dimension
  • ranges: Array of the dims arrays of the histogram bin boundaries in each dimension
  • hist: Output histogram
  • accumulate: accumulation flag, enables to compute a single histogram from several sets of arrays.
Return: It returns an array of histogram points of dtype float32.

 

============================  기계 번역 ↓   ============================

구문: cv2.calcHist(이미지, 채널, 마스크, histSize, 범위[, hist[, 누적]])
매개변수:
  • 이미지: numpy 배열로 된 이미지 목록입니다. 모든 이미지는 동일한 dtype과 동일한 크기여야 합니다.
  • 채널: 히스토그램을 계산하는 데 사용되는 채널 목록입니다.
  • 마스크: 입력 이미지와 동일한 크기의 선택적 마스크(8비트 배열)입니다.
  • histSize: 각 차원의 히스토그램 크기
  • 범위: 각 차원의 히스토그램 빈 경계의 희미한 배열 배열
  • hist: 출력 히스토그램
  • 누적: 누적 플래그, 여러 배열 세트에서 단일 히스토그램을 계산할 수 있습니다.
반환: dtype float32의 히스토그램 포인트 배열을 반환합니다.

 

============================  부드럽게 번역 ↓   ============================

구문: cv2.calcHist(이미지, 채널, 마스크, histSize, 범위[, hist[, 누적]])
매개변수:
  • 이미지: 이미지 데이터
  • 채널: 히스토그램을 계산하는 데 사용되는 채널 목록, 단일 채널은 0, 다중 채널일 경우 Blue 0, Green 1, Red 2로 사용
  • 마스크: 입력 이미지와 동일한 크기의 선택적 마스크(8비트 배열)입니다, 이미지 분석 할 영역을 따로 설정
  • histSize: 각 차원의 히스토그램 크기, 앞에 설명한 빈도수(BINS)이다
  • 범위: 각 차원의 히스토그램 빈 경계의 희미한 배열 배열, 앞서 설명한(RANGE) X축 범위
  • hist: 출력 히스토그램
  • 누적: 누적 플래그, 여러 배열 세트에서 단일 히스토그램을 계산할 수 있습니다, 누적해 반영할지 여부
반환: dtype float32의 히스토그램 포인트 배열을 반환합니다.

 

조사하고 나니, c#은 dims와 uniform 2개 더 있는데,

dims: 채널 매개 변수의 배열 요소 수를 의미

uniform: 히스토그램이 균일한지에 대한 플래그이며, 값이 true인 경우에 채널의 순서에 따라 히스토그램 채널마다 범위 배열의 요소가 사용 된다. false인 경우엔 범위 배열의 모든 요소가 채널의 순서에 따라서 순차 배치 된다.

public static void CalcHist(
	Mat[] images,
	int[] channels,
	InputArray mask,
	OutputArray hist,
	int dims,
	int[] histSize,
	float[][] ranges,
	bool uniform = true,
	bool accumulate = false
)