OpenCV Q&A Forum - RSS feedhttp://answers.opencv.org/questions/OpenCV answersenCopyright <a href="http://www.opencv.org">OpenCV foundation</a>, 2012-2018.Sun, 04 May 2014 10:16:00 -0500How to reorder matrix columns according to sortIdx() result?http://answers.opencv.org/question/12693/how-to-reorder-matrix-columns-according-to-sortidx-result/Hi all.
I have two matrices of the same size (1 x ncols, vectors actually) and I need
- one of them sorted in descending order
- another one reordered according to the first one.
What is the most optimal method to do that?
cv::sortIdx() function gives me correct ordering, but I cannot figure out, how to use it for this task.
Tue, 30 Apr 2013 05:17:38 -0500http://answers.opencv.org/question/12693/how-to-reorder-matrix-columns-according-to-sortidx-result/Answer by Guanta for <p>Hi all.</p>
<p>I have two matrices of the same size (1 x ncols, vectors actually) and I need </p>
<ul>
<li>one of them sorted in descending order</li>
<li>another one reordered according to the first one.</li>
</ul>
<p>What is the most optimal method to do that?</p>
<p>cv::sortIdx() function gives me correct ordering, but I cannot figure out, how to use it for this task.</p>
http://answers.opencv.org/question/12693/how-to-reorder-matrix-columns-according-to-sortidx-result/?answer=12695#post-id-12695Something similar to the following should work:
cv::Mat indices;
cv::sortIdx(matrix1, indices, cv::SORT_EVERY_ROW | cv::SORT_DESCENDING);
// I assume your matrix1 and matrix2 are of same size and of type float
// -> change it to your type
cv::Mat1f matrix1_sorted(1, matrix1.cols);
cv::Mat1f matrix2_sorted(1, matrix1.cols);
for( int i = 0; i < indices.cols; i++) {
matrix1_sorted(0,i) = matrix1(indices.at<int>(0, i));
matrix2_sorted(0,i) = matrix2(indices.at<int>(0, i));
}
// your matrices are now sorted according to matrix1
Please forgive me any errors, I wrote it from scratch without testing it.Tue, 30 Apr 2013 05:49:38 -0500http://answers.opencv.org/question/12693/how-to-reorder-matrix-columns-according-to-sortidx-result/?answer=12695#post-id-12695Answer by Philippe for <p>Hi all.</p>
<p>I have two matrices of the same size (1 x ncols, vectors actually) and I need </p>
<ul>
<li>one of them sorted in descending order</li>
<li>another one reordered according to the first one.</li>
</ul>
<p>What is the most optimal method to do that?</p>
<p>cv::sortIdx() function gives me correct ordering, but I cannot figure out, how to use it for this task.</p>
http://answers.opencv.org/question/12693/how-to-reorder-matrix-columns-according-to-sortidx-result/?answer=32812#post-id-328121 year later, but I have come across a solution that works on 2D arrays.
so instead of 2 vectors, you can make it a Nx2 array, and sort the 2nd column based on the 1st column - no need for index list. Furthermore, if there are duplicates in the 1st column, you can then sort the duplicates based on the 2nd column - e.g.:
[7,15],[7,10],[1,2],[3,4],[7,2] => [1,2],[3,4],[7,2],[7,10],[7,15]
this can even be extended to Nx3 as done in the example below... most of the code is actually the cout to show the results - the code is a single line of qsort, and then the qsort comparison routine (which is the engine).
Made a variation for int by changing the arr definition, and the qsort type - works like a charm...Since I am new to this forum, I am restricted in submitting code.... hope it comes out.
#include <sstream>
#include <string>
#include <iostream>
#include <stdlib.h>
using namespace std;
static int compfloat(const void* p1, const void* p2) {
float* arr1 = (float*)p1;
float* arr2 = (float*)p2;
float diff1 = arr1[0] - arr2[0];
if (diff1) return diff1;
return arr1[1] - arr2[1]; //only compares 2nd column if the 1st is the same - can remove
}
#define arraysize 5
int main()
{ float arr[arraysize][3] = {{5,10,1},{2,2,1}, {1,5,2}, {5,4,3}, {5,20,4}}; //example data
for (int i=0; i<arraysize; i++)
{ for (int j=0;j<3;j++) //3=number of columns... change as required
cout << arr[i][j] << " ";
cout << endl;
}
cout << endl;
qsort(arr, arraysize, 3*sizeof(float), compfloat); //3=number of columns... change as required
for (int i=0; i<arraysize; i++)
{ for (int j=0;j<3;j++) //3=number of columns... change as required
cout << arr[i][j] << " ";
cout << endl;
}
return 0;
}
Sun, 04 May 2014 10:16:00 -0500http://answers.opencv.org/question/12693/how-to-reorder-matrix-columns-according-to-sortidx-result/?answer=32812#post-id-32812