Я хотел бы адаптивно настроить порог этого изображения, чтобы найти внешнюю границу, используя findContours()
из OpenCV. Я использую адаптивный порог по обычной причине: глобальное определение порога, даже с помощью метода Оцу, не позволяет адекватно компенсировать различия в яркости между различными частями изображения.
К сожалению, адаптивное установление пороговых значений создает обрывы на некоторых пересечениях с толстыми линиями сетки. Это связано с тем, что для пикселей на пересечении толстые линии сетки занимают такую большую часть окружающей области, что локальный порог поднимается выше (только умеренно темного) значения пикселей на пересечении. Удивительно, но этот эффект до некоторой степени сохраняется даже для больших пороговых окон.
Конечно, это делает адаптивный порог бесполезным для поиска контуров на этих типах изображений. Однако в целом он по-прежнему намного лучше, чем другие алгоритмы, такие как Canny, при создании связанных ребер.
Я смог повторно соединить края после адаптивного определения порога, вручную заполнив все одно- и двухпиксельные промежутки в изображении (на самом деле я пороговую для уменьшенного изображения, чтобы сэкономить время выполнения; промежутки больше в приведенном выше полном размер изображения). Вот код OpenCV, который я использовал (написанный для привязок Android). 0 - черный, -1 - белый.
private void fillGaps(Mat image) {
int size = image.rows() * image.cols();
byte[] src = new byte[size], dst = new byte[size];
image.get(0, 0, src);
int c = image.cols();
int start = 2 * c + 2;
int end = size - start;
for (int i = start; i < end; i++) {
if (src[i+1] == -1 && src[i-1] == -1 || src[i+c] == -1 && src[i-c] ==-1){
// 1-pixel gap
dst[i] = -1;
} else if (src[i+1] == 0 && src[i+2 ] == -1 && src[i-1] == -1) {
// 2-pixel horizontal gap
dst[i] = -1; dst[i+1] = -1;
} else if (src[i+c] == 0 && src[i+2*c] == -1 && src[i-c] == -1) {
// 2-pixel vertical gap
dst[i] = -1; dst[i+c] = -1;
}
}
image.put(0, 0, dst);
}
Вот уменьшенное изображение до и после заполнения пробелов:
Хотя здесь это работает довольно хорошо, это грубая техника, она не заполняет все пробелы и иногда соединяет сетку с другими близлежащими контурами.
Как можно надежно избежать отсоединения контуров после адаптивного порога?