Мне нужно создать маску для извлечения объекта (объекта переднего плана) на основе двух связанных изображений.
Изображение 1:
[! [введите описание изображения здесь]Изображение 2:
[! [введите описание изображения здесь]Изображения содержат объект переднего плана и фон с текстурой.
Два изображения в основном одинаковы, за исключением того, что в image2 объект переднего плана мог немного измениться (его можно было повернуть, перевести или / и масштабировать).
Используя OpenCV, я сделал следующее:
findTransformECC
с параметром cv::MOTION_AFFINE
) получить трансформацию переднего плана;cv::warpAffine
с параметром cv::INTER_LINEAR
+ cv::WARP_INVERSE_MAP
) на основе приведенной выше матрицы преобразования;cv::absdiff
& cv::threshold
с параметром cv::THRESH_BINARY_INV
) между image2 и уже преобразованным image1. Я думаю, что я близок к своей цели, но я все еще не могу получить чистую маску объекта переднего плана из-за оставшихся шумов в области фона.
Каково решение, чтобы удалить все шумы на image_absdiff_invert.png (выше), чтобы создать чистую маску объекта переднего плана?
Я только что попробовал это.
Использование морфологических операций часто немного сложно (методом проб и ошибок) и дает мне такой результат:
Хотя использование медианного фильтра может быть хорошей предварительной обработкой (или, может быть, даже достаточным для извлечения контура), он дает такой результат (это просто медианное размытие на входном изображении, пока нет морфологических операций)
вот тестовый код:
int main(int argc, char* argv[])
{
cv::Mat input = cv::imread("C:/StackOverflow/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:/StackOverflow/Output/maskNoiseMorph.png", mask);
cv::imwrite("C:/StackOverflow/Output/maskNoiseMedian.png", median);
cv::waitKey(0);
return 0;
}
Других решений пока нет …