2012-04-11 9 views
1

私はUbuntu Opencvで働いています。私は1つの画像のPCA分析をしようとしています。私は3つのチャンネル画像を取って、3つの列とr * c番号rows.rとCのそれは私に緑のimage.Hereを与えるPCAに逆投影を行った後、私は再構成画像を表示しようとする元image.Whenの行と列であることはあなたが私のコードPCAプロジェクトとOpencvのバックプロジェクト

Mat pcaset=cvCreateMat(image->height*image->width,image->nChannels,CV_8UC1); 
for(int i=0;i<image->height;i++) 
    { 
     for(int j=0;j<image->width;j++) 
     { 
      for(int k=0;k<image->nChannels;k++) 
      (ptrpcaset+i*pcaset.step)[k]=((ptrimage+i*image->widthStep)[3*j+k]); 

     } 

    } 
int nEigens=3; 
    Mat databackprojected; 
    PCA pca(pcaset,Mat(),CV_PCA_DATA_AS_ROW,nEigens); 
    Mat dataprojected(pcaset.rows,nEigens,CV_8UC1); 
    pca.project(pcaset,dataprojected); 
    pca.backProject(dataprojected,databackprojected); 
    Mat backprojectnorm;//(databackprojected.rows,nEigens,CV_8UC1); 
    normalize(databackprojected,backprojectnorm,0,255,NORM_MINMAX,-1); 
    Mat finaldataafterreshaping(image->height,image->width,CV_8UC3); 
    uchar* finalptr=(uchar*)finaldataafterreshaping.data; 
    uchar* ptrnorm=(uchar*)backprojectnorm.data; 

    int x=0,y=0,i=0; 

    while(i<backprojectnorm.rows) 
    { 
     while(x<image->height) 
     { 
      while(y<image->width) 
      { 
       for(int k=0;k<image->nChannels;k++) 
       { 
        (finalptr+x*finaldataafterreshaping.step)[3*y+k]=(ptrnorm+i*backprojectnorm.step)[k]; 
       } 
       y=y+1;i=i+1; 
      } 
      x=x+1;y=0; 
     } 
    } 
imshow("Reconstructed data",finaldataafterreshaping); 

答えて

1

です次の変更を行う必要があります。

(ptrpcaset+(j + i*image->width)*pcaset.step)[k]=((ptrimage+i*image->widthStep)[3*j+k]); 

j座標を使用していないため、int oあなたがデータを変換するときに、最終的に新しい行列に画像の最後の行を保存するようにします。

、あなたのデータを再構築するとき、あなたはこのような何か実行する必要があります。あなたが結果として取得行列はタイプfloatないucharであるため

float* val = (float*)&(ptrnorm+i*backprojectnorm.step)[(k*4)]; 
(finalptr+x*finaldataafterreshaping.step)[3*y+k]=*val; 

を。だから、何らかの変換が必要です。私はそれがこのようにすることは良い考えであるかどうかはわかりませんが、うまくいきます。私はOpenCV 2のC++ APIを見てみることをお勧めします.OpenCV 2はこれをはるかに良い方法で処理できます。

また、while(i<backprojectnrom.rows)ループ全体は必要ありません。

+0

私は(ptrpcaset +(j + i * image-> width)* pcaset.stepを実行すれば、各行はピクセルのrgb値を表す* 3行列に変換しようとしています) [k]これはどうすれば – SB26

+0

が動作しますが、 'n'は' width x height'ですか? 現在、変数 'i'を使用して宛先行列の行をアドレス指定しています。しかし、 'i'は0と' image-> height'の間の値だけをとります。したがって、作成した行列の大量の行にアクセスしていないため、何かが正しくないことがわかります。 したがって、変数 'j'を'(j + i * image-> width) 'のようなもので考慮する必要があります。この式を使用すると、(i、j)の各ペアに対して1つのユニークなインデックスが得られます。つまり、1ピクセルあたり1行だけ正確に表示されます。 – sietschie