# How can I sort the matrix acc. to the first column?

I have a Mat. I want to change the order of its rows, based on the value of their first element. So a row that begins with 1 will be placed before a row beginning with 2 etc. If two rows begin with the same number, I want to keep their original order.

Is there a simple way to achieve this ? I would be very grateful if someone help me.

edit retag close merge delete

Sort by » oldest newest most voted

yes, with cv::sortIdx it shouldn't be too difficult and work similar to (I haven't tested it - but you should get the spirit):

//get first column
cv::Mat one = your_mat.col(0);
// sort the first column and save indices in dst
cv::Mat1i idx;
cv::sortIdx(one, idx, cv::SORT_EVERY_COLUMN + cv::SORT_ASCENDING);
// now build your final matrix
cv::Mat result(your_mat.rows, your_mat.cols, your_mat.type());
for(int y = 0; y < your_mat.rows; y++){
your_mat.row(y).copyTo(result.row(idx(0,y)));
}

more

ah, cool. that really works ;)

maybe fix the constants ?

cv::SORT_EVERY_COLUMN + cv::SORT_ASCENDING


CV_ prefix and cv:: namespace are kinda xor

//get first column
cv::Mat one = your_mat.col(0);
// sort the first column and save indices in dst
cv::Mat1i idx;
cv::sortIdx(one, idx, cv::SORT_EVERY_COLUMN + cv::SORT_ASCENDING);
// now build your final matrix
cv::Mat result(your_mat.rows, your_mat.cols, your_mat.type());
for(int y = 0; y < your_mat.rows; y++){
your_mat.row(idx(0,y)).copyTo(result.row(y)); //correction here
}

more

Thanks! This is the right answer.

this corriection dont work for me

The idx should indeed be on the left side, although muglikars answer game me an exception. For me the correct line there was:

your_mat.row(idx(y)).copyTo(result.row(y));


This did sort correctly, the answer of Guanta (the current most upvoted answer) gave me weird sortings.

Official site

GitHub

Wiki

Documentation