Удаление шума для создания маски в OpenCV
Мне нужно создать маску для извлечения объекта (объекта переднего плана) на основе двух связанных изображений.
Изображение 1:
[! [введите описание изображения здесь]
Изображение 2:
[! [введите описание изображения здесь]
Изображения содержат объект переднего плана и фон с текстурой. Два изображения в основном одинаковы, за исключением того, что в image2 объект переднего плана мог немного измениться (его можно было повернуть, перевести или / и масштабировать).
Используя OpenCV, я сделал следующее:
- выполнить выравнивание изображения (используя
findTransformECC
с параметромcv::MOTION_AFFINE
) получить трансформацию переднего плана; - сделать преобразование в изображение1 (используя
cv::warpAffine
с параметромcv::INTER_LINEAR
+cv::WARP_INVERSE_MAP
) на основе приведенной выше матрицы преобразования; - сделать абсолютную разницу (
cv::absdiff
&cv::threshold
с параметромcv::THRESH_BINARY_INV
) между image2 и уже преобразованным image1.
Я думаю, что я близок к своей цели, но я все еще не могу получить чистую маску объекта переднего плана из-за оставшихся шумов в области фона.
Какое решение удалить весь шум в image_absdiff_invert.png (выше), чтобы создать чистую маску объекта переднего плана?
1 ответ
Я только что попробовал это.
Использование морфологических операций часто немного сложно (методом проб и ошибок) и дает мне такой результат:
Хотя использование медианного фильтра может быть хорошей предварительной обработкой (или, может быть, даже достаточным для извлечения контура), он дает такой результат (это всего лишь медианное размытие на входном изображении, пока нет морфологических операций):
вот тестовый код:
int main(int argc, char* argv[])
{
cv::Mat input = cv::imread("C:/Stackru/Input/maskNoise.png", CV_LOAD_IMAGE_GRAYSCALE);
cv::Mat mask = input.clone();
cv::dilate(mask, mask, cv::Mat());
cv::dilate(mask, mask, cv::Mat());
cv::erode(mask, mask, cv::Mat());
cv::erode(mask, mask, cv::Mat());
cv::erode(mask, mask, cv::Mat());
cv::erode(mask, mask, cv::Mat());
//cv::erode(mask, mask, cv::Mat());
//cv::erode(mask, mask, cv::Mat());
//cv::dilate(mask, mask, cv::Mat());
//cv::dilate(mask, mask, cv::Mat());
cv::dilate(mask, mask, cv::Mat());
cv::dilate(mask, mask, cv::Mat());
cv::Mat median;
cv::medianBlur(input, median, 7);
cv::Mat resizedIn;
cv::Mat resizedMask;
cv::Mat resizedMedian;
cv::resize(mask, resizedMask, cv::Size(), 0.5, 0.5);
cv::resize(median, resizedMedian, cv::Size(), 0.5, 0.5);
cv::resize(input, resizedIn, cv::Size(), 0.5, 0.5);
cv::imshow("input", resizedIn);
cv::imshow("mask", resizedMask);
cv::imshow("median", resizedMedian);
cv::imwrite("C:/Stackru/Output/maskNoiseMorph.png", mask);
cv::imwrite("C:/Stackru/Output/maskNoiseMedian.png", median);
cv::waitKey(0);
return 0;
}