OpenCvSharpでHSVで特定の色を取り出すときの簡易確認ツール
OpenCVで特定の色だけにしぼり込むときに、HSV(Hue,Saturation,Value)で範囲を指定するとします。
ある画像をサンプルとして、自分が絞り込みたい色の範囲はHSVでどの値の範囲なのかを確認したいです。
そんなちょっとした確認に便利なツールがあると便利です。ここでは、そんなちょっとしたツールをOpenCvSharpで作ります。
OpenCVでは独自のウィンドウに加え、スライダーをウィンドウに設置することができるため、こういった値を変えながら結果を確認したい、という用途にピッタリのツールを簡単に作ることができます。
参考
OpenCVのサンプルコードはPythonやC++のものがたくさん見つかりますが、OpenCvSharpでも書き方はほとんど同じなので、他言語のサンプルを簡単な脳内変換でOpenCvSharpで使うことができます。
今回参考にさせてもらったのは以下の記事です。
ありがとうございました。
実装
流れとしては、
- 名前付きのウィンドウを作成する
- そのウィンドウにスライダー(trackbar)を配置する
- スライダーのOnChangedイベントにイベントハンドラを設定する
- イベントハンドラの中でスライダーの値をもとに画像を生成してウィンドウを更新
です。これがほぼすべてです。
using OpenCvSharp; using System; namespace OpenCvHsvChecker { class Program { private static int _h_min = 0; private static int _h_max = 0; private static int _s_min = 0; private static int _s_max = 0; private static int _v_min = 0; private static int _v_max = 0; private static Mat src = new Mat(); private static Mat hsv = new Mat(); //private static Mat dst = new Mat(); private const string WINDOW_NAME = "HSV Checker"; static void Main(string[] args) { Console.WriteLine("Hello World!"); string inputImagePath = "Images/gauge-1.jpg"; src = Cv2.ImRead(inputImagePath); if (src is null) return; Cv2.ImShow("src", src); Cv2.CvtColor(src, hsv, ColorConversionCodes.BGR2HSV, 3); Cv2.ImShow("hsv", hsv); //名前つきウィンドウを作成 Cv2.NamedWindow(WINDOW_NAME); //ウィンドウ名を指定してスライダーを配置 Cv2.CreateTrackbar("H_Min", WINDOW_NAME, 179, onChange: H_Min_Changed); Cv2.CreateTrackbar("H_Max", WINDOW_NAME, 179, onChange: H_Max_Changed); Cv2.CreateTrackbar("S_Min", WINDOW_NAME, 255, onChange: S_Min_Changed); Cv2.CreateTrackbar("S_Max", WINDOW_NAME, 255, onChange: S_Max_Changed); Cv2.CreateTrackbar("V_Min", WINDOW_NAME, 255, onChange: V_Min_Changed); Cv2.CreateTrackbar("V_Max", WINDOW_NAME, 255, onChange: V_Max_Changed); //初期画像を表示 Cv2.ImShow(WINDOW_NAME, src); Cv2.WaitKey(); } private static void V_Max_Changed(int pos, IntPtr userData) { _v_max = pos; Update(); } private static void V_Min_Changed(int pos, IntPtr userData) { _v_min = pos; Update(); } private static void S_Max_Changed(int pos, IntPtr userData) { _s_max = pos; Update(); } private static void S_Min_Changed(int pos, IntPtr userData) { _s_min = pos; Update(); } private static void H_Max_Changed(int pos, IntPtr userData) { _h_max = pos; Update(); } private static void H_Min_Changed(int pos, IntPtr userData) { _h_min = pos; Console.WriteLine(_h_min); Update(); } static void Update() { //HSV画像とスライダーの値からマスクを生成 var scalar_min = new Scalar(_h_min, _s_min, _v_min); var scalar_max = new Scalar(_h_max, _s_max, _v_max); Mat mask = new Mat(); Cv2.InRange(hsv, scalar_min, scalar_max, mask); //マスク画像を使って元画像にフィルタをかける Mat dst = new Mat(); src.CopyTo(dst, mask); //ウィンドウの画像を更新 Cv2.ImShow(WINDOW_NAME, dst); } } }
OpenCvSharpのインストールについては以下の記事を。