cvvecfacetracking.cpp.svn-base

来自「非结构化路识别」· SVN-BASE 代码 · 共 976 行 · 第 1/3 页

SVN-BASE
976
字号
                {
                    cr.r = cvContourBoundingRect(internal);	  
                    Move(cr.r, roi.x, roi.y);
                    if (RectInRect(cr.r, m_rROI) && cr.r.width > dMinSize  && cr.r.height > dMinSize)
                    {
                        cr.ptCenter = Center(cr.r);
                        cr.iColor = colors[i];
                        cvSeqPush(m_seqRects, &cr);
                    }
                }
            }
            cvClearSeq(seq);
        }
    }
    cvResetImageROI(img);
    cvResetImageROI(thresh);
}//void CvFaceElement::FindContours(IplImage* img, IplImage* thresh, int nLayers)

void CvFaceElement::MergeRects(int d)
{
    int nRects = m_seqRects->total;
    CvSeqReader reader, reader2;
    cvStartReadSeq( m_seqRects, &reader );
    int i, j;
    for (i = 0; i < nRects; i++)
    {
        CvTrackingRect* pRect1 = (CvTrackingRect*)(reader.ptr);
        cvStartReadSeq( m_seqRects, &reader2 );
        cvSetSeqReaderPos(&reader2, i + 1);
        for (j = i + 1; j < nRects; j++)
        {
            CvTrackingRect* pRect2 = (CvTrackingRect*)(reader2.ptr);
            if (abs(pRect1->ptCenter.y - pRect2->ptCenter.y) < d && 
                abs(pRect1->r.height - pRect2->r.height) < d)
            {
                CvTrackingRect rNew;
                rNew.iColor = (pRect1->iColor + pRect2->iColor + 1) / 2;
                rNew.r.x = min(pRect1->r.x, pRect2->r.x);
                rNew.r.y = min(pRect1->r.y, pRect2->r.y);
                rNew.r.width = max(pRect1->r.x + pRect1->r.width, pRect2->r.x + pRect2->r.width) - rNew.r.x;
                rNew.r.height = min(pRect1->r.y + pRect1->r.height, pRect2->r.y + pRect2->r.height) - rNew.r.y;
                if (rNew.r != pRect1->r && rNew.r != pRect2->r)
                {
                    rNew.ptCenter = Center(rNew.r);
                    cvSeqPush(m_seqRects, &rNew);
                }
            }
            CV_NEXT_SEQ_ELEM( sizeof(CvTrackingRect), reader2 );
        }
        CV_NEXT_SEQ_ELEM( sizeof(CvTrackingRect), reader );
    }
    // delete equal rects
    for (i = 0; i < m_seqRects->total; i++)
    {
        CvTrackingRect* pRect1 = (CvTrackingRect*)cvGetSeqElem(m_seqRects, i);
        int j_begin = i + 1;
        for (j = j_begin; j < m_seqRects->total;)
        {
            CvTrackingRect* pRect2 = (CvTrackingRect*)cvGetSeqElem(m_seqRects, j);
            if (pRect1->r == pRect2->r)
                cvSeqRemove(m_seqRects, j);
            else
                j++;
        }
    }

}//void CvFaceElement::MergeRects(int d)

void CvFaceElement::Energy()
{
    CvSeqReader reader, reader2;
    cvStartReadSeq( m_seqRects, &reader );
    for (int i = 0; i < m_seqRects->total; i++)
    {
        CvTrackingRect* pRect = (CvTrackingRect*)(reader.ptr);
        // outside and inside rects
        cvStartReadSeq( m_seqRects, &reader2 );
        for (int j = 0; j < m_seqRects->total; j++)
        {
            CvTrackingRect* pRect2 = (CvTrackingRect*)(reader2.ptr);
            if (i != j)
            {
                if (RectInRect(pRect2->r, pRect->r))
                    pRect->nRectsInThis ++;
                else if (pRect2->r.y + pRect2->r.height <= pRect->r.y)
                    pRect->nRectsOnTop ++;
                else if (pRect2->r.y >= pRect->r.y + pRect->r.height)
                    pRect->nRectsOnBottom ++;
                else if (pRect2->r.x + pRect2->r.width <= pRect->r.x)
                    pRect->nRectsOnLeft ++;
                else if (pRect2->r.x >= pRect->r.x + pRect->r.width)
                    pRect->nRectsOnRight ++;
            }
            CV_NEXT_SEQ_ELEM( sizeof(CvTrackingRect), reader2 );
        }
        // energy
        pRect->Energy(m_trPrev);
        CV_NEXT_SEQ_ELEM( sizeof(CvTrackingRect), reader );
    }
}//void CvFaceElement::Energy()

CV_IMPL CvFaceTracker*
cvInitFaceTracker(CvFaceTracker* pFaceTracker, const IplImage* imgGray, CvRect* pRects, int nRects)
{
    _ASSERT(NULL != imgGray);
    _ASSERT(NULL != pRects);
    _ASSERT(nRects >= NUM_FACE_ELEMENTS);
    if ((NULL == imgGray) ||
        (NULL == pRects) ||
        (nRects < NUM_FACE_ELEMENTS))
        return NULL;
    
    int new_face = FALSE;
    CvFaceTracker* pFace = pFaceTracker;
    if (NULL == pFace)
    {
        pFace = new CvFaceTracker;
        if (NULL == pFace)
            return NULL;
        new_face = TRUE;
    }
    pFace->Init(pRects, (IplImage*)imgGray);
    return pFace;
}//CvFaceTracker* InitFaceTracker(IplImage* imgGray, CvRect* pRects, int nRects)

CV_IMPL void
cvReleaseFaceTracker(CvFaceTracker** ppFaceTracker)
{
    if (NULL == *ppFaceTracker)
        return;
    delete *ppFaceTracker;
    *ppFaceTracker = NULL;
}//void ReleaseFaceTracker(CvFaceTracker** ppFaceTracker)


CV_IMPL int
cvTrackFace(CvFaceTracker* pFaceTracker, IplImage* imgGray, CvRect* pRects, int nRects, CvPoint* ptRotate, double* dbAngleRotate)
{
    _ASSERT(NULL != pFaceTracker);
    _ASSERT(NULL != imgGray);
    _ASSERT(NULL != pRects && nRects >= NUM_FACE_ELEMENTS);
    if ((NULL == pFaceTracker) ||
        (NULL == imgGray))
        return FALSE;
    pFaceTracker->InitNextImage(imgGray);
    *ptRotate = pFaceTracker->ptRotate;
    *dbAngleRotate = pFaceTracker->dbRotateAngle;
    
    int nElements = 16;
    double d_eyes = sqrt(pow2(pFaceTracker->face[LEYE].ptCenter.x - pFaceTracker->face[REYE].ptCenter.x) + 
        pow2(pFaceTracker->face[LEYE].ptCenter.y - pFaceTracker->face[REYE].ptCenter.y));
    int d = int(0.25 * d_eyes + 0.5);
    int dMinSize = d;
    int nRestarts = 0;
    
    int elem;
    
    CvFaceElement big_face[NUM_FACE_ELEMENTS];
START:
    // init
    for (elem = 0; elem < NUM_FACE_ELEMENTS; elem++)
    {
        CvRect r = pFaceTracker->face[elem].r;
        Extend(r, d);
        if (r.width < 4*d)
        {
            r.x -= (4*d - r.width) / 2;
            r.width += 4*d - r.width;
        }
        if (r.height < 3*d)
        {
            r.y -= (3*d - r.height) / 2;
            r.height += 3*d - r.height;
        }
        if (r.x < 1)
            r.x = 1;
        if (r.y < 1)
            r.y = 1;
        if (r.x + r.width > pFaceTracker->imgGray->width - 2)
            r.width = pFaceTracker->imgGray->width - 2 - r.x;
        if (r.y + r.height > pFaceTracker->imgGray->height - 2)
            r.height = pFaceTracker->imgGray->height - 2 - r.y;
        if (!big_face[elem].Init(r, pFaceTracker->face[elem], pFaceTracker->mstgContours))
            return FALSE;
    }
    // find contours
    for (elem = 0; elem < NUM_FACE_ELEMENTS; elem++)
        big_face[elem].FindRects(pFaceTracker->imgGray, pFaceTracker->imgThresh, 32, dMinSize);
    // candidats
    CvTrackingRect new_face[NUM_FACE_ELEMENTS];
    int new_energy = 0;
    int found = ChoiceTrackingFace3(pFaceTracker, nElements, big_face, new_face, new_energy);
    int restart = FALSE;
    int find2 = FALSE;
    int noel = -1;
    if (found)
    {
        if (new_energy > 100000 && -1 != pFaceTracker->iTrackingFaceType)
            find2 = TRUE;
        else if (new_energy > 150000)
        {
            int elements = 0;
            for (int el = 0; el < NUM_FACE_ELEMENTS; el++)
            {
                if (big_face[el].m_seqRects->total > 16 || (big_face[el].m_seqRects->total > 8 && new_face[el].iEnergy < 100))
                    elements++;
                else
                    noel = el;
            }
            if (2 == elements)
                find2 = TRUE;
            else 
                restart = TRUE;
        }
    }
    else
    {
        if (-1 != pFaceTracker->iTrackingFaceType)
            find2 = TRUE;
        else
            restart = TRUE;
    }
RESTART:
    if (restart)
    {
        if (nRestarts++ < 2)
        {
            d = d + d/4;
            goto START;
        }
    }
    else if (find2)
    {
        if (-1 != pFaceTracker->iTrackingFaceType)
            noel = pFaceTracker->iTrackingFaceType;
        int found2 = ChoiceTrackingFace2(pFaceTracker, nElements, big_face, new_face, new_energy, noel);
        if (found2 && new_energy < 100000)
        {
            pFaceTracker->iTrackingFaceType = noel;
            found = TRUE;
        }
        else 
        {
            restart = TRUE;
            goto RESTART;
        }
    }
    
    if (found)
    {
        // angle by mouth & eyes
        double vx_prev = double(pFaceTracker->face[LEYE].ptCenter.x + pFaceTracker->face[REYE].ptCenter.x) / 2.0 - pFaceTracker->face[MOUTH].ptCenter.x;
        double vy_prev = double(pFaceTracker->face[LEYE].ptCenter.y + pFaceTracker->face[REYE].ptCenter.y) / 2.0 - pFaceTracker->face[MOUTH].ptCenter.y;
        double vx_prev1 = vx_prev * cos(pFaceTracker->dbRotateDelta) - vy_prev * sin(pFaceTracker->dbRotateDelta);
        double vy_prev1 = vx_prev * sin(pFaceTracker->dbRotateDelta) + vy_prev * cos(pFaceTracker->dbRotateDelta);
        vx_prev = vx_prev1;
        vy_prev = vy_prev1;
        for (elem = 0; elem < NUM_FACE_ELEMENTS; elem++)
            pFaceTracker->face[elem] = new_face[elem];
        double vx = double(pFaceTracker->face[LEYE].ptCenter.x + pFaceTracker->face[REYE].ptCenter.x) / 2.0 - pFaceTracker->face[MOUTH].ptCenter.x;
        double vy = double(pFaceTracker->face[LEYE].ptCenter.y + pFaceTracker->face[REYE].ptCenter.y) / 2.0 - pFaceTracker->face[MOUTH].ptCenter.y;
        pFaceTracker->dbRotateDelta = 0;
        double n1_n2 = (vx * vx + vy * vy) * (vx_prev * vx_prev + vy_prev * vy_prev);
        if (n1_n2 != 0)
            pFaceTracker->dbRotateDelta = asin((vx * vy_prev - vx_prev * vy) / sqrt(n1_n2));
        pFaceTracker->dbRotateAngle -= pFaceTracker->dbRotateDelta;
    }
    else
    {
        pFaceTracker->dbRotateDelta = 0;
        pFaceTracker->dbRotateAngle = 0;
    }
    if ((pFaceTracker->dbRotateAngle >= pi/2 && pFaceTracker->dbRotateAngle > 0) ||
        (pFaceTracker->dbRotateAngle <= -pi/2 && pFaceTracker->dbRotateAngle < 0))
    {
        pFaceTracker->dbRotateDelta = 0;
        pFaceTracker->dbRotateAngle = 0;
        found = FALSE;
    }
    if (found)
    {
        for (int i = 0; i < NUM_FACE_ELEMENTS && i < nRects; i++)
            pRects[i] = pFaceTracker->face[i].r;
    }
    return found;
}//int FindFaceTracker(CvFaceTracker* pFaceTracker, IplImage* imgGray, CvRect* pRects, int nRects, CvPoint& ptRotate, double& dbAngleRotate)

void ThresholdingParam(IplImage *imgGray, int iNumLayers, int &iMinLevel, int &iMaxLevel, float &step, float& power, int iHistMin /*= HIST_MIN*/)
{
    _ASSERT(imgGray != NULL);
    _ASSERT(imgGray->nChannels == 1);
    int i, j; 
    // create histogram
    int histImg[256] = {0};
    uchar* buffImg = (uchar*)imgGray->imageData;
    CvRect rROI = cvGetImageROI(imgGray);
    buffImg += rROI.y * imgGray->widthStep + rROI.x;
    for (j = 0; j < rROI.height; j++)
    {
        for (i = 0; i < rROI.width; i++)
            histImg[buffImg[i]] ++;
        buffImg += imgGray->widthStep;
    }
    // params
    for (i = 0; i < 256; i++)
    {
        if (histImg[i] > iHistMin)
            break;
    }
    iMinLevel = i;
    for (i = 255; i >= 0; i--)
    {
        if (histImg[i] > iHistMin)
            break;
    }
    iMaxLevel = i;
    if (iMaxLevel <= iMinLevel)
    {
        iMaxLevel = 255;
        iMinLevel = 0;
    }
    // power
    double black = 1;
    double white = 1;
    for (i = iMinLevel; i < (iMinLevel + iMaxLevel) / 2; i++)
        black += histImg[i];

⌨️ 快捷键说明

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