shuhelohelo’s blog

Xamarin.Forms多めです.

OpenCvSharp4で特定の色だけを抜き出す

以下の記事をOpenCvSharpを使ってやった内容になります。

tecsingularity.com

RGBで指定

RGBで色の範囲を指定して抜き出すには以下のようにします。

using OpenCvSharp;
using System;

namespace OpenCVColorExtraction
{
    class Program
    {
        //抽出したい色の範囲をRGBで指定
        const int B_MAX = 40;
        const int B_MIN = 0;
        const int G_MAX = 50;
        const int G_MIN = 0;
        const int R_MAX = 170;
        const int R_MIN = 100;

        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            string inputFilePath = "Images/gauge-1.jpg";

            //画像を読み込み
            var src = Cv2.ImRead(inputFilePath);
            if (src is null)
                Console.WriteLine("fail to read file.");

            //マスクを作成
            Scalar s_min = new Scalar(B_MIN, G_MIN, R_MIN);
            Scalar s_max = new Scalar(B_MAX, G_MAX, R_MAX);
            Mat maskImage = new Mat();
            Cv2.InRange(src, s_min, s_max, maskImage);


            //マスクを使ってフィルタリング
            Mat masked = new Mat();
            src.CopyTo(masked, maskImage);

            //表示
            using (new Window("src", src))
            using (new Window("maskImage", maskImage))
            using (new Window("masked", masked))
                Cv2.WaitKey();//何かキーが押されるまで待つ

        }
    }
}

概ねOKですね。

元画像 f:id:shuhelohelo:20201123094350p:plain

マスク f:id:shuhelohelo:20201123094404p:plain

抽出 f:id:shuhelohelo:20201123095126p:plain

HSVで指定

(追記:HSVの値を変えながらデバッグを繰り返すのは面倒なので簡易確認ツールを作成しました。

shuhelohelo.hatenablog.com )

using OpenCvSharp;
using System;

namespace OpenCVColorExtraction
{
    class Program
    {
        //抽出したい色の範囲をHSVで指定
        const int H_MAX = 120;
        const int H_MIN = 111;
        const int S_MAX = 255;
        const int S_MIN = 50;
        const int V_MAX = 255;
        const int V_MIN = 50;
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            string inputFilePath = "Images/gauge-1.jpg";

            //画像を読み込み
            var src = Cv2.ImRead(inputFilePath);
            if (src is null)
                Console.WriteLine("fail to read file.");

            //HSVに変換
            Mat hsv = new Mat();
            Cv2.CvtColor(src, hsv, ColorConversionCodes.RGB2HSV);

            //マスクを作成
            Scalar s_min = new Scalar(H_MIN, S_MIN, V_MIN);
            Scalar s_max = new Scalar(H_MAX, S_MAX, V_MAX);
            Mat maskImage = new Mat();
            Cv2.InRange(hsv, s_min, s_max, maskImage);

            //マスクを使ってフィルタリング
            Mat masked = new Mat();
            src.CopyTo(masked, maskImage);

            //表示
            using (new Window("src", src))
            using (new Window("hsv", hsv))
            using (new Window("maskImage", maskImage))
            using (new Window("masked", masked))
                Cv2.WaitKey();//何かキーが押されるまで待つ
        }

でも、色相の指定がよくわからないな。 なぜこの色がこの範囲になるのか。

f:id:shuhelohelo:20201123103926p:plain

f:id:shuhelohelo:20201123103948p:plain

f:id:shuhelohelo:20201123104000p:plain

ソースコード

github.com