2017-11-26 5 views
0

openCVメソッドwarpPerspective()を最初から実装しようとしていますが、私は以下のコードを作成しました.yとxのシフトを処理できますが、findHomography warpPerspective()出力と比較して空白のイメージを与えるようにしました。openCVメソッドの実装warpPerspective()

私は、ピクセルの新しい場所を見つけるために、この定義に従っ:

s*x' h1 h2 h3 x s*y' = h4 h5 h6 * y s h7 h8 1 1

私のマッピングは、0.5、1、{のような単純なシフトに取り組んでいます-51,0,1,50,0,0 、1} enter image description here

が、行列は次のようである場合: [1.0340946, 0.032195676, -6.419126; 0.00302419, 1.0487343, -96.520393; 3.7013847e-06, 0.00010837225, 1] 出力は次のようである:

enter image description here

私の実装: - 与えられたHと画像A、 - Aのピクセルの新しい位置を見つけてTransArryに保存します。配列のインデックスはAの線形化インデックスです。 - AのピクセルをtranImgに置き換えます。

Mat transform(Mat A, Mat H) 
{ 
// allocate array of all locations 
int Numrows = A.rows; 
int Numcols = A.cols; 
int channels = A.channels(); 
cout << "rows " << Numrows << "col " << Numcols << "channels " << channels <<endl; 
int size = Numrows*Numcols; 
int MaxX,MaxY = -1000; 
int MinX,MinY = 1000; 
int *TransArry = (int *)malloc(sizeof(int)*size); 
int Idx; 

int homeX=Idx % Numcols; 
int homeY=Idx/Numcols; 
cout << H << endl; 

waitKey();   
for (Idx=0; Idx < size; ++Idx){ 

     homeX=Idx % Numcols; 
     homeY=Idx/Numcols; 

     float x = (H.at<float>(0,0) * (homeX)) +(H.at<float>(0,1) * (homeY)) + (H.at<float>(0,2) * 1) ; 
     float y = (H.at<float>(1,0) * (homeX)) +(H.at<float>(1,1) * (homeY)) + (H.at<float>(1,2) * 1) ; 
     float s = (H.at<float>(2,0) * (homeX)) +(H.at<float>(2,1) * (homeY)) + (H.at<float>(2,2) * 1) ; 

     cout << " x = " << x << " y= " << y << " s= " << s; 
     x = (x/s); 

     y = y/s; 

     // for the first col in TransMatrix 
     if (homeX ==0){ 
      if (x > MaxX) MaxX = x; 
      if (x < MinX) MinX = x; 
     } 

     //for thee first row in TransMatrix 
     if (homeY ==0){ 
      if (y > MaxY) MaxY = y; 
      if (y < MinY) MinY = y; 
     } 
     if((y)>=A.rows || (y)<0 || (x)>=A.cols || (x)<0){ 
      TransArry[Idx] = -1; 
      cout << "x= " << x << "y= "<< y << endl; 
     }else{ 
      TransArry[Idx] = (y * Numcols + x); 
     }   

     //cout << Numcols << endl; 
     cout <<  "New index of " << Idx << "is " << TransArry[Idx] << endl; 
     } 

     Mat tranImg ; 

     A.copyTo(tranImg); 
     tranImg = tranImg - tranImg; 
     cout <<  "Rows" << tranImg.rows << "cols" << tranImg.cols << "cha" << A.channels() << endl; 


     waitKey(); 
     // Remap Image 
     for (Idx=0; Idx < size; Idx ++){ 

      homeX=Idx % Numcols; 
      homeY=Idx/Numcols;     
      //tranImg.at<uchar>(homeY, homeX) =0; 
      if(TransArry[Idx] != -1){ 
       //cout << "Index " << Idx << "Passed " << endl; 
       int newhomeX=TransArry[Idx] % Numcols; // Col ID 
       int newhomeY=TransArry[Idx]/Numcols; // Row ID 


       cout << "Index is " << Idx << endl; 
       cout << "HomeX is " << homeX << " and HomeY is " << homeY << endl; 
       cout << "New Index is " << TransArry[Idx] << endl; 
       cout << "New HomeX is " << newhomeX << " and New HomeY is " << newhomeY << endl; 
       cout << "*****************************************"<< endl; 
       // if (!(Idx%100)) sleep(20); 

       tranImg.at<uchar>(newhomeY, (newhomeX*channels)) = A.at<uchar>(homeY, homeX*channels); 
       if(channels>1) 
        tranImg.at<uchar>(newhomeY, newhomeX*channels+1) = A.at<uchar>(homeY, homeX*channels+1); 
       if(channels>2) 
        tranImg.at<uchar>(newhomeY, newhomeX*channels+2) = A.at<uchar>(homeY, homeX*channels+2); 
       // if (!(Idx%100)){ 
        // imshow("inside", tranImg); 
        // waitKey(1); 
        // } 
       } 
     } 
     //cout << tranImg << endl; 

return tranImg; 

} 

Hを計算して検証します。

したがって、行列HとAにアクセスする方法に問題はありますか?

答えて

2

私の答えはhereです。両方の質問に答える必要があります。この答えはまだwarpPerspective()を使用していますが、ホモグラフィがイメージの境界をどのくらい遠ざけているかを計算する方法の完全な洞察が得られ、イメージの各面に適切にパッドすることができます。

warpPerspective()を手動で実行する場合は、すべての画像座標を線形同次配列に入れ、ホモグラフィで乗算し、最後の座標で除算してデカルト座標に戻すだけです。次に、remap()を使用して補間を実行できます。 remap()の構文は混乱する可能性がありますので、私の答えhereを参照して、その使い方を知ることができます。この答えは、手動変換と補間を示します。これは、少なくともほぼ同じ結果をwarpPerspective()に与えるはずです。

+0

詳細な回答をいただきありがとうございます。解決策を試しましたが、回転した画像が表示されません。コードを別の質問に投稿すべきですか?なぜなら行列要素を扱い、それらをc配列に変換しようとする問題があるからです。 –

+1

@KaramAboGhaliehこの質問の範囲にまだ当てはまると思います。元の投稿を編集してコードと現在の問題を含めるだけです(ただし、あなたの現在の投稿を削除しないことをお勧めします)。投稿を編集すると質問のキューにも表示されますので、さらに反応が出るかもしれません。また、私のGitHubリポジトリ[C++の埋め込みワープロ](https://github.com/alkasm/padded-transformations-cpp)を参考にしてください。 –

+0

私の実装は、xまたはyのシフトでうまく動作しますが、完全なHの行列を扱うことはできません。 –

関連する問題