void FaceDetection::FindContours(IplImage* imgGray) { ReallocImage(&m_imgThresh, cvGetSize(imgGray), 1); if (NULL == m_imgThresh) return; // int iNumLayers = m_iNumLayers; int iMinLevel = 0, iMaxLevel = 255, iStep = 255 / iNumLayers; ThresholdingParam(imgGray, iNumLayers, iMinLevel, iMaxLevel, iStep); // init cvReleaseMemStorage(&m_mstgContours); m_mstgContours = cvCreateMemStorage(); if (NULL == m_mstgContours) return; memset(m_seqContours, 0, sizeof(CvSeq*) * MAX_LAYERS); cvReleaseMemStorage(&m_mstgRects); m_mstgRects = cvCreateMemStorage(); if (NULL == m_mstgRects) return; m_seqRects = cvCreateSeq(0, sizeof(CvSeq), sizeof(CvContourRect), m_mstgRects); if (NULL == m_seqRects) return; // find contours for (int l = iMinLevel, i = 0; l < iMaxLevel; l += iStep, i++) { cvThreshold(imgGray, m_imgThresh, (double)l, (double)255, CV_THRESH_BINARY); if (cvFindContours(m_imgThresh, m_mstgContours, &m_seqContours[i], sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE)) AddContours2Rect(m_seqContours[i], l, i); } // sort rects cvSeqSort(m_seqRects, CompareContourRect, NULL); }// void FaceDetection::FindContours(IplImage* imgGray)
void CvFaceElement::FindContours(IplImage* img, IplImage* thresh, int nLayers, int dMinSize) { CvSeq* seq; CvRect roi = m_rROI; Extend(roi, 1); cvSetImageROI(img, roi); cvSetImageROI(thresh, roi); // layers int colors[MAX_LAYERS] = {0}; int iMinLevel = 0, iMaxLevel = 255; float step, power; ThresholdingParam(img, nLayers / 2, iMinLevel, iMaxLevel, step, power, 4); int iMinLevelPrev = iMinLevel; int iMaxLevelPrev = iMinLevel; if (m_trPrev.iColor != 0) { iMinLevelPrev = m_trPrev.iColor - nLayers / 2; iMaxLevelPrev = m_trPrev.iColor + nLayers / 2; } if (iMinLevelPrev < iMinLevel) { iMaxLevelPrev += iMinLevel - iMinLevelPrev; iMinLevelPrev = iMinLevel; } if (iMaxLevelPrev > iMaxLevel) { iMinLevelPrev -= iMaxLevelPrev - iMaxLevel; if (iMinLevelPrev < iMinLevel) iMinLevelPrev = iMinLevel; iMaxLevelPrev = iMaxLevel; } int n = nLayers; n -= (iMaxLevelPrev - iMinLevelPrev + 1) / 2; step = float(iMinLevelPrev - iMinLevel + iMaxLevel - iMaxLevelPrev) / float(n); int j = 0; float level; for (level = (float)iMinLevel; level < iMinLevelPrev && j < nLayers; level += step, j++) colors[j] = int(level + 0.5); for (level = (float)iMinLevelPrev; level < iMaxLevelPrev && j < nLayers; level += 2.0, j++) colors[j] = int(level + 0.5); for (level = (float)iMaxLevelPrev; level < iMaxLevel && j < nLayers; level += step, j++) colors[j] = int(level + 0.5); // for (int i = 0; i < nLayers; i++) { cvThreshold(img, thresh, colors[i], 255.0, CV_THRESH_BINARY); if (cvFindContours(thresh, m_mstgRects, &seq, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE)) { CvTrackingRect cr; for (CvSeq* external = seq; external; external = external->h_next) { cr.r = cvContourBoundingRect(external); 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); } for (CvSeq* internal = external->v_next; internal; internal = internal->h_next) { 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)