看看 OpenCV 的inRange函数。这将允许您同时为 3 通道图像设置多个阈值。
因此,要创建您正在寻找的面具,请执行以下操作:
inRange(diff, Scalar(30, 30, 30), Scalar(255, 255, 255), mask);
这也应该比尝试自己访问每个像素更快。
编辑:如果您要进行皮肤检测,我会先进行皮肤检测,然后再进行背景减法以去除背景。否则,您的皮肤检测器将不得不考虑由减法引起的强度偏移。
查看我的其他答案,关于皮肤检测的好技术。
编辑 :
这是不是更快?
int main(int argc, char* argv[])
{
Mat fg = imread("fg.jpg");
Mat bg = imread("bg.jpg");
cvtColor(fg, fg, CV_RGB2YCrCb);
cvtColor(bg, bg, CV_RGB2YCrCb);
Mat distance = Mat::zeros(fg.size(), CV_32F);
vector<Mat> fgChannels;
split(fg, fgChannels);
vector<Mat> bgChannels;
split(bg, bgChannels);
for(size_t i = 0; i < fgChannels.size(); i++)
{
Mat temp = abs(fgChannels[i] - bgChannels[i]);
temp.convertTo(temp, CV_32F);
distance = distance + temp;
}
Mat mask;
threshold(distance, mask, 35, 255, THRESH_BINARY);
Mat kernel5x5 = getStructuringElement(MORPH_RECT, Size(5, 5));
morphologyEx(mask, mask, MORPH_OPEN, kernel5x5);
imshow("fg", fg);
imshow("bg", bg);
imshow("mask", mask);
waitKey();
return 0;
}
此代码根据您的输入图像生成此掩码:
最后,这是我使用简单的阈值方法得到的结果:
Mat diff = fgYcc - bgYcc;
vector<Mat> diffChannels;
split(diff, diffChannels);
// only operating on luminance for background subtraction...
threshold(diffChannels[0], bgfgMask, 1, 255.0, THRESH_BINARY_INV);
Mat kernel5x5 = getStructuringElement(MORPH_RECT, Size(5, 5));
morphologyEx(bgfgMask, bgfgMask, MORPH_OPEN, kernel5x5);
这会产生以下掩码: