Я использую cv :: ximgproc :: SuperpixelSLIC opencv c ++ для генерации сегментов изображения. Я хочу, чтобы каждый сегмент метки был уникальным. Вот мой код
Mat segmentImage() {
int num_iterations = 4;
int prior = 2;
bool double_step = false;
int num_levels = 10;
int num_histogram_bins = 5;
int width, height;
width = h1.size().width;
height = h1.size().height;
seeds = createSuperpixelSLIC(h1);
Mat mask;
seeds->iterate(num_iterations);
Mat labels;
seeds->getLabels(labels);
for (int i = 0; i < labels.rows; i++) {
for (int j = 0; j < labels.cols; j++) {
if (labels.at<int>(i, j) == 0)
cout << i << " " << j << " " << labels.at<int>(i, j) << endl;
}
}
ofstream myfile;
myfile.open("label.txt");
myfile << labels;
myfile.close();
seeds->getLabelContourMask(mask, false);
h1.setTo(Scalar(0, 0, 255), mask);
imshow("result", h1);
imwrite("result.png", h1);
return labels;
}
В label.txt Я заметил, что метка 0 была присвоена двум сегментам (то есть сегмент включает пиксель (0,0) и пиксель (692,442). Эти два сегмента довольно далеко.
Это нормальная вещь или мой код неверен. Пожалуйста, помогите мне найти уникальный ярлык для каждого сегмента.
По сути, вам нужен алгоритм связанных компонентов. Не зная точной реализации SLIC, которую вы используете, SLIC обычно имеет тенденцию создавать отключенные суперпиксели, то есть отключенные сегменты с одинаковой меткой. Простое решение, которое я использовал, это форма алгоритма связанных компонентов: https://github.com/davidstutz/matlab-multi-label-connected-components (изначально отсюда: http://xenia.media.mit.edu/~rahimi/connected/). Обратите внимание, что этот репозиторий содержит оболочку MatLab. В вашем случае вам нужно только connected_components.h
вместе со следующим кодом:
#include "connected_components.h"// ...
void relabelSuperpixels(cv::Mat &labels) {
int max_label = 0;
for (int i = 0; i < labels.rows; i++) {
for (int j = 0; j < labels.cols; j++) {
if (labels.at<int>(i, j) > max_label) {
max_label = labels.at<int>(i, j);
}
}
}
int current_label = 0;
std::vector<int> label_correspondence(max_label + 1, -1);
for (int i = 0; i < labels.rows; i++) {
for (int j = 0; j < labels.cols; j++) {
int label = labels.at<int>(i, j);
if (label_correspondence[label] < 0) {
label_correspondence[label] = current_label++;
}
labels.at<int>(i, j) = label_correspondence[label];
}
}
}
int relabelConnectedSuperpixels(cv::Mat &labels) {
relabelSuperpixels(labels);
int max = 0;
for (int i = 0; i < labels.rows; ++i) {
for (int j = 0; j < labels.cols; ++j) {
if (labels.at<int>(i, j) > max) {
max = labels.at<int>(i, j);
}
}
}
ConnectedComponents cc(2*max);
cv::Mat components(labels.rows, labels.cols, CV_32SC1, cv::Scalar(0));
int component_count = cc.connected<int, int, std::equal_to<int>, bool>((int*) labels.data, (int*) components.data, labels.cols,
labels.rows, std::equal_to<int>(), false);
for (int i = 0; i < labels.rows; i++) {
for (int j = 0; j < labels.cols; j++) {
labels.at<int>(i, j) = components.at<int>(i, j);
}
}
// component_count would be the NEXT label index, max is the current highest!
return component_count - max - 1;
}
На полученных ярлыках запустите relabelConnectedSuperpixels
,
Других решений пока нет …