【问题标题】:Opencv function equal for matlab sortrows用于matlab排序的Opencv函数相等
【发布时间】:2014-04-08 02:19:31
【问题描述】:

我的 Android OpenCV 项目中有一个二维数组类型 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中的排序结果如下:

1     1     1
1     2     1
1     2     3
2     1     3

【问题讨论】:

    标签: android matlab sorting opencv


    【解决方案1】:

    来自documentation

    函数 sort 按升序或降序对每个矩阵行或每个矩阵列进行排序。所以你应该传递两个操作标志来获得所需的行为。

    因此,您还需要传递一个排序标志。由于 MATLAB 的 sortrows 是按升序排序的,因此请传递相应的标志:

    Core.sort(FeatureMatrix, FeatureMatrix, Core.SORT_EVERY_ROW + Core.SORT_ASCENDING);
    

    【讨论】:

    • 这与 sortrows 不同。这将对行进行排序,因为它逐行排序并对每行中的所有元素进行排序。 Matlab 排序行将交换行,以便在第一列将较低的意义上,每一行将“更小”,或者如果相等,则第二列将较低,依此类推。不会改变每行中列的顺序,只会移动整行。
    【解决方案2】:

    最后,我决定从头开始编写排序方法,工作结果变成如下代码:

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

    也许这对其他人有帮助。

    【讨论】:

      【解决方案3】:

      这是一个使用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;}
      

      【讨论】:

        猜你喜欢
        • 2020-11-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多