人脸轮廓筛选

主要筛选准则:人脸面积>400, 轮廓长度>20, 0.5<轮廓长/宽<2.5;具体选择根据实际情况改动。

void findcontours(Mat *src,Mat mask)//mask为检测到的人脸二值图区域,src为源图。
{
    Mat mask1;
    mask.copyTo (mask1);
    Mat mask2 (mask1.size(), CV_8UC1 );
    Mat element1 = getStructuringElement (MORPH_RECT,Size(5,5));
    erode(mask1, mask1,element1, Point(-1,-1), 1);
    imshow ("腐蚀", mask1);
    Mat element2 = getStructuringElement (MORPH_ELLIPSE, Size(5,5));
    dilate (mask1, mask1,element2);
    imshow("膨胀",mask1);
    //imwrite ("mask1.jpg", mask2);
    threshold(mask1, mask2, 0,255,CV_THRESH_BINARY );
    mask2.convertTo (mask2, CV_8UC1 );
    fillHole2(&mask2);//孔洞填充
    imshow ("填充后", mask2);
    //imshow("mask2图像", mask2);
    //轮廓查找
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;
    findContours (mask2, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE );
    //筛选轮廓
    vector<int> label;
    int add_lable = 0;
    vector<Rect> boundRect(contours.size());//定义外接矩形集合
    vector<RotatedRect > box(contours.size()); // 定义最小外接矩形几何
    for (int i =0; i < contours.size(); i++)
    {
        double con_area = contourArea (contours[i]);
        double con_length = arcLength (contours[i], true);
        int x0 =0, y0 =0, w0 =0, h0 =0, w1 = 0, h1 = 0;
        boundRect[i] = boundingRect(contours[i]);
        //box[i] = minAreaRect (contours[i]);
        x0 = boundRect[i].x;
        y0 = boundRect[i].y;
        w0 = boundRect[i].width;
        h0 = boundRect[i].height;
        /*w1 = box[i].size.width ;
        h1 = box[i].size.height;*/
        if (con_area > 400 && w0 > 20 && h0 > 20 && (h0/w0)>0.2 && (h0/w0)<2.5 )
        {
            drawContours (mask2, contours,i, Scalar (255, 0, 0), 1, 8);
            rectangle (*src, Point(x0, y0), Point(x0+w0, y0+h0), Scalar (0, 255, 0), 2, 8);
            putText (*src, "Face", Point(x0+w0/4, y0-5), CV_FONT_HERSHEY_SIMPLEX,0.5,Scalar(0,255,0),1 );
            label.push_back (i);
            add_lable ++;

        }
    }   
}
void fillHole2(Mat *src)//利用漫水填充进行孔洞填充
{

    Mat temp = Mat::zeros((src->size().height ) + 2, (src->size().width)+2, src->type());
    src->copyTo (temp(Range (1,(src->size().height ) + 1),Range (1,(src->size().width)+1)));
    floodFill (temp, Point(0,0),Scalar (255));
    //imshow("floodFill", temp);
    Mat cutImg;//将图像还原为原来大小
    temp(Range (1,(src->size().height ) + 1),Range (1,(src->size().width)+1)).copyTo (cutImg );
    *src = (*src) | (~ cutImg );

}

参考文献
https://blog.csdn.net/mao19931004/article/details/48933435

猜你喜欢

转载自blog.csdn.net/u010623565/article/details/80343381