EmguCV實現顏色物體識別與追蹤(CvInvoke.InRange()函數)

文章目錄

說明

1、在HSV顏色空間下進行顏色追蹤,RGB顏色空間每個通道分量受亮度影響大,HSV顏色空間受亮度影響較小;
2、EmguCV與OpenCV的HSV取值: H:0-180 ; S: 0-255; V: 0-255(注意取值範圍);
在這裏插入圖片描述
3、常用的HSV參考值:
在這裏插入圖片描述
4、使用Inrange()函數在HSV空間中尋找HSV在某一範圍內的值,輸出掩膜,作爲尋找結果。

Code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Emgu.CV;
using Emgu.CV.Util;
using Emgu.CV.Structure;
using Emgu.CV.CvEnum;
using Emgu.Util;
using System.Drawing;

namespace lesson28_console
{
    class Program
    {
        static void Main(string[] args)
        {
            ///圖片顏色識別
            //Mat srcImg = CvInvoke.Imread(@"C:\Users\hello\Desktop\EmguCVDemo\lesson28\lesson28_console\bin\Debug\opencv-logo-white.png");
            //CvInvoke.Imshow("input", srcImg);

            //Mat hsvImg = new Mat();
            //Mat mask = new Mat();

            //double h_min = 0, s_min = 43, v_min = 46;
            //double h_max = 10, s_max = 255, v_max = 255;
            //ScalarArray hsv_min = new ScalarArray(new MCvScalar(h_min, s_min, v_min));
            //ScalarArray hsv_max = new ScalarArray(new MCvScalar(h_max, s_max, v_max));

            //CvInvoke.CvtColor(srcImg, hsvImg, ColorConversion.Bgr2Hsv);
            //CvInvoke.InRange(hsvImg, hsv_min, hsv_max, mask);   //輸出爲符合要求的圖像掩膜
            //CvInvoke.MedianBlur(mask, mask, 5);
            //CvInvoke.Imshow("mask", mask);
            //VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
            //VectorOfRect hierarchy = new VectorOfRect();
            ////發現輪廓
            //CvInvoke.FindContours(mask, contours,hierarchy, RetrType.External, ChainApproxMethod.ChainApproxNone);
            //VectorOfVectorOfPoint contours_approx = new VectorOfVectorOfPoint(contours.Size);
            //Rectangle rect = new Rectangle();
            //for (int i =0; i < contours.Size;i++)
            //{
            //    CvInvoke.ApproxPolyDP(contours[i], contours_approx[i], 3, true);
            //    CvInvoke.DrawContours(srcImg, contours_approx, i, new MCvScalar(255, 0, 0), 1, LineType.EightConnected, hierarchy, 0);
            //    CvInvoke.Imshow("red", srcImg);
            //    rect = CvInvoke.BoundingRectangle(contours_approx[i]);
            //    CvInvoke.Rectangle(srcImg, rect, new MCvScalar(0, 0, 255), 1);
            //    CvInvoke.PutText(srcImg, "red", new Point(rect.X, rect.Y), FontFace.HersheyComplexSmall, 1.2, new MCvScalar(0, 255, 0));
            //}
            //CvInvoke.WaitKey(0);


            ///視頻綠色物體追蹤
            //VideoCapture cap = new VideoCapture("1.mp4");
            //if(!cap.IsOpened)     //打開文件失敗
            //{
            //    Console.WriteLine("Open video failed!");
            //    return;
            //}
            //Mat frame = new Mat();
            //while(true)
            //{
            //    //frame = cap.QueryFrame();
            //    cap.Read(frame);
            //    if(frame.IsEmpty)
            //    {
            //        Console.WriteLine("frame is empty...");
            //        break;
            //    }
            //    Mat hsvimg = new Mat();
            //    Mat mask = new Mat();

            //    double h_min = 35, s_min = 110, v_min = 106;
            //    double h_max = 77, s_max = 255, v_max = 255;

            //    ScalarArray hsv_min = new ScalarArray(new MCvScalar(h_min, s_min, v_min));
            //    ScalarArray hsv_max = new ScalarArray(new MCvScalar(h_max, s_max, v_max));

            //    CvInvoke.CvtColor(frame, hsvimg, ColorConversion.Bgr2Hsv);
            //    CvInvoke.InRange(hsvimg, hsv_min, hsv_max, mask);
            //    CvInvoke.MedianBlur(mask, mask, 5);
            //    CvInvoke.Imshow("mask", mask);

            //    VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
            //    VectorOfRect hierachy = new VectorOfRect();
            //    CvInvoke.FindContours(mask, contours, hierachy, RetrType.External, ChainApproxMethod.ChainApproxNone);

            //    for(int i = 0; i< contours.Size; i++)
            //    {
            //        Rectangle rect = CvInvoke.BoundingRectangle(contours[i]);
            //        if (rect.Width < 10 || rect.Height < 10)                //對於太小的外接矩形,刪除掉
            //            continue;
            //        CvInvoke.Rectangle(frame, rect, new MCvScalar(255, 0, 0), 1);
            //        CvInvoke.PutText(frame, "green", new Point(rect.X, rect.Y - 5), FontFace.HersheyComplexSmall, 1.2, new MCvScalar(0, 255, 0));
            //    }
            //    CvInvoke.Imshow("hsv_track", frame);
            //    if(CvInvoke.WaitKey(30) == 27)
            //    {
            //        break;
            //    }
            //}

            ///藍色物體追蹤
            //VideoCapture cap = new VideoCapture("1.mp4");
            //if (!cap.IsOpened)     //打開文件失敗
            //{
            //    Console.WriteLine("Open video failed!");
            //    return;
            //}
            //Mat frame = new Mat();
            //while (true)
            //{
            //    //frame = cap.QueryFrame();   //實驗讀取到最後一幀有異常
            //    cap.Read(frame);
            //    if (frame.IsEmpty)
            //    {
            //        Console.WriteLine("frame is empty...");
            //        break;
            //    }
            //    Mat hsvimg = new Mat();
            //    Mat mask = new Mat();

            //    double h_min = 81, s_min = 77, v_min = 93;
            //    double h_max = 125, s_max = 255, v_max = 255;

            //    ScalarArray hsv_min = new ScalarArray(new MCvScalar(h_min, s_min, v_min));
            //    ScalarArray hsv_max = new ScalarArray(new MCvScalar(h_max, s_max, v_max));


            //    //!!!因爲圖像某一部分存在干擾,所以設置感興趣區域,只追蹤在規定範圍內的顏色物體
            //    Mat frameROI = new Mat(frame, new Rectangle(0, 0, 350, 353));  //將干擾區域切除

            //    CvInvoke.CvtColor(frameROI, hsvimg, ColorConversion.Bgr2Hsv);
            //    CvInvoke.InRange(hsvimg, hsv_min, hsv_max, mask);
            //    CvInvoke.MedianBlur(mask, mask, 5);
            //    CvInvoke.Imshow("mask", mask);

            //    VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
            //    VectorOfRect hierachy = new VectorOfRect();
            //    CvInvoke.FindContours(mask, contours, hierachy, RetrType.External, ChainApproxMethod.ChainApproxNone);

            //    for (int i = 0; i < contours.Size; i++)
            //    {
            //        Rectangle rect = CvInvoke.BoundingRectangle(contours[i]);
            //        if (rect.Width < 10 || rect.Height < 10)                //對於太小的外接矩形,刪除掉
            //            continue;
            //        CvInvoke.Rectangle(frame, rect, new MCvScalar(255, 0, 0), 1);
            //        CvInvoke.PutText(frame, "blue", new Point(rect.X, rect.Y - 5), FontFace.HersheyComplexSmall, 1.2, new MCvScalar(0, 255, 0));
            //    }
            //    CvInvoke.Imshow("hsv_track", frame);
            //    if (CvInvoke.WaitKey(30) == 27)
            //    {
            //        break;
            //    }
            //}


            ///紅色綠色同時追蹤
            //VideoCapture cap = new VideoCapture("1.mp4");
            //if (!cap.IsOpened)     //打開文件失敗
            //{
            //    Console.WriteLine("Open video failed!");
            //    return;
            //}
            //Mat frame = new Mat();
            //while (true)
            //{
            //    //frame = cap.QueryFrame();   //實驗讀取到最後一幀有異常
            //    cap.Read(frame);
            //    if (frame.IsEmpty)
            //    {
            //        Console.WriteLine("frame is empty...");
            //        break;
            //    }
            //    Mat hsvimg = new Mat();
            //    Mat mask_red = new Mat();
            //    Mat mask_green = new Mat();

            //    double h_min_red = 0, s_min_red = 127, v_min_red = 128;
            //    double h_max_red = 10, s_max_red = 255, v_max_red = 255;

            //    double h_min_green = 35, s_min_green = 110, v_min_green = 106;
            //    double h_max_green = 77, s_max_green = 255, v_max_green = 255;

            //    ScalarArray hsv_min_red = new ScalarArray(new MCvScalar(h_min_red, s_min_red, v_min_red));
            //    ScalarArray hsv_max_red = new ScalarArray(new MCvScalar(h_max_red, s_max_red, v_max_red));

            //    ScalarArray hsv_min_green = new ScalarArray(new MCvScalar(h_min_green, s_min_green, v_min_green));
            //    ScalarArray hsv_max_green = new ScalarArray(new MCvScalar(h_max_green, s_max_green, v_max_green));               

            //    CvInvoke.CvtColor(frame, hsvimg, ColorConversion.Bgr2Hsv);
            //    CvInvoke.InRange(hsvimg, hsv_min_red, hsv_max_red, mask_red);
            //    CvInvoke.InRange(hsvimg, hsv_min_green, hsv_max_green, mask_green);
            //    CvInvoke.MedianBlur(mask_red, mask_red, 5);
            //    CvInvoke.MedianBlur(mask_green, mask_green, 5);

            //    Mat mask = new Mat();
            //    CvInvoke.Add(mask_red, mask_green, mask);  //掩膜相加
            //    CvInvoke.Imshow("mask", mask);          //顯示合在一起的掩膜

            //    VectorOfVectorOfPoint contours_red = new VectorOfVectorOfPoint();
            //    VectorOfRect hierachy_red = new VectorOfRect();
            //    CvInvoke.FindContours(mask_red, contours_red, hierachy_red, RetrType.External, ChainApproxMethod.ChainApproxNone);

            //    for (int i = 0; i < contours_red.Size; i++)
            //    {
            //        Rectangle rect = CvInvoke.BoundingRectangle(contours_red[i]);
            //        if (rect.Width < 10 || rect.Height < 10)                //對於太小的外接矩形,刪除掉
            //            continue;
            //        CvInvoke.Rectangle(frame, rect, new MCvScalar(255, 0, 0), 1);
            //        CvInvoke.PutText(frame, "red", new Point(rect.X, rect.Y - 5), FontFace.HersheyComplexSmall, 1.2, new MCvScalar(0, 255, 0));
            //    }

            //    VectorOfVectorOfPoint contours_green = new VectorOfVectorOfPoint();
            //    VectorOfRect hierachy_green = new VectorOfRect();
            //    CvInvoke.FindContours(mask_green, contours_green, hierachy_green, RetrType.External, ChainApproxMethod.ChainApproxNone);

            //    for (int i = 0; i < contours_green.Size; i++)
            //    {
            //        Rectangle rect = CvInvoke.BoundingRectangle(contours_green[i]);
            //        if (rect.Width < 10 || rect.Height < 10)                //對於太小的外接矩形,刪除掉
            //            continue;
            //        CvInvoke.Rectangle(frame, rect, new MCvScalar(255, 0, 0), 1);
            //        CvInvoke.PutText(frame, "green", new Point(rect.X, rect.Y - 5), FontFace.HersheyComplexSmall, 1.2, new MCvScalar(0, 255, 0));
            //    }
            //    CvInvoke.Imshow("hsv_track", frame);
            //    if (CvInvoke.WaitKey(30) == 27)
            //    {
            //        break;
            //    }
            //}


            ///手掌膚色提取

            Mat src = CvInvoke.Imread("2.bmp");

            double h_min = 0, s_min = 70, v_min = 70;       //手的HSV顏色分佈
            double h_max = 15, s_max = 255, v_max = 255;

            ScalarArray hsv_min = new ScalarArray(new MCvScalar(h_min, s_min, v_min));
            ScalarArray hsv_max = new ScalarArray(new MCvScalar(h_max, s_max, v_max));

            Mat hsvimg = new Mat();
            Mat mask = new Mat();

            CvInvoke.CvtColor(src, hsvimg, ColorConversion.Bgr2Hsv);
            CvInvoke.InRange(hsvimg, hsv_min, hsv_max, mask);
            CvInvoke.MedianBlur(mask, mask, 5);

            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
            VectorOfRect hierarchy = new VectorOfRect();
            //發現輪廓
            CvInvoke.FindContours(mask, contours, hierarchy, RetrType.External, ChainApproxMethod.ChainApproxNone);

            for(int i = 0; i< contours.Size;i++)
            {
                Rectangle rect = CvInvoke.BoundingRectangle(contours[i]);
                if (rect.Width < 10 || rect.Height < 10)
                    continue;
                CvInvoke.Rectangle(src, rect, new MCvScalar(255, 0, 0));
                CvInvoke.PutText(src, "hand", new Point(rect.X, rect.Y - 5), FontFace.HersheyComplexSmall, 1.2, new MCvScalar(0, 0, 255));
            }
            CvInvoke.Imshow("hsv_track", src);

            CvInvoke.WaitKey(0);

        }
    }
}

效果

1、尋找圖像紅色部分:
在這裏插入圖片描述
掩膜:
在這裏插入圖片描述
2、尋找紅色部分:
在這裏插入圖片描述
3、尋找視頻中的綠色部分:

在這裏插入圖片描述
4、尋找視頻中紅色與綠色物體:
在這裏插入圖片描述
5、根據手的HSV特徵尋找手:
在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章