1、检测人脸,可以使用opencv自带的级联分类器或者dlib实现人脸检测
2、放大人脸范围,调整到正常寸照尺寸
3、基于RMGB算法得到人像掩码
4、生成尺寸相同的纯色背景与当前人像进行ALPHA融合即可
alpha融合实现
- void alphaBlend(cv::Mat& fgImg, cv::Mat& roi, cv::Mat& mask)
- {
- for (int i = 0; i < roi.rows; i++)
- {
- for (int j = 0; j < roi.cols; j++)
- {
- auto maskVal = (float)mask.at
(i, j)/255; - for (size_t n = 0; n < 3; n++)
- {
- roi.at
(i, j)[n] = fgImg.at(i, j)[n]*maskVal + roi.at(i, j)[n]*(1-maskVal); - }
- }
- }
- }
如果原图是纯色背景,那么扣取的图片可能存在部分边界色,可以通过一下滤波函数处理一下边界
- void filterBoundary(cv::Mat& roi, cv::Mat& mask)
- {
- cv::Mat kernel = (cv::Mat_<double>(3, 3) << 1, 2, 1,
- 2, 4, 2,
- 1, 2, 1);
- kernel /= 16.0; // 归一化
-
- int sz = 1;
- for (int i = 0; i < roi.rows; i++)
- {
- for (int j = 0; j < roi.cols; j++)
- {
- auto maskVal = (float)mask.at
(i, j); - if (maskVal < 255 && maskVal > 0)
- {
- int left = MAX(j - sz, 0);
- int right = MIN(j + sz, roi.cols - 1);
- int top = MAX(i - sz, 0);
- int bottom = MIN(i + sz, roi.rows - 1);
- auto tmpRoi = roi(cv::Rect(left, top, right - left + 1, bottom - top + 1));
- cv::filter2D(tmpRoi, tmpRoi, -1, kernel);
- }
- }
- }
- }
