user969776
user969776

Reputation: 53

OpenCV PCA question

I'm trying to create a PCA model in OpenCV to hold pixel coordinates. As an experiment I have two sets of pixel coordinates that maps out two approximate circles. Each set of coordiantes has 48 x,y pairs. I was experimenting with the following code which reads the coordinates from a file and stores them in a Mat structure. However, I don't think it is right and PCA in openCV seems very poorly covered on the Internet.

    Mat m(2, 48, CV_32FC2); // matrix with 2 rows of 48 cols of floats held in two channels

pFile = fopen("data.txt", "r");

for (int i=0; i<48; i++){
    int x, y;
    fscanf(pFile, "%d%c%c%d%c", &x, &c, &c, &y, &c);

    m.at<Vec2f>( 0 , i )[0] = (float)x; // store x in row 0, col i in channel 0
    m.at<Vec2f>( 0 , i )[1] = (float)y; // store y in row 0, col i in channel 1

}

for (int i=0; i<48; i++){
    int x, y;
    fscanf(pFile, "%d%c%c%d%c", &x, &c, &c, &y, &c);

    m.at<Vec2f>( 1 , i )[0] = (float)x; // store x in row 1, col i in channel 0
    m.at<Vec2f>( 1 , i )[1] = (float)y; // store y in row 1, col i in channel 1

}

PCA pca(m, Mat(), CV_PCA_DATA_AS_ROW, 2); // 2 principle components??? Not sure what to put here e.g. is it 2 for two data sets or 48 for number of elements?

    for (int i=0; i<48; i++){
 float x = pca.mean.at<Vec2f>(i,0)[0]; //get average x
     float y = pca.mean.at<Vec2f>(i,0)[1]; //get average y
     printf("\n x=%f, y=%f", x, y);
}

However, this crashes when creating the pca object. I know this is a very basic question but I am a bit lost and was hoping that someone could get me started with pca in open cv.

Upvotes: 2

Views: 5114

Answers (1)

Kevin
Kevin

Reputation: 771

Perhaps it would be helpful if you described in further detail what you need to use PCA for and what you hope to achieve (output?).

I am fairly sure that the reason your program crashes is because the input Mat is CV_32FC2, when it should be CV_32FC1. You need to reshape your data into 1 dimensional row vectors before using PCA, not knowing what you need I can't say how to reshape your data. (The common application with images is eigenFace which requires an image to be reshaped into a row vector). Additionally you will need to normalize your input data between 0 and 1.

As a further aside, usually you would choose to keep 1 less principal component than the number of input samples because the last principal component is simply orthogonal to the others.

I have worked with opencv PCA before and would like to help further. I would also refer you to this blog: http://www.bytefish.de/blog/pca_in_opencv which helped me get started with PCA in openCV.

Upvotes: 3

Related Questions