# LDA loaded does not work

I've trained my LDA on several thousand images and was keen to save it so that I could load it in the main program that would be doing predictions (rather than running it fresh each time). I knew that with an SVM I can use a command like this to save it:

SVM.save("tag_svm.yml");


So I tried a similar thing for LDA, and that also seemed to work:

cv::LDA lda(2);
lda.compute(trainData, trainLabels);
cv::Mat projected = lda.project(trainData);
lda.save("tag_lda.yml");


Then, in my prediction program, I load the LDA and try to project the new data:

cv::LDA lda(2);
cv::Mat projected = lda.project(testData);


The loading part worked fine, however when I try to project the new data, I get this error:

OpenCV Error: Bad argument (Wrong shapes for given matrices. Was size(src) = (256,30), size(W) = (256,2).) in subspaceProject error: (-5) Wrong shapes for given matrices. Was size(src) = (256,30), size(W) = (256,2). in function subspaceProject


But that doesn't make sense to me: the data I trained the LDA on had 256 columns, it was grayscale pixel values. I did exactly the same processing for my test images as I did for my training images. If I don't bother about loading the LDA and just have the prediction stage in the same program it works perfectly (same code for processing the test images too!), so I can't understand why this error keeps occurring.

To clarify, I've been running std::cout on trainData and to confirm it has 256 cols and 30 rows but still get the error. This is driving me crazy because if I deliberately make testData an incorrectly sized matrix (not the 256 cols it's expecting) than I get the same answer!

The main section of code

cv::Mat testData;

for (int i=0; i < 30; i++)
{
std::string filename = "/Users/u5305887/Desktop/tags/test/";
filename = filename + std::to_string(i);
filename = filename + ".jpg";
cv::Mat flat_image = image.clone().reshape(0, 1);
testData.push_back(flat_image);
}

cv::LDA lda;

std::cout << "testData columns: " << testData.cols << std::endl;
std::cout << "testData rows: " << testData.rows << std::endl;

cv::Mat projected = lda.project(testData);

cv::Mat proj_float;
projected.convertTo(proj_float, CV_32FC1);

edit retag close merge delete

3

please check your testData. it should have 256 cols (and any number of rows)

( 2015-07-06 05:31:18 -0500 )edit

I've been doing std::cout for the number of cols and rows for trainData, I keep getting 256 for trainData.cols and 30 for trainData.rows. That's what I don't understand about the error.

( 2015-07-06 06:49:45 -0500 )edit

But thank-you for the suggestion, it's something I should have been more explicit about and would have made a lot of sense given the error messages, which is why I'm finding this so confusing!

( 2015-07-06 06:56:20 -0500 )edit

Do you happen to know what the error "Was size(src) = (256,30), size(W) = (256,2). in function subspaceProject" means?

( 2015-07-06 07:03:06 -0500 )edit

berak said testData (not trainData), that is the data you are projecting in LDA (after loading the LDA)

( 2015-07-06 09:06:45 -0500 )edit
1

your testdata seems to have 256 rows, and 30 cols. here's the code (lda.cpp, 178):

int d = src.cols;
// make sure the data has the correct shape
if(W.rows != d) {
String error_message = format("Wrong shapes for given matrices. Was size(src) = (%d,%d), size(W) = (%d,%d).", src.rows, src.cols, W.rows, W.cols);