Этот вопрос не дублирует этот вопрос
Я хочу отсортировать Mat image
и сохранить индексы, похожие на MatLab [B, Ix] = sort(A);
Но в openCV, sort() и sortIdx() работают только для EACH_ROW
или EACH_COLUMN
.
Проблема: Итак, как я могу сортировать весь Mat
и хранить Indices
также в openCV?
PS: Я хочу получить следующее:
INPUT =
2 0
4 1
dst_index =
1 1
2 2
dst_sorted =
0 1
2 4
Есть решение, но оно работает, только если изображение непрерывно в памяти. Это обычно так, если ваш образ не является только ROI большего изображения. Вы можете проверить это, используя функцию isContinuous. Хитрость заключается в создании Mat, который использует тот же буфер памяти, что и исходное изображение, но вместо того, чтобы рассматривать его как N строк и столбцов M, он рассматривает его как столбцы с 1 строкой и M * N. Это можно сделать с помощью функции изменения формы.
Mat sameMemoryNewShape = image.reshape(1, 1);
Теперь вы можете использовать sort() или sortIdx() на sameMemoryNewShape.
На основе решения "Майкл Бурдинов" должно работать следующее.
Mat A = (Mat_<uchar>(3, 4) << 0, 5, 2, 5, 2, 4, 9, 12, 3, 12, 11, 1); // example matrix
Mat B; //storing the 1D index result
Mat C = A.reshape(1, 1); //as mentioned by Michael Burdinov
sortIdx(C, B, SORT_EVERY_ROW + SORT_ASCENDING);
for (int i = 0; i < B.cols; i++) //from index 0 to index rows * cols of the original image
{
int val = B.at<int>(0, i); //access B, which is in format CV_32SC1
int y = val / A.cols; //convert 1D index into 2D index
int x = val % A.cols;
std::cout << "idx " << val << " at (x/y) " << x << "/" << y
<< " is " << (int) A.at<uchar>(y, x) << endl;
}
Обратите внимание, что результат B
находится в CV_32SC1 (32-битное целое число). Не считая этого, это может привести к "странному" поведению и может привести к 1 0 0 0
.
1 0 0 0
... как?