This question is not the duplicate of this question
I want to sort the whole Mat image
and store the indices similar to the MatLab's [B , Ix] = sort(A);
But in openCV, the sort() and sortIdx() only works for EACH_ROW
or EACH_COLUMN
.
Problem: So, how can i sort the whole Mat
and store the Indices
also in openCV?
PS: I want to get the following:
INPUT =
2 0
4 1
dst_index =
1 1
2 2
dst_sorted =
0 1
2 4
There are a solution but it works only if the image is continuous in memory. This is usually the case unless your image is only a ROI of bigger image. You can check that by using function isContinuous . The trick is to create Mat that uses the same memory buffer as your original image but instead of treating it as N rows and M columns, it treat it as 1 row and M*N columns. This can be done by reshape function.
Mat sameMemoryNewShape = image.reshape(1, 1);
Now you can use sort() or sortIdx() on sameMemoryNewShape.
Based on the solution of 'Michael Burdinov' the following should work.
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;
}
Note that the result B
is in CV_32SC1 (32bit integer). Not considering that may lead to "strange" behaviour and could result in 1 0 0 0
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.