Как уменьшить шум на изображении, оценив процент равных соседних пикселей - Java OpenCV - PullRequest
0 голосов
/ 28 августа 2018

Я использую библиотеку openCV (v3.4.2), и я планировал преобразовать изображения RGB в HSV, а затем отфильтровать их по цвету, отрегулировав значения оттенков, чтобы получить черно-белые изображения (регулировка насыщенности и значения / яркости не будет дайте мне гораздо лучшие результаты), который уже работает в теории. Тем не менее, некоторые из моих изображений имеют много шума, как вы можете видеть в разделе изображения, которое показано ниже (изображение 1).

Теперь я хотел бы заполнить плотные черные пятна (убрать несколько белых пикселей внутри них) и удалить редкие черные пиксели, которые в основном окружены белыми пикселями, чтобы получить нечто похожее на то, что показано ниже на рисунке 2.

Я бы не сказал, что это гауссовский шум, поскольку на изображениях есть довольно «чистые» пятна. Я уже рассмотрел этот пост: Удалите паразитные маленькие островки шума на изображении - Python OpenCV . Я позаимствовал несколько строк и адаптировал их под свои цели так:

// cloV and opV are JSliders so that I can try different values
Mat se1 = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(cloV,cloV));
Mat se2 = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(opV,opV));

Mat mask = new Mat();

// bwMat is my Mat containing the black&white image
Imgproc.morphologyEx(bwMat, mask, Imgproc.MORPH_CLOSE, se1);
Imgproc.morphologyEx(mask, mask, Imgproc.MORPH_OPEN, se2);
bwMat.setTo(new Scalar(0), mask);

Пытаясь использовать этот подход и играя с параметрами, я не могу получить приличных результатов (хотя мне удается превратить в основном все внутри изображений в черный цвет). Я предполагаю, что это потому, что каждый соседний пиксель взят во внимание, и почти всегда есть по крайней мере несколько пикселей в непосредственной близости. Теперь я подумал, что, возможно, существует метод, который воздействует на пиксели, только если в его окрестности есть определенный процент (например, определенный радиус), но я не знаю, что искать. Это правильный подход? Или это даже реалистично, о чем я думаю?

(1) Оригинальное черно-белое изображение:

[! [Originalopenc picture] [2]] [2]

(2) Черно-белое изображение, которое я хотел бы получить:

[! [Отредактированное изображение] [3]] [3]

Примечание: я создал 2-е изображение с помощью Paint. Я только хотел показать, что я пытаюсь сохранить более плотные черные области (я, возможно, даже удалил некоторые на этом изображении случайно), так что это не должно выглядеть точно так, но я благодарен за любой намек, который приближает меня к этому.

Редактировать: Кто-то сказал мне, чтобы посмотреть шум соли и перца, и тогда я наткнулся на метод медианблюра, который уже довольно эффективен:

Imgproc.medianBlur(Mat src, Mat dst, int ksize);

Я оставляю этот вопрос открытым на некоторое время на случай, если появятся другие предложения. Редактировать 2: Изображения удалены

1 Ответ

0 голосов
/ 29 августа 2018

Это код, который я пробовал.

Я думаю, что найти контуры и удалить маленькие капли после того, как этот код сработает, будет результат, который вы ожидали.

Mat image = Imgcodecs.imread(templImage, Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);
Imgproc.GaussianBlur(image, image, new Size(3,3), 0);

Mat thre = new Mat();
Imgproc.threshold(image, thre, 80, 255, Imgproc.THRESH_BINARY);

Mat eroded = new Mat();
Imgproc.erode(thre, eroded, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(2,2)));
Imgproc.dilate(eroded, eroded, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(2,2)));

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...