Opencv函数等于matlab sortrows

时间:2014-03-05 19:45:54

标签: android matlab sorting opencv

我的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

3 个答案:

答案 0 :(得分:1)

来自documentation

  

函数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;}