OpenCVsharp4で濃度ヒストグラムの作成&平滑化

濃度ヒストグラムとは

画素の明るさごとのヒストグラム」のこと
濃度ヒストグラムは、明るさの補正や二値化する際の目安に使われたりなどする

プログラム

サンプルプログラムをほとんど流用

using System;  
using OpenCvSharp;  

namespace 画像ヒストグラム {  
    class Program {  
        static void Main(string[] args) {  
            //画像を読み込む  
            Mat srcImg = new Mat(@"D:\IMG_8804.jpg");  

            //読み込んだ画像をグレースケール化  
            Cv2.CvtColor(srcImg, srcImg, ColorConversionCodes.BGR2GRAY);  

            //ヒストグラム表示用  
            const int width = 260, height = 200;  
            Mat render = new Mat(new Size(width, height), MatType.CV_8UC3, Scalar.All(255));  

            //ヒストグラムの計算  
            Mat hist = new Mat();//ヒストグラムの画像  
            int[] hdims = { 256 };//ヒストグラムのサイズ  
            Rangef[] ranges = {new Rangef(0,256), };//最大値と最小値  
            Cv2.CalcHist(   
                new Mat[]{ srcImg }, //入力画像   
                new int[]{ 0 },       //画像チャンネル  
                null,                 //マスク画像  
                hist,                 //出力先  
                1,                   //ヒストグラムの次元  
                hdims,                //各次元のヒストグラムの配列  
                ranges               //ヒストグラムを計測したい画素値の範囲  
                );  

            //ヒストグラムから最大値を取得  
            double minVal, maxVal;  
            Cv2.MinMaxLoc(hist, out minVal, out maxVal);  

            Scalar color = Scalar.All(100);  

            //ヒストグラムの大きさと描画  
            hist *= (maxVal != 0 ? height / maxVal : 0.0);  

            for(int j=0; j < hdims[0]; ++j) {  
                int binW = (int)((double)width / hdims[0]);  
                render.Rectangle(  
                    new Point(j*binW, render.Rows-(int)hist.Get<float>(j)),  
                    new Point((j+1)*binW, render.Rows),  
                    color,  
                    -1  
                    );  
            }  

            //画像と画像ヒストグラムの表示  
            using(new Window("Image", WindowMode.AutoSize | WindowMode.FreeRatio, srcImg))  
            using(new Window("Histogram", WindowMode.AutoSize | WindowMode.FreeRatio, render)) {  
                Cv2.WaitKey();  
            }  

        }  
    }  
}  

結果

f:id:negizoku:20200920225212j:plain
↑から

↓のようなヒストグラムが表示される

f:id:negizoku:20200920225229p:plain




ヒストグラム平滑化も簡単にできたので載せておく

using System;  
using OpenCvSharp;  

namespace 画像ヒストグラム {  
    class Program {  
        static void Main(string[] args) {  
            //画像を読み込む  
            Mat srcImg = new Mat(@"D:\icon.jpg");  

            //読み込んだ画像をグレースケール化  
            Cv2.CvtColor(srcImg, srcImg, ColorConversionCodes.BGR2GRAY);  


            Mat histImg = new Mat();  

            Cv2.EqualizeHist(srcImg, histImg);  

            Cv2.ImShow("入力画像", srcImg);  
            Cv2.ImShow("出力画像", histImg);  

            Cv2.WaitKey();  

            Cv2.DestroyAllWindows();  
        }  
    }  
}  

#参考
http://ipr20.cs.ehime-u.ac.jp/column/gazo_syori/chapter2.html
http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_imgproc/py_histograms/py_histogram_begins/py_histogram_begins.html
https://shimat.github.io/opencvsharp_docs/html/e4ea7d0d-4168-cd5b-febb-b0ceccaffa1a.htm