2012-04-11 36 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