6

未知のタイプの行列の要素にアクセスしたいと思います。

for(int ii = 0; ii < origCols; ii++)
{
  colIdx.at<img.type()>(0,ii) = ii+1; // make one based index
}

タイプを定義する式(<>内)は定数である必要があるため、上記のコードは機能しません。異なる画像タイプを切り替える以外に、これを行う方法はありますか?

4

2 に答える 2

4

いくつかのドキュメントを調べた後、分岐を回避せずにそれを行うためのネイティブのOpenCVの方法はないと思います。

よりクリーンなコードが気になる場合は、テンプレートを気にしない限り、テンプレートアプローチを試すことができます。

template <typename T> void dostuff(cv::Mat& colIdx, int origCols)
{
   for(int ii = 0; ii < origCols; ii++)
   {
       colIdx.at<T>(0,ii) = (T)(ii+1); // make one based index
   }
}

void dostuff_poly(cv::Mat& colIdx, int origCols)
{
    switch(colIdx.type())
    {
        case CV_8UC1: dostuff<char>(colIdx, origCols); break;
        case CV_32FC1: dostuff<float>(colIdx, origCols); break;
        case CV_64FC1: dostuff<double>(colIdx, origCols); break;
        // and so on
        default:
    }
}

この例では、コードがかなり小さいので、テンプレートは悪い選択ではないように見え、冗長なコードをたくさん書くことなく、必要なポリモーフィズムを提供します。

たぶん、これらのチュートリアルのいくつかはあなたにもっと良いアイデアを与えるでしょう:

OpenCVドキュメント:コアモジュールチュートリアル

OpenCVドキュメント:画像をスキャンする方法

于 2012-07-16T22:14:25.530 に答える
1

あなたの問題に対するネイティブのOpencvソリューションはありません、そしてそれはこのライブラリで頻繁に苦痛です。考えられる解決策は3つあります。

  1. 常に同じ深さの行列を使用してください。それはあなたが聞きたいことではないと思います。
  2. マトリックスに含まれる要素のタイプによってコードを呼び出すメソッドをテンプレート化します。.at<>メソッドのテンプレートは、マトリックスのcv :: Point2fによるものである必要があるため、これは単一チャネルマトリックスに対してのみ機能します。複数のチャネル。
  3. 行列の深さに基づいて行列データにアクセスする方法を知っている「スマート」イテレータクラスを作成します。何かのようなもの:

    class PtrMat
    {
      PtrMat(cv::Mat& mat, int row)
      {
        if(mat.depth() == CV_32F) { _ptr = new PtrFloat(mat, row); }
        else if(mat.depth() == CV_8U) { _ptr = new PtrUchar(mat, row); }
        ...
      }
      Ptr* _ptr
    };
    
    class Ptr
    {
      virtual void set(const float& val)=0;
    };
    class PtrFloat: public Ptr
    {
      PtrFloat(const cv::Mat& mat, int row){ _val = mat.ptr<float>(row); }
      void set(const float& val) { _val = val; }
      float* _val;
    }
    class PtrUchar: public Ptr
    {
      PtrUchar(const cv::Mat& mat, int row){ _val = mat.ptr<uchar>(row); }
      void set(const float& val) { _val = val; }
      uchar* _val;
    }
    

もちろん、3番目のソリューションでは、多くの重複コードが発生します。フロートキャスティングは、ループの速度を低下させる可能性もあります。この場合、完璧な解決策はありません。

于 2012-07-17T14:18:36.767 に答える