trying to make face recognition with ANN

asked 2014-05-12 10:36:28 -0600

Darius gravatar image

updated 2014-05-12 11:25:04 -0600

berak gravatar image

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.

edit retag flag offensive close merge delete

Comments

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

berak gravatar imageberak ( 2014-05-12 12:09:56 -0600 )edit

that post is realy good:) i already made data loading, now just reading the "MLP readymade" to get a grip how its made :)

Darius gravatar imageDarius ( 2014-05-12 12:48:14 -0600 )edit

found an mlp example

berak gravatar imageberak ( 2014-05-12 13:10:32 -0600 )edit

can someone explain me why i get memory allocation problem?

int sks[4]={10,10,5,1};
  CvMat skuoksniai= cvMat(1,4,CV_8UC1,sks); // not sure about CV_8UC1 part as well :/
  CvANN_MLP tinklas;
  tinklas.create( &skuoksniai,CvANN_MLP::SIGMOID_SYM,1,1); //problem line.
Darius gravatar imageDarius ( 2014-05-13 11:08:43 -0600 )edit
1
int sks[4]={10,10,5,1};
cv::Mat skuoksniai= cv::Mat(1,4,CV_32SC1,sks); // just use CV_32S
CvANN_MLP tinklas;
tinklas.create(skuoksniai,CvANN_MLP::SIGMOID_SYM,1,1); //problem no more i hope ;)

(yea, i know, that cv::Mat, cvMat is annoying ...)

is that lithuanian above ;) ?

berak gravatar imageberak ( 2014-05-13 11:20:28 -0600 )edit

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 :)

Darius gravatar imageDarius ( 2014-05-13 11:24:05 -0600 )edit

damn, works fine here ...

berak gravatar imageberak ( 2014-05-13 11:34:04 -0600 )edit

dude, sry my bad.. didn't sow the "cv::Mat" part. now its seams to run :) thank you so much :)

Darius gravatar imageDarius ( 2014-05-13 11:38:27 -0600 )edit

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);

Darius gravatar imageDarius ( 2014-05-13 12:56:24 -0600 )edit

http://docs.opencv.org/modules/ml/doc/neural_networks.html#cvann-mlp-train

  • your trainData Mat has the correct shape, but the wrong type. you need float data here, so it needs a simple conversion, before you apply it: trainData.convertTo(trainData, CV_32F); (cvtColor is more for translating from bgr to hsv or such, it does not change the datatype)
  • your labels have the wrong shape. for 17 feature vecs(rows), you need 17 labels(rows) as well, so: 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 ;)

berak gravatar imageberak ( 2014-05-13 13:33:30 -0600 )edit

yeah, i did a bit reading bout CV_32F c1 c2 and etc :) ill gona try thank you again :)

Darius gravatar imageDarius ( 2014-05-13 13:57:46 -0600 )edit

still same error, ill gonna continue tomorrow, and ill post if find anything :) thank you for your help, its getting bit clearer :D

Darius gravatar imageDarius ( 2014-05-13 14:46:21 -0600 )edit

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

Darius gravatar imageDarius ( 2014-05-14 04:46:33 -0600 )edit

morning ;)

cv::Mat pazinti(1,38416,CV_32F); // 1 feature vector for testing (1 row)
cv::Mat label(1, 1, CV_32FC1 ); // as many rows as your output layer (1 here?)

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)

berak gravatar imageberak ( 2014-05-14 05:03:17 -0600 )edit

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?

Darius gravatar imageDarius ( 2014-05-14 05:14:36 -0600 )edit

" 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);

berak gravatar imageberak ( 2014-05-14 05:30:33 -0600 )edit

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} }

Darius gravatar imageDarius ( 2014-05-14 05:41:22 -0600 )edit

"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..

berak gravatar imageberak ( 2014-05-14 05:48:01 -0600 )edit

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?

Darius gravatar imageDarius ( 2014-05-14 06:50:06 -0600 )edit

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. ;(

berak gravatar imageberak ( 2014-05-14 07:01:02 -0600 )edit

thank you once again :) i will make that ** work :D in this point you deserve a medal for helping me out ;)

Darius gravatar imageDarius ( 2014-05-14 07:14:37 -0600 )edit

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.

Darius gravatar imageDarius ( 2014-05-14 08:26:32 -0600 )edit

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..)

berak gravatar imageberak ( 2014-05-14 08:45:07 -0600 )edit

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 :(

Darius gravatar imageDarius ( 2014-05-14 08:59:02 -0600 )edit

google thought so, too. ;9

what are you trying to imshow() ? if it's a float img, if it's not in the [0..1] range, it might need some scaling, like img/255 or similar.

also, if you're training with backprop, you'll probably need a few ( thousand ;] ) iterations

berak gravatar imageberak ( 2014-05-14 09:08:40 -0600 )edit

yeah, google knows it all :D i checked that transormation, everything is alight, i guess now just need to make backprop with parameters :) could you explain in human language what sampleIdx should contain? talking about CvANN_MLP::train

Darius gravatar imageDarius ( 2014-05-14 09:27:39 -0600 )edit