# 抠图算法（交互式）以及证件照的自动抠图

1、cv::grabCut(srcImg, mask, retangle, bgModle, fgModle, 5, cv::GC_INIT_WITH_RECT);

srcImg:原图，ratangle:矩形框，bgModle: 与原图大小一致Mat类型，fgModle:与原图大小一致 Mat类型， 5：高斯混合建模迭代次数，cv::GC_INIT_WITH_RECT：标志位。

cv::Mat4b resultMaskToMatrix(int w, int h){
cv::Mat cvMat(h, w, CV_8UC4);
cvMat.setTo(0);

unsigned char *data2 = cvMat.data;
foreCount = 0;
int fgd = 0, bgd = 0, pfgd = 0, pbgd = 0;

for (int y = 0; y < h; y++){
for (int x = 0; x < w; x++){
int index = w * y + x;
int offset = 4 * (w * y + x);
if (data[index] == cv::GC_FGD){
//cvMat.at<cv::Vec4b>(cv::Point(x, y)) == cv::Vec4b(0, 0, 0, 255);
data2[offset] = 255;
data2[offset + 1] = 255;
data2[offset + 2] = 255;
data2[offset + 3] = 255;
fgd++;
}
else if (data[index] == cv::GC_BGD){
//cvMat.at<cv::Vec4b>(cv::Point(x, y)) == cv::Vec4b(255, 255, 255, 255);
data2[offset] = 0;
data2[offset + 1] = 0;
data2[offset + 2] = 0;
data2[offset + 3] = 255;
bgd++;
}
else if (data[index] == cv::GC_PR_FGD){
//cvMat.at<cv::Vec4b>(cv::Point(x, y)) == cv::Vec4b(0,  0,  0,  255);
data2[offset] = 255;
data2[offset + 1] = 255;
data2[offset + 2] = 255;
data2[offset + 3] = 255;
pfgd++;
}
else if (data[index] == cv::GC_PR_BGD){
//cvMat.at<cv::Vec4b>(cv::Point(x, y)) == cv::Vec4b(255, 255, 255, 255);
data2[offset] = 0;
data2[offset + 1] = 0;
data2[offset + 2] = 0;
data2[offset + 3] = 255;
pbgd++;
}
}
}
foreCount = pfgd;
printf("fgd = %d, bgd = %d, pfgd = %d, pbgd = %d, total = %d, width * height = %d\n", fgd, bgd, pfgd, pbgd, fgd + bgd + pfgd + pbgd, w*h);
printf("foreCount = %d\n", foreCount);
return cvMat;
}

cv::Mat1b regularMask(cv::Mat maskImg){

unsigned char *data = makers.data;
int countFGD = 0, countBGD = 0, countRem = 0;

for (int y = 0; y < maskImg.rows; y++){
for (int x = 0; x < maskImg.cols; x++){
int offset = 4 * (maskImg.cols* y + x);
int red = tempdata[offset];
int green = tempdata[offset + 1];
int blue = tempdata[offset + 2];
if (red == 255 && green == 255 && blue == 255){
data[y * maskImg.cols + x] = cv::GC_FGD;
countFGD++;
}
else if (red == 0 && green == 0 && blue == 0){
data[y * maskImg.cols + x] = cv::GC_BGD;
countBGD++;
}
else{
countRem++;
}
}
}
foreCount = countFGD + foreCount;
printf("countFGD = %d, countBGD = %d, countRem = %d,width * height = %d", countFGD, countBGD, countRem, maskImg.cols*maskImg.rows);
printf("foreCount = %d", foreCount);
return makers;
}

1.原图

1、原图                                                                            2、自动抠像效果图

3、背景替换效果图