void print_feature_vectors(feature_vectors* fs) { printf("FEATURE VECTORS PACKET {{{{{{{{{{{{\n"); for(int i = 0; i < fs->num_vectors; i++) print_feature(&fs->features[i]); printf("}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}\n\n"); }
int main_train(int argc, char **argv) { char *posSplFile = NULL; char *negSplFile = NULL; char *modelFile = NULL; int stage = 15; int width = 0, height = 0; int numPos = 0, numNeg = 0; const int numVal = 400; float tarfpr = 0.05; float maxfnr = 0.05; std::vector<std::string> negImgList; if((argc - 1) / 2 != 10) { print_train_usage(argv[0]); return 1; } for(int i = 1; i < argc; i++) { if(strcmp(argv[i], "--stage") == 0) stage = atoi(argv[++i]); else if(strcmp(argv[i], "-X") == 0) width = atoi(argv[++i]); else if(strcmp(argv[i], "-Y") == 0) height = atoi(argv[++i]); else if(strcmp(argv[i], "--false_alarm_rate") == 0) tarfpr = atof(argv[++i]); else if(strcmp(argv[i], "--missing_rate") == 0) maxfnr = atof(argv[++i]); else if(strcmp(argv[i], "--pos") == 0) posSplFile = argv[++i]; else if(strcmp(argv[i], "--neg") == 0) negSplFile = argv[++i]; else if(strcmp(argv[i], "-m") == 0) modelFile = argv[++i]; else if(strcmp(argv[i], "--numPos")) numPos = atoi(argv[++i]); else if(strcmp(argv[i], "--numNeg")) numNeg = atoi(argv[++i]); else { printf("Can't recognize params %s\n", argv[i]); print_train_usage(argv[0]); return 1; } } if(posSplFile == NULL || negSplFile == NULL || width == 0 || height == 0 || numPos <= 0 || numNeg <= 0){ print_train_usage(argv[0]); return 1; } std::list<float *> positiveSet, negativeSet, validateSet; int ret; std::vector<Feature*> featureSet; float *stepFPR; float npRatio = 1.0 * numNeg / numPos; CascadeClassifier *cc = new CascadeClassifier(); StrongClassifier* sc; float maxfpr = 1.0; std::list<StrongClassifier *> scs; init_cascade_classifier(cc, scs, width, height); printf("GENERATE POSITIVE SAMPLES\n"); ret = generate_positive_samples(posSplFile, positiveSet, width, height, numPos); if(ret != 0) return 2; printf("GENERATE NEGATIVE SAMPLES\n"); read_image_list(negSplFile, negImgList); for(int i = 0; i < numNeg; i ++) { float *data = NULL; read_neg_sample_from_file(negImgList, width, height, &data); #ifdef USE_HAAR_FEATURE integral_image(data, width, height); #endif negativeSet.push_back(data); } printf("GENERATE VALIDATE SAMPLES\n"); generate_validate_samples(negImgList, width, height, validateSet, numPos); printf("Positive sample size: %ld\n", positiveSet.size()); printf("Negative sample size: %ld\n", negativeSet.size()); printf("Validate sample size: %d\n", numVal); printf("GENERATE FEATURE TEMPLATE\n"); generate_feature_set(featureSet, width, height); printf("SELECT FEATURE TEMPLATE\n"); select_feature(featureSet, positiveSet, validateSet, width); init_steps_false_positive(&stepFPR, stage, tarfpr); clock_t startTime = clock(); char outname[128]; for(int i = 0; i < stage; i++) { printf("\n--------------cascade stage %d-----------------\n", i+1); int correctSize = 0; std::list<float*>::iterator iter, iterEnd; numNeg = numPos * npRatio; printf("READ NEGATIVE SAMPLES\n"); ret = generate_negative_samples(negImgList, width, height, cc, negativeSet, numNeg); if(ret != numNeg) { printf("Can't generate enough negatvie samples %d:%d\n", ret, numNeg); break; } printf("READ VALIDATE SAMPLES\n"); ret = generate_negative_samples(negImgList, width, height, cc, validateSet, numVal); if(ret != numVal) { printf("Can't generate enough validate samples %d:%d\n", ret, numVal); break; } maxfpr *= stepFPR[i]; printf("Positive sample size: %d\n", numPos); printf("Negative sample size: %d\n", numNeg); printf("Target false positive rate: %f\n", maxfpr); printf("Target false negative rate: %f\n", maxfnr); sc = adaboost_learning(cc, positiveSet, numPos, negativeSet, numNeg, validateSet, featureSet, maxfpr, maxfnr); add(cc, sc); iter = positiveSet.begin(); iterEnd = positiveSet.end(); while(iter != iterEnd) { if(classify(cc, *iter, width, 0, 0) == 0) { std::list<float*>::iterator iterTmp = iter; iter++; delete[] (*iterTmp); positiveSet.erase(iterTmp); iter--; } iter++; } numPos = positiveSet.size(); printf("cascade TP: %d\n", numPos); iter = negativeSet.begin(); iterEnd = negativeSet.end(); correctSize = negativeSet.size(); while(iter != iterEnd) { if(classify(cc, *iter, width, 0, 0) == 0) { std::list<float*>::iterator iterTmp = iter; iter++; delete[] (*iterTmp); negativeSet.erase(iterTmp); iter--; } iter++; } printf("cascade TN: %ld\n", correctSize - negativeSet.size()); iter = validateSet.begin(); iterEnd = validateSet.end(); while(iter != iterEnd) { if(classify(cc, *iter, width, 0, 0) == 0) { std::list<float*>::iterator iterTmp = iter; iter++; delete[] (*iterTmp); validateSet.erase(iterTmp); iter--; } iter++; } printf("----------------------------------------\n"); sprintf(outname, "model/cascade_%d.dat", i+1); save(cc, outname); #ifdef SHOW_FEATURE print_feature(cc); #endif } save(cc, modelFile); clock_t trainTime = clock() - startTime; printf("Train time:"); print_time(trainTime); printf("\n"); clear(cc); clear_list(positiveSet); clear_list(negativeSet); clear_list(validateSet); clear_features(featureSet); return 0; }