2012-04-11 35 views
1

我正在Ubuntu Opencv中工作。我嘗試對單個圖像進行PCA分析。我將3個通道圖像並將其更改爲具有3列和r * c數字的單通道圖像rows.r和c是行和原image.When列的我嘗試做的PCA它給了我一個綠色image.Here反投影后顯示重建圖像是我的代碼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* val = (float*)&(ptrnorm+i*backprojectnorm.step)[(k*4)]; 
(finalptr+x*finaldataafterreshaping.step)[3*y+k]=*val; 

因爲你得到的結果矩陣是float型的,而不是uchar。所以你需要進行某種轉換。我不確定,如果這樣做是一個好主意,但它是有效的。我建議你看看OpenCV 2的C++ API,它可以以更好的方式處理這些事情。

此外,整個while(i<backprojectnrom.rows)循環是不需要的。

+0

以及我試圖將3通道矩陣轉換爲* 3矩陣,其中每行代表像素的rgb值。如果我這樣做(ptrpcaset +(j + i * image-> width)* pcaset.step) [k]這將如何工作 – SB26 2012-04-12 17:17:18

+0

但'n'應該是'寬x高'? 目前,您正在使用變量「i」處理目標矩陣的行。但'i'只取0到'image-> height'之間的值。所以你可以看到有些東西是不正確的,因爲你沒有訪問你創建的矩陣中的大量行。 所以你需要把這個變量'j'考慮進去,像這樣'(j + i * image-> width)'。有了這個公式,你可以得到每一對(i,j)的唯一索引。所以最終每個像素只有一行。 – sietschie 2012-04-13 08:12:21