Это насколько я могу получить:
Вы, вероятно, знаете о функции medianBlur
, которая находит медианное значение в каждом ядре и подставляет это значение в центр ядра. Мы можем сделать что-то похожее на это, но вместо медианы используйте значение max, а затем значение min. Со средним пятном я тоже получил некоторые результаты. Я знаю, что они не идеальны, но я надеюсь, что это даст вам некоторые идеи (вы можете поиграть с размерами входного изображения и ядрами, это может немного улучшить результаты).
У меня не установлено python прямо сейчас, поэтому я делюсь точным кодом C ++, который я использовал:
Mat im1 = imread("E:/1/3.jpg", 0);
Mat im2, im3;
im2 = Mat::zeros(im1.size(), CV_8U);
for (size_t i = 1; i < im1.rows-1; i++)
{
for (size_t j = 1; j < im1.cols-1; j++)
{
double minVal, maxVal = 0;
minMaxIdx(im1(Rect(j - 1, i - 1, 3, 3)), &minVal, &maxVal);
im2.at<uchar>(i, j) = maxVal;
}
}
imshow("(1) max bluring", im2);
medianBlur(im2, im2, 3);
imshow("(2) median bluring", im2);
im2.copyTo(im1);
im2 = Mat::zeros(im1.size(), CV_8U);
for (size_t i = 1; i < im1.rows - 1; i++)
{
for (size_t j = 1; j < im1.cols - 1; j++)
{
double minVal, maxVal = 0;
minMaxIdx(im1(Rect(j - 1, i - 1, 3, 3)), &minVal, &maxVal);
im2.at<uchar>(i, j) = minVal;
}
}
imshow("(3) min bluring", im2);
Mat tmp;
double st = threshold(im2, tmp, 10, 255, THRESH_OTSU);
threshold(im2, im2, st + 14, 255, THRESH_BINARY_INV);
//dilate(im2, im2, Mat::ones(3, 3, CV_8U));
imshow("(4) final", im2);
waitKey(0);
Кстати, в таких случаях методы глубокого обучения, такие как YOLO и RCNN, являются лучшими. Попробуйте их тоже.