Я хотел бы реализовать компонент маркировки алгоритма для цветного изображения.
Цветовые расстояния четырех соседей от текущего пикселя в (i, j) вычисляются, и алгоритм работает следующим образом:
Если ни один из соседей не имеет цветового расстояния меньше предварительно определенного порогового значения (T), назначьте новую метку пикселю (i, j).
Если только один из соседей имеет цветовое расстояние меньше, чем T, назначьте его метку пикселю (i, j).
(a) Если два или более соседей имеют цветовое расстояние меньше T, пикселю в точке (i, j) присваивается метка того, который имеет наименьшее цветовое расстояние.
(b) Метка пикселя с наименьшим цветовым расстоянием также присваивается другим соседним пикселям.
(c) Все ранее помеченные пиксели в изображении, которые имеют ту же метку, что и метка других соседних пикселей, переназначаются с меткой пикселя, имеющего наименьшее цветовое расстояние.
Я хочу реализовать код на C ++, используя библиотеку opencv. Какова лучшая структура данных, которую я могу использовать для реализации вышеуказанного алгоритма? Должен ли я использовать std :: map для хранения значений соседних расстояний?
Кроме того, если какое-либо условие удовлетворяет (1-3), мне нужно присвоить метку этого соответствующего пикселя текущему пикселю (i, j). Поэтому мне также нужно знать, какая это метка соседа (то есть слева, сверху, сверху слева по диагонали, сверху справа по диагонали). Как мне это получить?
Хеш-таблица будет хорошо работать для этого варианта использования:
unordered_map<srcpixel,vector<pair<targetpixel,dist> > >
Таким образом, каждый srcpixel будет действовать как ключ в хеш-таблице, а значением будет вектор, содержащий его расстояния от соседей.
Это было бы быстро, O (1) время поиска для каждого srcpixel и затем линейный обход для его соседей.
Чтобы сохранить цветовое расстояние до 4 соседей каждого пикселя, вы должны использовать массив данных на основе массива, т.е. std::vector
обычные C-массивы или, возможно, даже opencv-образы — все, что вам удобнее всего использовать.
Чтобы сохранить значения для пикселей изображения в одномерном массиве, массив обычно индексируется построчно, то есть индекс j * imageWidth + i
используется для адресации пикселя (i, j)
,
Например, используя std::vector
Вы можете сохранить значения расстояния до соседа ниже, как это:
std::vector<uint8_t> colorDistDown(imageWidth * (imageHeight-1));
for(int j = 0; j < imageHeight - 1; ++j) {
for(int i = 0; i < imageWidth; ++i) {
colorDistDown[j * imageWidth + i] = colorDistance(image, i,j, i,j+1);
}
}
С помощью std::map
или же std::unordered_map
будет намного медленнее. Однако использование структуры данных карты может иметь смысл, если вы хотите хранить записи только для небольших (и непрямоугольных) областей вашего изображения.