我的Android OpenCV项目中有一个2D数组类型Mat
,我需要以与MATLAB sortrows
函数相同的方式对数组进行排序。我发现Core.sort()
函数带有Sort_Every_Row
之类的标记。这似乎是我想要的,但是当我使用这个方法时,我得到的结果与我从MATLAB得到的结果不同。
是否还有其他功能或其他方式进行此类排序?我是否必须从头开始编写方法?
下面是我用来排序我的数组FeatureMatirx的行:
Core.sort(FeatureMatrix, FeatureMatrix, Core.SORT_EVERY_ROW);
编辑: 让我用一个简单的例子来解释:
Mat test = new Mat(4,3, CvType.CV_64FC1);
test.put(0, 0, 1);
test.put(0, 1, 2);
test.put(0, 2, 3);
test.put(1, 0, 1);
test.put(1, 1, 1);
test.put(1, 2, 1);
test.put(2, 0, 2);
test.put(2, 1, 1);
test.put(2, 2, 3);
test.put(3, 0, 1);
test.put(3, 1, 2);
test.put(3, 2, 1);
Core.sort(test, test,Core.SORT_EVERY_ROW + Core.SORT_ASCENDING);
for (int k = 0; k < test.rows(); k++) {
Log.i("Test", test.get(k, 0)[0] + " " + test.get(k, 1)[0]+ " " +test.get(k, 2)[0]);
}
以上例子的结果如下:
03-05 21:32:01.893: I/Test(1323): 1.0 2.0 3.0
03-05 21:32:01.893: I/Test(1323): 1.0 1.0 1.0
03-05 21:32:01.893: I/Test(1323): 1.0 2.0 3.0
03-05 21:32:01.893: I/Test(1323): 1.0 1.0 2.0
但在matlab中的sortrows结果如下:
1 1 1
1 2 1
1 2 3
2 1 3
答案 0 :(得分:1)
函数sort按升序或降序对每个矩阵行或每个矩阵列进行排序。因此,您应该传递两个操作标志以获得所需的行为。
因此,您还需要传递排序顺序标志。由于MATLAB的sortrows
按升序排序,因此传递适当的标志:
Core.sort(FeatureMatrix, FeatureMatrix, Core.SORT_EVERY_ROW + Core.SORT_ASCENDING);
答案 1 :(得分:0)
最后,我决定从头开始编写排序方法,工作结果类似于下面的代码:
private Mat SortRows(Mat FeatureMatrix)
{
// Sorting
Mat SortedFeatureMatrix = new Mat(FeatureMatrix.rows(),FeatureMatrix.cols(), FeatureMatrix.type());
FeatureMatrix.row(0).copyTo(SortedFeatureMatrix.row(0));
for (int i = 1; i < FeatureMatrix.rows(); i++) {
int index = i;
while(index>0)
{
boolean cmp = false;
for (int j = 0; j < FeatureMatrix.cols(); j++) {
if(FeatureMatrix.get(i, j)[0]==SortedFeatureMatrix.get(index-1, j)[0])
{
continue;
}
else if(FeatureMatrix.get(i, j)[0]<SortedFeatureMatrix.get(index-1, j)[0])
{
cmp = true;
SortedFeatureMatrix.row(index-1).copyTo(SortedFeatureMatrix.row(index));
break;
}
else if(FeatureMatrix.get(i, j)[0]>SortedFeatureMatrix.get(index-1, j)[0])
{
cmp = false;
FeatureMatrix.row(i).copyTo(SortedFeatureMatrix.row(index));
break;
}
}
if(cmp == true)
{
index-=1;
if(index == 0)
{
FeatureMatrix.row(i).copyTo(SortedFeatureMatrix.row(index));
}
continue;
}
else
{
break;
}
}
}
return SortedFeatureMatrix;
}
也许这会帮助别人。
答案 2 :(得分:0)
这是一个使用openCV sortIdx函数的高效递归算法:
Mat SortRows(Mat FeatureMatrix,Mat &index,int direction){
Mat main_column=FeatureMatrix.col(0);//Extract Main column
sortIdx(main_column,index,direction+CV_SORT_EVERY_COLUMN);//Sort Main column
Mat sorted_FeatureMatrix=indexing(FeatureMatrix,index);//Sort Whole FeatureMatrix based on Sorted Main Column index
if (FeatureMatrix.cols==1)//last column
return sorted_FeatureMatrix;
//Check identical consecutive elements in Main Column and sort them baesd on next columns
int start=-1;
int end=-1;
for(int i=0;i<sorted_FeatureMatrix.rows;i++)
{
if((i!=sorted_FeatureMatrix.rows-1)&&(sorted_FeatureMatrix.at<float>(i,0)==sorted_FeatureMatrix.at<float>(i+1,0)))
{
if(start==-1) start=i;
end=i+1;
}
else
if(start!=-1)//if Start has been set
{//Seperate next columns of rows(start:end) and Sort them based on next columns
Mat partial_FeatureMatrix=sorted_FeatureMatrix(Range(start,end+1),Range(1,FeatureMatrix.cols));
Mat partial_index=index.rowRange(start,end+1);
Mat temportal_index;
Mat sorted_partial_FeatureMatrix=SortRows(partial_FeatureMatrix,temportal_index,direction);
sorted_partial_FeatureMatrix.copyTo(sorted_FeatureMatrix(Range(start,end+1),Range(1,FeatureMatrix.cols)));
Mat sorted_partial_index=indexing(partial_index,temportal_index);
sorted_partial_index.copyTo(index.rowRange(start,end+1));
start=-1;
end=-1;
}
}
return sorted_FeatureMatrix;}