Я не знаю, пытались ли вы это сделать, но обычно вы можете добиться лучших результатов, обработав сначала изображение.
1) Примените GuassianBlur , чтобы удалить шум
2) Применить AdaptiveThreshold -> для преобразования изображения в черно-белое
3) Применить операцию Расширить , заполнить трещины
Используя различные настройки для AdaptiveThreshold и операции Dlate, вы можете получить замкнутые контуры ...
Пример, который я использовал, выглядит следующим образом:
// 1) Apply gaussian blur to remove noise
Imgproc.GaussianBlur(mGraySubmat, mIntermediateMat, new Size(11,11), 0);
// 2) AdaptiveThreshold -> classify as either black or white
Imgproc.adaptiveThreshold(mIntermediateMat, mIntermediateMat, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY, 5, 2);
// 3) Invert the image -> so most of the image is black
Core.bitwise_not(mIntermediateMat, mIntermediateMat);
// 4) Dilate -> fill the image using the MORPH_DILATE
Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_DILATE, new Size(3,3), new Point(1,1));
Imgproc.dilate(mIntermediateMat, mIntermediateMat, kernel);