OpenCV視頻篇——顏色跟蹤

@[TOC]


在這里插入圖片描述

一森瘪、黑白圖片

來(lái)自:輕舞飛揚(yáng)

在了解色彩空間前牡属,先了解一下黑白圖片的形成。

用光線對(duì)著傳感器扼睬,從傳感器的立場(chǎng)上來(lái)看的話逮栅,一部分接收到了光線,那么這一部分就是明亮的窗宇,一部分沒有接收到光線措伐,那么這一部分將會(huì)是黑暗的,我們可以視為傳感器存在兩個(gè)通道军俊。

如果傳感器存在多個(gè)通道的話侥加,意思就是說我們將光線進(jìn)行分類,高能量的粪躬,中等能量的担败,低能量的等等多種分類,傳感器對(duì)這多種能力進(jìn)行區(qū)分顯示出不同的顏色镰官。

不同的顏色有不同的能量分布提前,一般來(lái)說紅色(R)在600-700nm波長(zhǎng)處能量最高,綠色在534-555nm處能量最高泳唠,藍(lán)色(B)在420-440nm處能力最高狈网。

在這里插入圖片描述

二、HSV顏色空間

?色調(diào)H
用角度度量笨腥,取值范圍為0°~360°拓哺,從紅色開始按逆時(shí)針方向計(jì)算,紅色為0°脖母,綠色為120°,藍(lán)色為240°士鸥。它們的補(bǔ)色是:黃色為60°,青色為180°,品紅為300°镶奉;

?飽和度S
飽和度S表示顏色接近光譜色的程度础淤。一種顏色,可以看成是某種光譜色與白色混合的結(jié)果哨苛。其中光譜色所占的比例愈大鸽凶,顏色接近光譜色的程度就愈高,顏色的飽和度也就愈高建峭。飽和度高玻侥,顏色則深而艷。光譜色的白光成分為0亿蒸,飽和度達(dá)到最高南用。通常取值范圍為0%~100%瞬浓,值越大,顏色越飽和。

?明度V
明度表示顏色明亮的程度封救,對(duì)于光源色,明度值與發(fā)光體的光亮度有關(guān)酱畅;對(duì)于物體色弄喘,此值和物體的透射比或反射比有關(guān)。通常取值范圍為0%(黑)到100%(白)贡蓖。

HSV模型的三維表示從RGB立方體演化而來(lái)曹鸠。設(shè)想從RGB沿立方體對(duì)角線的白色頂點(diǎn)向黑色頂點(diǎn)觀察,就可以看到立方體的六邊形外形斥铺。六邊形邊界表示色彩彻桃,水平軸表示純度,明度沿垂直軸測(cè)量晾蜘。<center>


在這里插入圖片描述

在這里插入圖片描述

</center>


在這里插入圖片描述

三邻眷、OpenCV中的HSV

HSV顏色空間與人眼較為接近,一般以HSV為顏色檢測(cè)和識(shí)別笙纤。
opencv H范圍(0-180) S(0-255) V(0-255)耗溜。

1. HSV二值化處理的函數(shù):

  • 說明
    檢查數(shù)組元素是否位于其他兩個(gè)數(shù)組的元素之間。
    該功能檢查范圍如下:

    ?? 對(duì)于單通道輸入數(shù)組的每個(gè)元素:
    \texttt{dst} (I)= \texttt{lowerb} (I)_0 \leq \texttt{src} (I)_0 \leq \texttt{upperb} (I)_0
    ?? 對(duì)于兩通道陣列:
    \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

    也就是說省容,如果src(I)在指定的1D抖拴,2D,3D等區(qū)域內(nèi)腥椒,則dst(I)設(shè)置為255(全1位)阿宅,否則設(shè)置為0。

    ==高低閾值指的是hsv的高低閾值,當(dāng)圖像的hsv在高低閾值之間那么輸出圖像為255(白)笼蛛,否則為0(黑色)洒放。==

    當(dāng)下邊界參數(shù)和/或上邊界參數(shù)為標(biāo)量時(shí),應(yīng)忽略上式中在lowerb和upperb處的索引(I)滨砍。

  • 聲明
    void inRange(InputArray src, InputArray lowerb,InputArray upperb, OutputArray dst);
    
  • 參數(shù)
    src 輸入圖像
    lowerb 低閾值
    upperb 高閾值往湿。
    dst 輸出圖像(大小與輸入圖像一樣妖异,類型是8U)相當(dāng)于:Mat dstImage = Mat::zeros(srcImage.size(),CV_8U);

2. HSV顏色范圍的選取:

HSV色環(huán)

內(nèi)容來(lái)自: 阿卡蒂奧

比如我們選擇某個(gè)偏紅色的范圍:
?? 1. 色環(huán)圖中這個(gè)區(qū)間即BGR(0,128,255)到BGR(255,0,213)领追;
?? 2. B他膳、G、R這三個(gè)通道的范圍分別為0-255绒窑,0-128棕孙,213-255。
?? 3. 因此閾值下限lowerb=Scalar(0,0,213)些膨,閾值上限upperb=Scalar(255,128,255)蟀俊。


在這里插入圖片描述

四、顏色直方圖的獲取與目標(biāo)跟蹤

1. 顏色直方圖的獲取

顏色直方圖是對(duì)運(yùn)動(dòng)目標(biāo)表面顏色分布的統(tǒng)計(jì)订雾,不受目標(biāo)的形狀肢预、姿態(tài)等變化的影響。所以用直方圖作為目標(biāo)的特征洼哎,依據(jù)顏色分布進(jìn)行匹配误甚,具有穩(wěn)定性好、抗部分遮擋谱净、計(jì)算方法簡(jiǎn)單和計(jì)算量小的特點(diǎn)窑邦,是比較理想的目標(biāo)顏色特征。為了抵抗光照亮暗帶來(lái)的影響壕探,一般的顏色直方圖均在HSV色系下提取冈钦。

對(duì)HSV3個(gè)分量按照對(duì)顏色變化的敏感程度不同分別進(jìn)行量化。設(shè)量化后李请,3個(gè)分量的取值范圍分別為\{0,1,...L_H-1\}瞧筛,\{0,1,...,L_S-1\}\{0,1,...,L_V-1\}按照[H导盅,S较幌,V]的形式排列成一個(gè)矢量,則其范圍為:\{0,1,...,L_H-1,...,L_H+L_S-1,...,L_H+L_S+L_V-1\}設(shè)顏色i的像素點(diǎn)個(gè)數(shù)為m_i,圖像的像素點(diǎn)的總數(shù)為:<center>

在這里插入圖片描述
</center>
則顏色i的出現(xiàn)概率白翻,即被定義為顏色直方圖乍炉,即<center>
在這里插入圖片描述

</center>

2.基于顏色直方圖的目標(biāo)跟蹤

因?yàn)轭伾狈綀D是矢量,以此作為特征進(jìn)行目標(biāo)跟蹤時(shí)滤馍,即基于顏色直方圖的目標(biāo)跟蹤時(shí)岛琼,可采用Bhattacharyya距離作為兩直方圖相似度的度量。計(jì)算公式為:<center>
在這里插入圖片描述
在這里插入圖片描述

</center>

其中:ρ為兩直方圖的Bhattacharyya系數(shù)巢株;p為候選目標(biāo)直方圖分布槐瑞;q為模板直方圖分布;d為兩直方圖的Bhattacharyya距離阁苞,其值越小困檩,表明兩直方圖的相似度越高祠挫;反之,兩直方圖相似度越低悼沿。

五茸歧、camshift算法原理

camshift就是利用目標(biāo)的顏色直方圖模型將圖像轉(zhuǎn)換為顏色概率分布圖,初始化一個(gè)搜索窗的大小和位置显沈,并根據(jù)上一幀得到的結(jié)果自適應(yīng)調(diào)整搜索窗口的位置和大小,從而定位出當(dāng)前圖像中目標(biāo)的中心位置逢唤。

分為三個(gè)部分:

1. 色彩投影圖(反向投影):

(1) RGB顏色空間對(duì)光照亮度變化較為敏感拉讯,為了減少此變化對(duì)跟蹤效果的影響,==首先將圖像從RGB空間轉(zhuǎn)換到HSV空間==鳖藕。

(2) 然后==對(duì)其中的H分量作直方圖魔慷,在直方圖中代表了不同H分量值出現(xiàn)的概率或者像素個(gè)數(shù)==,就是說可以查找出H分量大小為h的概率或者像素個(gè)數(shù)著恩,即得到了顏色概率查找表院尔。

(3) ==將圖像中每個(gè)像素的值用其顏色出現(xiàn)的概率對(duì)替換,就得到了顏色概率分布圖==喉誊。這個(gè)過程就叫反向投影邀摆,顏色概率分布圖是一個(gè)灰度圖像。

2. meanshift

meanshift算法是一種密度函數(shù)梯度估計(jì)的非參數(shù)方法伍茄,通過迭代尋優(yōu)找到概率分布的極值來(lái)定位目標(biāo)栋盹。
算法過程:
??1). 在顏色概率分布圖中選取搜索窗W
??2). 計(jì)算階距:

  • ?????? 計(jì)算零階矩
    M_{00}=\sum_x\sum_yI(x,y)
  • ?????? 計(jì)算一階矩:
    M_{10}=\sum_x\sum_y{xI(x,y) }
    M_{01}=\sum_x\sum_y{yI(x,y)}
  • ?????? 計(jì)算搜索窗的質(zhì)心:
    x_c=\frac{M_{10}}{M_{00}};
    y_c=\frac{M_{01}}{M_{00}};

??3)調(diào)整搜索窗的大小
寬度:s=\sqrt{\frac{M_{00}}{256}};
長(zhǎng)度: l=1.2s;
??4)移動(dòng)搜索窗的中心到質(zhì)心敷矫,如果移動(dòng)距離大于預(yù)設(shè)的固定閾值例获,則重復(fù)2)3)4),直到搜索窗的中心與質(zhì)心間的移動(dòng)距離小于預(yù)設(shè)的固定閾值曹仗,或者循環(huán)運(yùn)算的次數(shù)達(dá)到某一最大值榨汤,停止計(jì)算。關(guān)于meanshift的收斂性證明可以google相關(guān)文獻(xiàn)怎茫。

3. camshift

將meanshift算法擴(kuò)展到連續(xù)圖像序列收壕,就是camshift算法。==它將視頻的所有幀做meanshift運(yùn)算轨蛤,并將上一幀的結(jié)果啼器,即搜索窗的大小和中心,作為下一幀meanshift算法搜索窗的初始值==俱萍。如此迭代下去端壳,就可以實(shí)現(xiàn)對(duì)目標(biāo)的跟蹤。

算法過程

(1).初始化搜索窗
(2).計(jì)算搜索窗的顏色概率分布(反向投影)
(3).運(yùn)行meanshift算法枪蘑,獲得搜索窗新的大小和位置损谦。
(4).在下一幀視頻圖像中用(3)中的值重新初始化搜索窗的大小和位置岖免,再跳轉(zhuǎn)到(2)繼續(xù)進(jìn)行。

camshift能有效解決目標(biāo)變形和遮擋的問題照捡,對(duì)系統(tǒng)資源要求不高颅湘,時(shí)間復(fù)雜度低,在簡(jiǎn)單背景下能夠取得良好的跟蹤效果栗精。但當(dāng)背景較為復(fù)雜闯参,或者有許多與目標(biāo)顏色相似像素干擾的情況下,會(huì)導(dǎo)致跟蹤失敗悲立。因?yàn)樗鼏渭兊目紤]顏色直方圖鹿寨,忽略了目標(biāo)的空間分布特性,所以這種情況下需加入對(duì)跟蹤目標(biāo)的預(yù)測(cè)算法薪夕。

4. OpenCV中相關(guān)API

1. 直方圖

前面已經(jīng)提過:
OpenCV--017:圖像直方圖
OpenCV--018:圖像直方圖均衡化
OpenCV--020:圖像直方圖反向投影
OpenCV--021:直方圖規(guī)定化

2. CamShift函數(shù)
  • 說明
    查找對(duì)象的中心脚草,大小和方向。

  • 聲明

    RotatedRect cv::CamShift(
            InputArray probImage,
            Rect &window,
            TermCriteria criteria 
    )       
    Python:
           retval, window=cv.CamShift(  probImage, window, criteria )
    
  • 參數(shù)

    probImage 對(duì)象直方圖的反向投影原献。
    window 初始搜索窗口馏慨。
    criteria 底層meanShift的停止條件。

    criterial:
    OpenCV--TermCriteria類
    返回(在舊接口中)CAMSHIFT用于收斂函數(shù)的迭代次數(shù)姑隅,實(shí)現(xiàn)CAMSHIFT對(duì)象跟蹤算法写隶。首先,它使用meanShift找到一個(gè)對(duì)象中心讲仰,然后調(diào)整窗口大小樟澜,找到最佳旋轉(zhuǎn)。該函數(shù)返回旋轉(zhuǎn)后的矩形結(jié)構(gòu)叮盘,其中包括對(duì)象位置秩贰、大小和方向。通過RotatedRect::boundingRect()可以獲得搜索窗口的下一個(gè)位置柔吼。

六毒费、基于顏色特征的目標(biāo)跟蹤

//用HSV中的Hue分量進(jìn)行跟蹤

     Mat image;
    //表示是否要進(jìn)入反向投影模式,true則表示要進(jìn)入反向投影模式
    bool backprogectMode = false;

    //表示在選中要跟蹤的初始目標(biāo)愈魏,true表示正在用鼠標(biāo)選擇要跟蹤的目標(biāo)
    bool selectObject = false;

    //跟蹤目標(biāo)的個(gè)數(shù)
    int trackObject = 0;

    //是否顯示HUE分量直方圖
    bool showHist = true;

    //用于保存鼠標(biāo)選擇第一次單擊時(shí)點(diǎn)的位置
    Point origin;

    //用于保存鼠標(biāo)選擇的矩形框
    Rect selection;


    int vmin = 10, vmax = 256, smin = 30;

    //鼠標(biāo)事件,該函數(shù)用鼠標(biāo)進(jìn)行跟蹤目標(biāo)的選擇
    static void onMouse(int event,int x,int y,int ,void*) {
        //鼠標(biāo)左鍵按下時(shí)觅玻,則條件為true,在用鼠標(biāo)進(jìn)行目標(biāo)選擇
        //if里面的代碼塊就是確定所選擇的矩形區(qū)域selection
        if (selectObject) {
            //確定鼠標(biāo)點(diǎn)擊的矩形左上角頂點(diǎn)的坐標(biāo)
            selection.x = MIN(x, origin.x);
            cout << "origin: " << origin.x <<",";
            selection.y = MIN(y, origin.y);
            cout << origin.y << endl;

            selection.width = std::abs(x - origin.x);//矩形寬
            selection.height = std::abs(y - origin.y);//矩形高

            //用于確保所選的矩形區(qū)域在圖片區(qū)域內(nèi)
            selection &= Rect(0, 0, image.cols, image.rows);
        }

        switch (event)
        {
        //鼠標(biāo)按下,開始點(diǎn)擊選擇跟蹤物體
        case EVENT_LBUTTONDOWN:
            //記錄鼠標(biāo)第一次按下的位置
            origin = Point(x, y);
            //鼠標(biāo)剛按下去時(shí),初始化了一個(gè)矩形區(qū)域
            selection = Rect(x, y, 0, 0);
            selectObject = true;
            break;

        //鼠標(biāo)松開,完成選擇跟蹤物體
        case EVENT_LBUTTONUP:
            selectObject = false;
            //如果選擇物體有效培漏,則打開跟蹤功能
            if (selection.width > 0 && selection.height > 0)
                trackObject = -1;
            break;
        }
    }

    static void help() {
        cout << "\n這是一個(gè)基于meanShift算法的demo:\n"
            "   你可以選擇一個(gè)跟蹤的顏色目標(biāo)溪厘,比如你的臉。\n";
        cout << "\n\nHot keys: \n"
            "\tESC - quit the program\n"
            "\tc - stop the tracking\n"
            "\tb - switch to/from backprojection view\n"
            "\th - show/hide object histogram\n"
            "To initialize tracking, select the object with mouse: \n";
    }
    

    static void camshiftTest() {
        help();
        VideoCapture cap;
        Rect trackWindow;

        int hsize = 16;
        float hranges[] = { 0,180 };
        const float* phranges = hranges;
        
        
        //打開默認(rèn)的攝像頭
        cap.open(0);
        //判斷攝像頭是否成功打開
        if (!cap.isOpened())
        {
            help();
            cout << "***could not initialize capturing...***\n";
            return ;
        }

        //直方圖窗口:用于顯示直方圖
        namedWindow("Histogram", 0);
        //CamShift :用于顯示視頻
        namedWindow("CamShift Demo", 0);
        //設(shè)置鼠標(biāo)回調(diào)函數(shù)
        setMouseCallback("CamShift Demo", onMouse, 0);
        //createTrackbar函數(shù)的功能是在對(duì)應(yīng)的CamShift Demo窗口創(chuàng)建滑動(dòng)條Vmin,Vmax,Smin
        //滑動(dòng)條的值最大為256,最后一個(gè)參數(shù)為0代表沒有調(diào)用滑動(dòng)拖動(dòng)的響應(yīng)函數(shù)
        //vmin,vmax,smin初始值分別為10牌柄,256畸悬,30
        createTrackbar("Vmin", "CamShift Demo", &vmin, 256, 0);
        createTrackbar("Vmax", "CamShift Demo", &vmax, 256, 0);
        createTrackbar("Smin", "CamShift Demo", &smin, 256, 0);

        Mat frame, hsv, hue, mask, hist, histimg = Mat::zeros(200, 320, CV_8UC3), backproj;
        bool paused = false;
        for (;;) {
            if (!paused)
            {
                //從攝像頭中讀取的一幀存在frame中
                cap >> frame;
                //若讀取失敗,停止循環(huán)
                if (frame.empty())
                {
                    break;
                }
            }
            frame.copyTo(image);

            if (!paused)
            {
                //將BGR顏色空間轉(zhuǎn)化成HSV顏色空間
                cvtColor(image, hsv, COLOR_BGR2HSV);

                //判斷是否存在需要追蹤的目標(biāo),非0即有需要跟蹤的目標(biāo)
                if (trackObject)
                {
                    //獲取進(jìn)度條中設(shè)置的值
                    int _vmin = vmin, _vmax = vmax;
                    //inRange函數(shù)的功能是檢查輸入數(shù)組每個(gè)元素大小是否在2個(gè)給定數(shù)值之間珊佣,
                    //如果3個(gè)通道都在對(duì)應(yīng)的范圍內(nèi)蹋宦,則mask對(duì)應(yīng)的那個(gè)點(diǎn)的值全為1(0xff)披粟,否則為0(0x00).

                    //可以是多通道的,mask保存0通道的最小值,也就是h分量
                    //這里利用了hsv的3個(gè)通道冷冗,比較h:0~180,s:smin~256,v:min(vmin,vmax),max(vmin,vmax)守屉。
                    inRange(hsv, Scalar(0, smin, MIN(_vmin, _vmax)), Scalar(180, 256, MAX(_vmin, _vmax)), mask);
                    
                    int ch[] = { 0,0 };
                    //hue初始化為與hsv大小深度一樣的矩陣,色調(diào)的度量是用角度表示的蒿辙,紅綠藍(lán)之間相差120度拇泛,反色相差180度
                    hue.create(hsv.size(), hsv.depth());
                    //將hsv第一個(gè)通道(也就是色調(diào))的數(shù)復(fù)制到hue中,0索引數(shù)組
                    mixChannels(&hsv, 1, &hue, 1, ch, 1);

                    //表示已經(jīng)選擇了有效地待追蹤區(qū)域
                    if (trackObject < 0)
                    {
                        //此處的構(gòu)造函數(shù)roi用的是Mat hue的矩陣頭思灌,且roi的數(shù)據(jù)指針指向hue俺叭,即共用相同的數(shù)據(jù),selection為其感興趣的區(qū)域
                        Mat roi(hue, selection);
                        //設(shè)置掩膜板選擇框?yàn)镽OI
                        Mat maskroi(mask, selection);
                        //得到選擇框內(nèi)且滿足掩膜板內(nèi)的直方圖
                        //calcHist()函數(shù):第1個(gè)參數(shù):輸入矩陣序列
                                      //  第2個(gè)參數(shù):表示輸入的矩陣數(shù)目习瑰,
                                      //  第3個(gè)參數(shù):表示將被計(jì)算直方圖維數(shù)通道的列表,
                                      //  第4個(gè)參數(shù):表示可選的掩碼函數(shù)
                                      //  第5個(gè)參數(shù):表示輸出直方圖秽荤,
                                      //  第6個(gè)參數(shù): 表示直方圖的維數(shù)甜奄,
                                      //  第7個(gè)參數(shù): 為每一維直方圖數(shù)組的大小,
                                      //  第8個(gè)參數(shù): 為每一維直方圖bin的邊界
                        
                        calcHist(&roi, 1, 0, maskroi, hist, 1, &hsize, &phranges);
                        
                        //將hist矩陣進(jìn)行歸一化窃款,都?xì)w一化到0-255
                        normalize(hist, hist, 0, 255, NORM_MINMAX);

                        trackWindow = selection;
                        //置trackObject為1,表明屬性提取完成
                        //只要鼠標(biāo)選完區(qū)域松開后课兄,且沒有按鍵盤清0鍵'c',則trackObject一直保持為1晨继,因此該if函數(shù)只能執(zhí)行一次烟阐,除非重新選擇跟蹤區(qū)域
                        trackObject = 1;

                        //與按下‘c’鍵是一樣的,這里的all(0)表示的是標(biāo)量全部清0
                        histimg = Scalar::all(0);

                        //histing是一個(gè)200*300的矩陣紊扬,hsize應(yīng)該是每一個(gè)bin的寬度蜒茄,也就是histing矩陣能分出幾個(gè)bin出來(lái)
                        int binW = histimg.cols / hsize;

                        //定義一個(gè)緩沖單bin矩陣
                        Mat buf(1, hsize, CV_8UC3);
                        //saturate_case函數(shù)為從一個(gè)初始類型準(zhǔn)確變換到另一個(gè)初始類型
                        for (int i = 0; i < hsize; i++)
                        {
                            buf.at<Vec3b>(i) = Vec3b(saturate_cast<uchar>(i * 180. / hsize), 255, 255);
                        }
                        cvtColor(buf, buf, COLOR_HSV2BGR);

                        for (int i = 0; i < hsize; i++)
                        {
                            //at函數(shù)為返回一個(gè)指定數(shù)組元素的參考值                                                          
                            //畫直方圖到圖像空間,指定左上角和右下角餐屎,并定義顏色檀葛,大小,線型等
                            int val = saturate_cast<int>(hist.at<float>(i) * histimg.rows / 255);
                            rectangle(  histimg,
                                        Point(i * binW, histimg.rows),
                                        Point((i + 1) * binW, histimg.rows - val),
                                        Scalar(buf.at<Vec3b>(i)),-1, 8);
                        }
                    }

                    //計(jì)算直方圖的反向投影
                    //計(jì)算hue圖像0通道直方圖hist的反向投影腹缩,并讓入backproj中
                    calcBackProject(&hue, 1, 0, hist, backproj, & phranges);
                    backproj &= mask;
                    //得到掩膜內(nèi)的反向投影
                    //trackWindow為鼠標(biāo)選擇的區(qū)域屿聋,TermCriteria為確定迭代終止的準(zhǔn)則
                    //使用MeanShift算法對(duì)backproj中的內(nèi)容進(jìn)行搜索,返回跟蹤結(jié)果
                    RotatedRect trackBox = CamShift(backproj, trackWindow,TermCriteria(1 | 2, 10, 1)); 
                    //如果鼠標(biāo)選擇的區(qū)域trackWindow小于等于1,重置trackWindow區(qū)域
                    if (trackWindow.area() <= 1)
                    {
                        int cols = backproj.cols, rows = backproj.rows, r = (MIN(cols, rows) + 5) / 6;
                        trackWindow = Rect(trackWindow.x - r, trackWindow.y - r,
                            trackWindow.x + r, trackWindow.y + r) &
                            Rect(0, 0, cols, rows);
                    }
                    if (backprogectMode)
                        cvtColor(backproj, image, COLOR_GRAY2BGR);

                    //畫出跟蹤結(jié)果的位置:以橢圓為代表
                    ellipse(image, trackBox, Scalar(0, 0, 255), 3);
                }
            }
            else if (trackObject < 0) {
                paused = false;
            }

            //如果正處于物體選擇藏鹊,畫出選擇框
            if (selectObject && selection.width > 0 && selection.height > 0)
            {
                Mat roi(image, selection);
                bitwise_not(roi, roi);// bitwise_not為將每一個(gè)bit位取反
            }

            imshow("CamShift Demo", image);
            imshow("Histogram", histimg);

            char c = (char)waitKey(10);
            if (c == 27)//退出鍵
                break;
            switch (c)
            {
            case 'b'://反向投影模型交替
                backprogectMode = !backprogectMode;
                break;
            case 'c'://清零跟蹤目標(biāo)對(duì)象
                trackObject = 0;
                histimg = Scalar::all(0);
                break;
            case 'h'://顯示直方圖交替
                showHist = !showHist;
                if (!showHist)
                    destroyWindow("Histogram");
                else
                    namedWindow("Histogram", 1);
                break;
            case 'p'://暫停跟蹤交替
                paused = !paused;
                break;
            default:
                ;
            }

        }
    }
int main(){
    //Mat src=imread("D:/test/sh.png");
    //inRangeTest(src);

    camshiftTest();

    waitKey(0);


}

在這里插入圖片描述
在這里插入圖片描述

在這里插入圖片描述

學(xué)習(xí)資料

  1. 點(diǎn)滴成海~: 基于顏色特征的目標(biāo)跟蹤

  2. 雷霄驊: Camshift算法原理及其Opencv實(shí)現(xiàn)

    ps:雖然不認(rèn)識(shí)润讥,但是每次看到都想哭,一想到他就會(huì)想起對(duì)我很重要的一個(gè)人盘寡。愿他們?cè)谔焐夏芸炜鞓窐返摹?/p>

  3. qq_35971623: opencv--顏色物體識(shí)別跟蹤

  4. opencv3/C++基于顏色的目標(biāo)跟蹤

  5. a &=b這是什么意思啊?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末楚殿,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子竿痰,更是在濱河造成了極大的恐慌勒魔,老刑警劉巖甫煞,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異冠绢,居然都是意外死亡抚吠,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門弟胀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)楷力,“玉大人,你說我怎么就攤上這事孵户∠舫” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵夏哭,是天一觀的道長(zhǎng)检柬。 經(jīng)常有香客問我,道長(zhǎng)竖配,這世上最難降的妖魔是什么何址? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮进胯,結(jié)果婚禮上用爪,老公的妹妹穿的比我還像新娘。我一直安慰自己胁镐,他們只是感情好偎血,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著盯漂,像睡著了一般颇玷。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上就缆,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天亚隙,我揣著相機(jī)與錄音,去河邊找鬼违崇。 笑死阿弃,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的羞延。 我是一名探鬼主播渣淳,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼伴箩!你這毒婦竟也來(lái)了入愧?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎棺蛛,沒想到半個(gè)月后怔蚌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡旁赊,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年桦踊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片终畅。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡籍胯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出离福,到底是詐尸還是另有隱情杖狼,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布妖爷,位于F島的核電站蝶涩,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏絮识。R本人自食惡果不足惜绿聘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望笋除。 院中可真熱鬧斜友,春花似錦炸裆、人聲如沸垃它。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)国拇。三九已至,卻和暖如春惯殊,著一層夾襖步出監(jiān)牢的瞬間酱吝,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工土思, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留务热,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓己儒,卻偏偏與公主長(zhǎng)得像崎岂,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子闪湾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容