trying to make face recognition with ANN
Hello, i'm using c++, VS2010, OpenCV 2.4.8. I want to make ANN witch can be trained to separate pictures to different classes (in my case face pictures), and decide if streaming video contains image witch belongs to any class. could you recommend where to start with ANN? how to make training part, or maybe some link to tutoials. i'm using OpenCV face detection program from examples. thank you in advance.
opencv comes with a MLP readymade that you could use.
here is a nice post on how to prepare the data (for an svm, but that step is the same for ANN, too)
apart from that: if you're really into ann's allow some time for this
that post is realy good:) i already made data loading, now just reading the "MLP readymade" to get a grip how its made :)
found an mlp example
can someone explain me why i get memory allocation problem?
(yea, i know, that cv::Mat, cvMat is annoying ...)
is that lithuanian above ;) ?
thank you for quick response. k, ill leave CV_32SC1 part for later. but when i remove & i get "no instance of overloaded function "CvANN_MLP::create"" :( yes :)
damn, works fine here ...
dude, sry my bad.. didn't sow the "cv::Mat" part. now its seams to run :) thank you so much :)
and one again i get memory allocation problem. cv::Mat trainData(17,38416,CV_8UC1)// its 17 rows and 38416 columns of grey images 1 row = image
cv::Mat label= cv::Mat(1,17,CV_32S,temp);// temp is int temp[17]; witch contains {0,0,0,0,0,0,0,1,1,1,1,1,2,2,2,2,2} cv::Mat weights= cv::Mat::ones(1,17,CV_32S); tinklas.train(trainData,label,weights);
i tried cv::Mat new; cvtColor(trainData,new,CV_32S);
http://docs.opencv.org/modules/ml/doc/neural_networks.html#cvann-mlp-train
trainData.convertTo(trainData, CV_32F);
(cvtColor is more for translating from bgr to hsv or such, it does not change the datatype)cv::Mat label= cv::Mat(17,1,CV_32S,temp); // only rows/cols swapped to what you got before
again, don't worry too much. you're doing fine. all that confusion is pretty normal ;)
yeah, i did a bit reading bout CV_32F c1 c2 and etc :) ill gona try thank you again :)
still same error, ill gonna continue tomorrow, and ill post if find anything :) thank you for your help, its getting bit clearer :D
ok, so found reason for that error, it was my silly mistake, forgot to set correct first layer. now i have another error, is with prediction. so the label is the same
cv::Mat label= cv::Mat(17,1,CV_32F,temp); cv::Mat pazinti(0,38416,CV_32F); tinklas.predict(pazinti,label);
and i get this error: OpenCV Error: Assertion failed (dims <= 2 && data && (unsigned)i0 < (unsigned)si ze.p[0] && (unsigned)(i1DataType<_Tp>::channels) < (unsigned)(size.p[1]channel s()) && ((((sizeof(size_t)<<28)|0x8442211) >> ((DataType<_Tp>::depth) & ((1 << 3 ) - 1))*4) & 15) == elemSize1()) in cv::Mat::at, file c:\opencv\build\include\op encv2\core\mat.hpp, line 537
morning ;)
btw, it might be a bit early for that, but to my experience, ann works better with 1 output per class. (you look for the maximum output, that's the actual class prediction)
morning :) well yes my output layer is 1. but i thought label supposed to be the same as in training, now i assume that the predict value will be stored in there?
" i thought label supposed to be the same as in training" - you train with 17 features and 17 resp. labels, and predict with 1 feature and num_outputs labels (a here, again[so far..])
"now i assume that the predict value will be stored in there?" - yep. float cls = mat.at<float>(0,0);
ok, so in that case everything should work, but im geting "OpenCV Error: Assertion failed (layer_sizes != 0) in CvANN_MLP::predict, file ........\opencv\modules\ml\src\ann_mlp.cpp, line 1611" could it be that i have created and trained ANN in a void function? i guess no, because i can use .predict
structure main{ void{load images, create/train ANN} void{webcam stream, .predict} }
"could it be that i have created and trained ANN in a void function?" -hmm, no idea what you mean.
if the problem does not resolve on its own, you might need to put your code on a pastebin, and sent the link here..
how as i thought, i have main function which Creates ANN and trains it (1 time), and i have another function which is in a loop and i want that in there i could use .predict(). so my question: what parameters i should send to my function (which is in a loop) that it could use .predict() ? or maybe i could make ANN global or smth?
oh, is it about passing arguments now ?
int myPredict( CvANN_MLP & ann ) { /* do the prediction*/ } int main() { CvANN_MLP ann; ann.train(...); int p = myPredict(ann); }
on the other hand, you usually train such a beast only once. then you save() it to xml or such, and the next time load() that model instead of retraining.
honestly, i can only guess, what you mean there. ;(
thank you once again :) i will make that ** work :D in this point you deserve a medal for helping me out ;)
ok, i guess its working kinda :D i get from .predict(input,label) data i get it by cout<<(int)label.at<float>(0,0) but its always the same result, no matter what is input. i guess i need to edit ANN.train(). btw i was assuming that it would be trained as backprop and not as rprop.
oh, cool ;)
yea, the fine-tuning will take some work. also, criteria.max_iter, criteria.epsilon, etc.
how do your skuoksniai look like now ? (i love that word..)
lol, i just now sow that i made a mistake in that word :D it should be sluoksniai :D nwm layers = 38416, 300,100,50,1 its random values actualy. but im quite concerned about that CV_32F part, because when i use imshow() the image is almost all white, i wonder does it affect pixel values. and when i use ANN.predict(input.label) (like 10 times with different input) the output doesn't change :(