2012-04-11 4 views
1

Je travaille dans Ubuntu Opencv.J'essaie de faire l'analyse PCA d'une seule image.J'utilise l'image à 3 canaux et la change en une image à un seul canal avec 3 colonnes et un numéro r * c de rows.r et c étant les lignes et les colonnes du image.When original que je tente d'afficher l'image reconstruite après avoir fait la rétroprojection sur l'APC, il me donne un image.Here vert est mon codeProjet PCA et backproject dans 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); 

Répondre

1

Vous besoin de faire les changements suivants:

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

parce que vous ne prenez pas la coordonnée j int o compte lorsque vous transformez vos données de sorte qu'à la fin vous ne sauvegardez que la dernière ligne de votre image dans la nouvelle matrice.

Lorsque vous remodeler vos données, vous devez faire quelque chose comme ceci:

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

parce que la matrice que vous obtenez comme résultat est de type float et non uchar. Vous avez donc besoin d'une sorte de conversion. Je ne suis pas sûr, si c'est une bonne idée de le faire de cette façon, mais cela fonctionne. Je suggère que vous jetez un oeil à l'API C++ d'OpenCV 2, qui peut gérer ces choses d'une manière beaucoup plus agréable.

De plus, l'ensemble de la boucle while(i<backprojectnrom.rows) n'est pas nécessaire.

+0

bien J'essaie de transformer la matrice à 3 canaux en une matrice * 3 où chaque ligne représente la valeur rgb du pixel.so si je le fais (ptrpcaset + (j + i * image-> largeur) * pcaset.step) [k] comment cela fonctionnera-t-il – SB26

+0

mais 'n' est supposé être' width x height'? Actuellement vous adressez les lignes de votre matrice de destination en utilisant la variable 'i'. Mais 'i' ne prend que des valeurs comprises entre 0 et' image-> height'. Vous pouvez donc voir que quelque chose ne va pas parce que vous n'accédez pas à une grande quantité de lignes dans la matrice que vous avez créée. Vous devez donc prendre en compte la variable 'j' avec quelque chose comme ceci' (j + i * image-> width) '. Avec cette formule, vous obtenez un index unique pour chaque paire de (i, j). Donc vous vous retrouvez avec exactement une ligne par pixel. – sietschie