Ответ 1
Это может быть своего рода взлом, но поскольку это "проект праздника", я все равно отправлю его:)
Вы пытались изолировать фон и затем инвертировать маску (это предполагало бы что-либо, кроме фона, это объект, но он может работать для того, что вы хотите).
Ниже приведен результат использования функции OpenCV inRange:
Возможно, вам захочется сгладить изображение (предварительный процесс) с помощью GuassianBlur, чтобы избавиться от некоторой нерезкости. Я использовал большее ядро дилатации, чем ядро эрозии (5x5 против 3x3), чтобы избавиться от некоторых шумных пикселей. Сглаживание может помочь в этом, а также настройка порогов может сделать ненужным эрозию. Но, это должно заставить вас начать.
Наконец, вот мой быстрый небольшой фрагмент кода, который я использовал для поиска этого диапазона:
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <vector>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
Mat src = imread("test.jpg");
int rh = 255, rl = 100, gh = 255, gl = 0, bh = 70, bl = 0;
string windowName = "background";
namedWindow(windowName);
createTrackbar("rh", windowName, &rh, 255);
createTrackbar("rl", windowName, &rl, 255);
createTrackbar("gh", windowName, &gh, 255);
createTrackbar("gl", windowName, &gl, 255);
createTrackbar("bh", windowName, &bh, 255);
createTrackbar("bl", windowName, &bl, 255);
// for dilation
Mat element = getStructuringElement(MORPH_RECT, Size(5, 5));
Mat bgIsolation;
int key = 0;
do
{
inRange(src, Scalar(bl, gl, rl), Scalar(bh, gh, rh), bgIsolation);
bitwise_not(bgIsolation, bgIsolation);
erode(bgIsolation, bgIsolation, Mat());
dilate(bgIsolation, bgIsolation, element);
imshow(windowName, bgIsolation);
key = waitKey(33);
} while((char)key != 27);
waitKey();
return 0;
}
Наслаждайтесь праздничным проектом! Выглядит весело:)