請先參考下面這一篇, 篩選RGB得到顏色範圍內的遮罩
    • RGB顏色範圍內的遮罩應用 Part II

    • ----------------------------------------------------

    • 先來認識inRange函式定義

    • inRange

      Checks if array elements lie between the elements of two other arrays.

      C++: void inRange(InputArray src, InputArray lowerb, InputArray upperb, OutputArray dst)
      Python: cv2.inRange(src, lowerb, upperb[, dst]) → dst
      C: void cvInRange(const CvArr* src, const CvArr* lower, const CvArr* upper, CvArr* dst)
      C: void cvInRangeS(const CvArr* src, CvScalar lower, CvScalar upper, CvArr* dst)
      Python: cv.InRange(src, lower, upper, dst) → None
      Python: cv.InRangeS(src, lower, upper, dst) → None

      Parameters:

      • src – first input array.
      • lowerb – inclusive lower boundary array or a scalar.
      • upperb – inclusive upper boundary array or a scalar.
      • dst – output array of the same size as src and CV_8U type.

      The function checks the range as follows:

      • For every element of a single-channel input array:

        \texttt{dst} (I)= \texttt{lowerb} (I)_0  \leq \texttt{src} (I)_0 \leq  \texttt{upperb} (I)_0

      • For two-channel arrays:

        \texttt{dst} (I)= \texttt{lowerb} (I)_0  \leq \texttt{src} (I)_0 \leq  \texttt{upperb} (I)_0  \land \texttt{lowerb} (I)_1  \leq \texttt{src} (I)_1 \leq  \texttt{upperb} (I)_1

      • and so forth.

      That is, dst (I) is set to 255 (all 1 -bits) if src (I) is within the specified 1D, 2D, 3D, ... box and 0 otherwise.

      When the lower and/or upper boundary parameters are scalars, the indexes (I) at lowerb and upperb in the above formulas should be omitted.

    • ----------------------------------------------------

接下來, RGB2HSV

colorInRange.h

image

colorInRange.cpp

void ImgProc::RGB2HSV()
{
    Mat dst = RGB2HSV(m_src);
    namedWindow("HSV", CV_WINDOW_NORMAL);
    cv::imshow("HSV", dst);
}
Mat ImgProc::RGB2HSV(const Mat& src)
{
    assert(src.type() == CV_8UC3);
 
    Mat dst;
    cv::cvtColor(src, dst, CV_BGR2HSV);
    return dst;
}

Form1.cs

private void rGB2HSVToolStripMenuItem_Click(object sender, EventArgs e)
{
    m_ip.RGB2HSV();
}

測試RGB2HSV

image

--------------------------------------------------------

接下來, 測試BGR抽離

colorInRange.h

image

colorInRange.cpp

void ImgProc::splitColorBGR()
{
    vector<Mat> spl = splitColor(m_src);
    namedWindow("spl1", CV_WINDOW_NORMAL);
    namedWindow("spl2", CV_WINDOW_NORMAL);
    namedWindow("spl3", CV_WINDOW_NORMAL);
    cv::imshow("spl1", spl[0]);            //b
    cv::imshow("spl2", spl[1]);            //g
    cv::imshow("spl3", spl[2]);            //r
}
vector<Mat> ImgProc::splitColor(const Mat& src)
{
    vector<Mat> dst;
    cv::split(src, dst);
    return dst;
}

Form1.cs

image

private void splitRGBToolStripMenuItem_Click(object sender, EventArgs e)
{
    m_ip.splitColorBGR();
}

測試結果1 (BGR抽離)

image

測試結果2 (BGR抽離)

image

--------------------------------------------------------

接下來, 要測試輸出R,G,B三個矩陣的像素值到一個或三個txt檔案[5]

colorInRange.h

image

colorInRange.cpp

// 輸出RGB像素
    void ImgProc::outputTxtRGB(wchar_t* fileRed, wchar_t* fileGreen, wchar_t* fileBlue)
    {
        wstring wsR(fileRed);
        wstring wsG(fileGreen);
        wstring wsB(fileBlue);
        string nameR = ImgProc::WstringToString(wsR);
        string nameG = ImgProc::WstringToString(wsG);
        string nameB = ImgProc::WstringToString(wsB);
        outputTxtRGB(m_src, nameR.c_str(), nameG.c_str(), nameB.c_str() );
        //cv::FileStorage file(name.c_str(), cv::FileStorage::WRITE);
        //file << m_src;
    }
    void ImgProc::outputTxtRGB(const Mat& src, const char* fileRed, const char* fileGreen, const char* fileBlue)
    {
        ofstream foutRed, foutGreen, foutBlue;
        foutRed.open(fileRed, std::ios_base::out);
        foutGreen.open(fileGreen, std::ios_base::out);
        foutBlue.open(fileBlue, std::ios_base::out);
 
        if (!foutRed)
            return;
        if (!foutGreen)
            return;
        if (!foutBlue)
            return;
 
 
        for (int i = 0; i< src.rows; i++)
        {
            for (int j = 0; j<src.cols; j++)
            {
                foutBlue  << setw(3) << (int)src.at<cv::Vec3b>(i, j)[0] << " ";
                foutGreen << setw(3) << (int)src.at<cv::Vec3b>(i, j)[1] << " ";
                foutRed   << setw(3) << (int)src.at<cv::Vec3b>(i, j)[2] << " ";
            }
            foutBlue << endl;
            foutGreen << endl;
            foutRed << endl;
        }
 
        foutBlue.close();
        foutGreen.close();
        foutRed.close();
    }

Form1.cs

private void outputRGBTextFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using (SaveFileDialog sfdR = new SaveFileDialog())
            using (SaveFileDialog sfdG = new SaveFileDialog())
            using (SaveFileDialog sfdB = new SaveFileDialog())
            {
                sfdR.Filter = "Text File|*.txt|Csv File|*.csv";
                sfdR.Title = "輸出Red純文字檔案";
                sfdG.Filter = "Text File|*.txt|Csv File|*.csv";
                sfdG.Title = "輸出Green純文字檔案";
                sfdB.Filter = "Text File|*.txt|Csv File|*.csv";
                sfdB.Title = "輸出Blue純文字檔案";
 
                if (sfdR.ShowDialog() == System.Windows.Forms.DialogResult.OK & 
                    sfdG.ShowDialog() == System.Windows.Forms.DialogResult.OK &
                    sfdB.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    unsafe
                    {
                        fixed (char* fileR = sfdR.FileName)
                        fixed (char* fileG = sfdG.FileName)
                        fixed (char* fileB = sfdB.FileName)
                        {
                            m_ip.outputTxtRGB(fileR, fileG, fileB);
                        }
                    }
                }
            }
        }

Red channel

image

Green channel

image

Blue channel

image

MATLAB驗證

image

下載範例

--------------------------------------------------------

接下來, 測試HSV抽離出來並輸出純文字檔案[7]

Different applications use different scales for HSV. For example gimp uses H = 0-360, S = 0-100 and V = 0-100. But OpenCV uses H: 0 - 180, S: 0 - 255, V: 0 - 255

以下為wiki HSL和HSV幾何示意圖[8]

H channel

image

MATLAB驗證

image

S channel

image

MATLAB驗證

image

V channel

image

MATLAB驗證

image

--------------------------------------------------------

所以, 接下來可以套用在HSV顏色範圍內的遮罩

image

colorInRange.h

#include <wchar.h>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <fstream>
#include <iomanip>
 
#pragma once
 
using namespace std;
using namespace cv;
 
namespace CVision
{
    public ref class ImgProc
    {
    public:
        void runColorInRangeHSV(double minH, double maxH, double minS, double maxS, double minV, double maxV);    // 執行HSV顏色範圍內像素
        void outputTxtHSV(wchar_t* fileH, wchar_t* fileS, wchar_t* fileV);                                        // 輸出HSV像素
        void outputTxtRGB(wchar_t* fileRed, wchar_t* fileGreen, wchar_t* fileBlue);                                  // 輸出RGB像素
        void splitColorBGR();
        void RGB2HSV();
        void runColorInRangeRGB(UINT minR, UINT maxR, UINT minG, UINT maxG, UINT minB, UINT maxB);                // 執行RGB顏色範圍內像素
        bool imread(wchar_t* filename);     
        bool imshow();
        ImgProc();
        ~ImgProc();
 
    private:
        Mat colorInRangeHSV(const Mat& src, double minH, double maxH, double minS, double maxS, double minV, double maxV);    // 篩選HSV顏色範圍內像素
        void outputTxtHSV(const Mat& src, const char* fileH, const char* fileS, const char* fileV);               // 輸出HSV像素
        void outputTxtRGB(const Mat& src, const char* fileRed, const char* fileGreen, const char* fileBlue);      // 輸出RGB像素  
        vector<Mat> splitColor(const Mat& src);
        Mat RGB2HSV(const Mat& src);
        Mat colorInRangeRGB(const Mat& src, UINT minR, UINT maxR, UINT minG, UINT maxG, UINT minB, UINT maxB);    // 篩選RGB顏色範圍內像素
        std::string WstringToString(const std::wstring str);
 
    };
 
    ImgProc::ImgProc()
    {
    }
 
    ImgProc::~ImgProc()
    {
    }
 
 
}

colorInRange.cpp

// 執行HSV顏色範圍內像素
void ImgProc::runColorInRangeHSV(double minH, double maxH, double minS, double maxS, double minV, double maxV)
{
    Mat dst;
    Mat mask;
    
    cvtColor(m_src, dst, CV_BGR2HSV);
    mask = colorInRangeHSV(dst, minH, maxH, minS, maxS, minV, maxV);
    if (!mask.data)
        return;
 
    // Show source image
    namedWindow("color in range of HSV", CV_WINDOW_NORMAL);
    cv::imshow("color in range of HSV", mask);
}
// 篩選HSV顏色範圍內像素
Mat ImgProc::colorInRangeHSV(const Mat& src, double minH, double maxH, double minS, double maxS, double minV, double maxV)
{
    assert(src.type() == CV_8UC3);
    Mat mask;
    //inRange(src, Scalar(minH, minS, minV), Scalar(maxH, maxS, maxV), mask);
    inRange(src, Scalar_<double>(minH, minS, minV), Scalar_<double>(maxH, maxS, maxV), mask);
    return mask;
}

Video 2016 03 31 143650 HSV animation

image

下載範例



參考資料

1. RGB顏色範圍內的遮罩應用 Part I: Visual Studio 2013編譯環境建構

2. RGB顏色範圍內的遮罩應用 Part II

3. Quick Installation for OpenCV 2.4.10 with Visual Studio 2013

4. i want to split and show R B G pictures ,why does it not work?

5. How to write a Float Mat to a file in OpenCV

6. Writing ASCII to file

7. Choosing correct HSV values for OpenCV thresholding with InRangeS

8. HSL和HSV色彩空間

9. Changing Colorspaces Object Tracking

10. OpenCV Extract colors 用HSV空間 分離顏色

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 me1237guy 的頭像
    me1237guy

    天天向上

    me1237guy 發表在 痞客邦 留言(0) 人氣()