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);
これにより、次のマスクが生成されます。
