⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 blobtrackingmsfg.cpp

📁 Using open CV draw color histogram, convert RGB To HSI
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                        Intel License Agreement
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of Intel Corporation may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#include "_cvaux.h"

// Uncomment to trade flexibility for speed
//#define CONST_HIST_SIZE

// Uncomment to get some performance stats in stderr
//#define REPORT_TICKS

#ifdef CONST_HIST_SIZE
#define m_BinBit 5
#define m_ByteShift 3
#endif

typedef float DefHistType;
#define DefHistTypeMat CV_32F
#define HIST_INDEX(_pData) (((_pData)[0]>>m_ByteShift) + (((_pData)[1]>>(m_ByteShift))<<m_BinBit)+((pImgData[2]>>m_ByteShift)<<(m_BinBit*2)))

class DefHist
{
public:
    CvMat*          m_pHist;
    DefHistType     m_HistVolume;
    DefHist(int BinNum=0)
    {
        m_pHist = NULL;
        m_HistVolume = 0;
        Resize(BinNum);
    }
    ~DefHist()
    {
        if(m_pHist)cvReleaseMat(&m_pHist);
    }
    void Resize(int BinNum)
    {
        if(m_pHist)cvReleaseMat(&m_pHist);
        if(BinNum>0)
        {
            m_pHist = cvCreateMat(1, BinNum, DefHistTypeMat);
            cvZero(m_pHist);
        }
        m_HistVolume = 0;
    }
    void Update(DefHist* pH, float W)
    {/* update hist */
        double  Vol, WM, WC;
        Vol = 0.5*(m_HistVolume + pH->m_HistVolume);
        WM = Vol*(1-W)/m_HistVolume;
        WC = Vol*(W)/pH->m_HistVolume;
        cvAddWeighted(m_pHist, WM, pH->m_pHist,WC,0,m_pHist);
        m_HistVolume = (float)cvSum(m_pHist).val[0];
    }/* update hist */
};

class CvBlobTrackerOneMSFG:public CvBlobTrackerOne
{
protected:
    int             m_BinNumTotal; /* protected only for parralel MSPF */
    CvSize          m_ObjSize;
    void ReAllocKernel(int  w, int h)
    {
        int     x,y;
        float   x0 = 0.5f*(w-1);
        float   y0 = 0.5f*(h-1);
        assert(w>0);
        assert(h>0);
        m_ObjSize = cvSize(w,h);

        if(m_KernelHist) cvReleaseMat(&m_KernelHist);
        if(m_KernelMeanShift) cvReleaseMat(&m_KernelMeanShift);
        m_KernelHist = cvCreateMat(h, w, DefHistTypeMat);
        m_KernelMeanShift = cvCreateMat(h, w, DefHistTypeMat);
        for(y=0;y<h;++y)for(x=0;x<w;++x)
        {
            double r2 = ((x-x0)*(x-x0)/(x0*x0)+(y-y0)*(y-y0)/(y0*y0));
//            double r2 = ((x-x0)*(x-x0)+(y-y0)*(y-y0))/((y0*y0)+(x0*x0));
            CV_MAT_ELEM(m_KernelHist[0],DefHistType, y, x) = (DefHistType)GetKernelHist(r2);
            CV_MAT_ELEM(m_KernelMeanShift[0],DefHistType, y, x) = (DefHistType)GetKernelMeanShift(r2);
        }
    }
private:
    /* parameters */
    int             m_IterNum;
    float           m_FGWeight;
    float           m_Alpha;
    CvMat*          m_KernelHist;
    CvMat*          m_KernelMeanShift;
#ifndef CONST_HIST_SIZE
    int             m_BinBit;
    int             m_ByteShift;
#endif
    int             m_BinNum;
    int             m_Dim;
    /*
    CvMat*          m_HistModel;
    float           m_HistModelVolume;
    CvMat*          m_HistCandidate;
    float           m_HistCandidateVolume;
    CvMat*          m_HistTemp;
    */
    DefHist         m_HistModel;
    DefHist         m_HistCandidate;
    DefHist         m_HistTemp;

    CvBlob          m_Blob;
    int             m_Collision;

    void ReAllocHist(int Dim, int BinBit)
    {
#ifndef CONST_HIST_SIZE
        m_BinBit = BinBit;
        m_ByteShift = 8-BinBit;
#endif
        m_Dim = Dim;
        m_BinNum = (1<<BinBit);
        m_BinNumTotal = cvRound(pow((double)m_BinNum,(double)m_Dim));
        /*
        if(m_HistModel) cvReleaseMat(&m_HistModel);
        if(m_HistCandidate) cvReleaseMat(&m_HistCandidate);
        if(m_HistTemp) cvReleaseMat(&m_HistTemp);
        m_HistCandidate = cvCreateMat(1, m_BinNumTotal, DefHistTypeMat);
        m_HistModel = cvCreateMat(1, m_BinNumTotal, DefHistTypeMat);
        m_HistTemp = cvCreateMat(1, m_BinNumTotal, DefHistTypeMat);
        cvZero(m_HistCandidate);
        cvZero(m_HistModel);
        m_HistModelVolume = 0.0f;
        m_HistCandidateVolume = 0.0f;
        */
        m_HistCandidate.Resize(m_BinNumTotal);
        m_HistModel.Resize(m_BinNumTotal);
        m_HistTemp.Resize(m_BinNumTotal);
    }
    double GetKernelHist(double r2)
    {
        return (r2 < 1) ? 1 -  r2 : 0;
    }
    double GetKernelMeanShift(double r2)
    {
        return (r2<1) ? 1 : 0;
    }
//    void CollectHist(IplImage* pImg, IplImage* pMask, CvPoint Center, CvMat* pHist, DefHistType* pHistVolume)
//    void CollectHist(IplImage* pImg, IplImage* pMask, CvPoint Center, DefHist* pHist)
    void CollectHist(IplImage* pImg, IplImage* pMask, CvBlob* pBlob, DefHist* pHist)
    {
        int UsePrecalculatedKernel = 0;
        int BW = cvRound(pBlob->w);
        int BH = cvRound(pBlob->h);
        DefHistType Volume = 0;
        int         x0 = cvRound(pBlob->x - BW*0.5);
        int         y0 = cvRound(pBlob->y - BH*0.5);
        int         x,y;

        UsePrecalculatedKernel = (BW == m_ObjSize.width && BH == m_ObjSize.height ) ;

        //cvZero(pHist);
        cvSet(pHist->m_pHist,cvScalar(1.0/m_BinNumTotal)); /* no zero bins, all bins have very small value*/
        Volume = 1;

        assert(BW < pImg->width);
        assert(BH < pImg->height);
        if((x0+BW)>=pImg->width) BW=pImg->width-x0-1;
        if((y0+BH)>=pImg->height) BH=pImg->height-y0-1;
        if(x0<0){ x0=0;}
        if(y0<0){ y0=0;}

        if(m_Dim == 3)
        {
            for(y=0;y<BH;++y)
            {
                unsigned char* pImgData = &CV_IMAGE_ELEM(pImg,unsigned char,y+y0,x0*3);
                unsigned char* pMaskData = pMask?(&CV_IMAGE_ELEM(pMask,unsigned char,y+y0,x0)):NULL;
                DefHistType* pKernelData = NULL;
                if(UsePrecalculatedKernel)
                {
                    pKernelData = ((DefHistType*)CV_MAT_ELEM_PTR_FAST(m_KernelHist[0],y,0,sizeof(DefHistType)));
                }
                for(x=0;x<BW;++x,pImgData+=3)
                {
                    DefHistType K;
                    int index = HIST_INDEX(pImgData);
                    assert(index >= 0 && index < pHist->m_pHist->cols);
                    if(UsePrecalculatedKernel)
                    {
                        K = pKernelData[x];
                    }
                    else
                    {
                        float dx = (x+x0-pBlob->x)/(pBlob->w*0.5f);
                        float dy = (y+y0-pBlob->y)/(pBlob->h*0.5f);
                        double r2 = dx*dx+dy*dy;
                        K = (float)GetKernelHist(r2);
                    }

                    if(pMaskData)
                    {
                        K *= pMaskData[x]*0.003921568627450980392156862745098f;
                    }
                    Volume += K;
                    ((DefHistType*)(pHist->m_pHist->data.ptr))[index] += K;
                }/* next column */
            }/* next row */
        }/* if m_Dim == 3 */
        pHist->m_HistVolume = Volume;
    };/*CollectHist*/
    double calcBhattacharyya(DefHist* pHM = NULL, DefHist* pHC = NULL, DefHist* pHT = NULL)
    {
        if(pHM==NULL) pHM = &m_HistModel;
        if(pHC==NULL) pHC = &m_HistCandidate;
        if(pHT==NULL) pHT = &m_HistTemp;
        if(pHC->m_HistVolume*pHM->m_HistVolume > 0)
        {
#if 0
            // use CV functions
            cvMul(pHM->m_pHist,pHC->m_pHist,pHT->m_pHist);
            cvPow(pHT->m_pHist,pHT->m_pHist,0.5);
            return cvSum(pHT->m_pHist).val[0] / sqrt(pHC->m_HistVolume*pHM->m_HistVolume);
#else
            // Do computations manually and let autovectorizer do the job
            DefHistType *hm, *hc, *ht;
            double sum;
            int     size;
            hm=(DefHistType *)(pHM->m_pHist->data.ptr);
            hc=(DefHistType *)(pHC->m_pHist->data.ptr);
            ht=(DefHistType *)(pHT->m_pHist->data.ptr);
            size = pHM->m_pHist->width*pHM->m_pHist->height;
            sum = 0.;
            for(int i = 0; i < size; i++ )
            {
                sum += sqrt(hm[i]*hc[i]);
            }
            return sum / sqrt(pHC->m_HistVolume*pHM->m_HistVolume);
#endif
        }
        return 0;
    } /* calcBhattacharyyaCoefficient */
protected:
    //double GetBhattacharyya(IplImage* pImg, IplImage* pImgFG, float x, float y, DefHist* pHist=NULL)
    double GetBhattacharyya(IplImage* pImg, IplImage* pImgFG, CvBlob* pBlob, DefHist* pHist=NULL, int /*thread_number*/ = 0)
    {
        if(pHist==NULL)pHist = &m_HistTemp;
        CollectHist(pImg, pImgFG, pBlob, pHist);
        return calcBhattacharyya(&m_HistModel, pHist, pHist);
    }
    void UpdateModelHist(IplImage* pImg, IplImage* pImgFG, CvBlob* pBlob)
    {
        if(m_Alpha>0 && !m_Collision)
        {/* update hist */
            CollectHist(pImg, pImgFG, pBlob, &m_HistCandidate);
            m_HistModel.Update(&m_HistCandidate, m_Alpha);
        }/* update hist */
    }/* UpdateModelHist*/

public:
    CvBlobTrackerOneMSFG()
    {

        /* add several parameters for external use */
        m_FGWeight = 2;
        AddParam("FGWeight", &m_FGWeight);
        CommentParam("FGWeight","Weight of FG mask using (0 - mask will not be used for tracking)");

        m_Alpha = 0.01f;
        AddParam("Alpha", &m_Alpha);
        CommentParam("Alpha","Coefficient for model histogramm updating (0 - hist is not upated)");

        m_IterNum = 10;
        AddParam("IterNum", &m_IterNum);
        CommentParam("IterNum","Maximal number of iteration in meanshift operation");

        /* init internal data */
        m_Collision = 0;
//        m_BinBit=0;
        m_Dim = 0;
        /*
        m_HistModel = NULL;
        m_HistCandidate = NULL;
        m_HistTemp = NULL;
        */
        m_KernelHist = NULL;
        m_KernelMeanShift = NULL;
        ReAllocHist(3,5);   /* 3D hist, each dim has 2^5 bins*/
    }
    ~CvBlobTrackerOneMSFG()
    {
        /*
        if(m_HistModel) cvReleaseMat(&m_HistModel);
        if(m_HistCandidate) cvReleaseMat(&m_HistCandidate);
        if(m_HistTemp) cvReleaseMat(&m_HistTemp);
        */
        if(m_KernelHist) cvReleaseMat(&m_KernelHist);
        if(m_KernelMeanShift) cvReleaseMat(&m_KernelMeanShift);
    }
    /* interface */
    virtual void Init(CvBlob* pBlobInit, IplImage* pImg, IplImage* pImgFG = NULL)
    {
        int w = cvRound(CV_BLOB_WX(pBlobInit));
        int h = cvRound(CV_BLOB_WY(pBlobInit));
        if(w<CV_BLOB_MINW)w=CV_BLOB_MINW;
        if(h<CV_BLOB_MINH)h=CV_BLOB_MINH;
        if(pImg)
        {
            if(w>pImg->width)w=pImg->width;
            if(h>pImg->height)h=pImg->height;
        }
        ReAllocKernel(w,h);
        if(pImg)
            CollectHist(pImg, pImgFG, pBlobInit, &m_HistModel);
        m_Blob = pBlobInit[0];
    };
    virtual CvBlob* Process(CvBlob* pBlobPrev, IplImage* pImg, IplImage* pImgFG = NULL)
    {
        int     iter;

        if(pBlobPrev)
        {
            m_Blob = pBlobPrev[0];
        }

        {/* check blob size and realloc kernels if it is necessary */
            int w = cvRound(m_Blob.w);
            int h = cvRound(m_Blob.h);
            if( w != m_ObjSize.width || h!=m_ObjSize.height)
            {
                ReAllocKernel(w,h);
                /* after this ( w != m_ObjSize.width || h!=m_ObjSize.height) shoiuld be false */
            }
        }/* check blob size and realloc kernels if it is necessary */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -