void generate_validate_samples(std::vector<std::string> &imgList, int WIDTH, int HEIGHT, std::list<float*> &validateSet, int size) { assert(size < imgList.size()); if(validateSet.size() > 0) clear_list(validateSet); for(int i = 0 ; i < size; i++) { cv::Mat img = cv::imread(imgList[i], 0); cv::Mat sImg; if(img.empty()) { printf("Can't open image %s\n", imgList[i].c_str()); exit(0); } cv::resize(img, sImg, cv::Size(WIDTH, HEIGHT)); float *data = mat_to_float(sImg); #ifdef USE_HAAR_FEATURE integral_image(data, WIDTH, HEIGHT); #endif validateSet.push_back(data); } }
int generate_negative_samples(std::vector<std::string> &imgList, int WIDTH, int HEIGHT, CascadeClassifier *cc, std::list<float*> &negativeSet, int size) { int count = negativeSet.size(); while(count < size) { float *data; int ret = read_neg_sample_from_file(imgList, WIDTH, HEIGHT, &data); if(ret == 0) return count; #ifdef USE_HAAR_FEATURE integral_image(data, WIDTH, HEIGHT); #endif if(classify(cc, data, WIDTH, 0, 0) == 1) { negativeSet.push_back(data); count++; printf("%6.2f%%\r", 100.0 * count/size); fflush(stdout); } else { delete [] data; } } if(count > size) return size; return count; }
void ImageProcessing::Process(const Scalar* greyscale_image, size_t w, size_t h, size_t pitch) { width = w; height = h; const size_t img_area = width * height; if (img_area > tI.size()) { AllocateImageData(img_area); } // Process image gradient<>(width, height, greyscale_image, &dI[0]); integral_image(width, height, greyscale_image, &intI[0] ); // Threshold image AdaptiveThreshold( width, height, greyscale_image, &intI[0], &tI[0], params.at_threshold, width / params.at_window_ratio, 20, (unsigned char)0, (unsigned char)255 ); // Label image (connected components) labels.clear(); Label(width, height, &tI[0], &lI[0], labels, params.black_on_white ? 0 : 255 ); }
t_image *load_image(const char *path) { t_image *image; image = malloc(sizeof(t_image)); image->surface = IMG_Load(path); image->path = path; if (!image->surface) { warn("%s ", path); return NULL; } image->bw = convert_to_grey_level(image->surface); integral_image(image); return image; }
int generate_positive_samples(const char *imgListFile, std::list<float*> &positiveSet, const int WIDTH, const int HEIGHT, int size) { std::vector<std::string> imgList; int ret; ret = read_image_list(imgListFile, imgList); if(imgList.size() < size) { printf("Can't get enough positive samples\n"); return 1; } for(int i = 0; i < size; i++) { cv::Mat img = cv::imread(imgList[i], 0); float *fData = NULL; if(img.empty()) { printf("Can't open image %s\n", imgList[i].c_str()); return 2; } cv::resize(img, img, cv::Size(WIDTH, HEIGHT)); fData = mat_to_float(img); positiveSet.push_back(fData); #ifdef USE_HAAR_FEATURE integral_image(fData, WIDTH, HEIGHT); #endif printf("%.2f\r", 100.0 * i / size); fflush(stdout); } return 0; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { double *X, *Y; unsigned char *X8; int m, n; //------------------------------------ // UINT8 image //------------------------------------ if (mxGetClassID(prhs[0]) == mxUINT8_CLASS) { //------------------------------------ // INPUT //------------------------------------ //-- // input image //-- X8 = (unsigned char *) mxGetPr(prhs[0]); m = mxGetM(prhs[0]); n = mxGetN(prhs[0]); //------------------------------------ // OUTPUT //------------------------------------ //-- // integral image //-- Y = mxGetPr(plhs[0] = mxCreateDoubleMatrix(m,n,mxREAL)); //------------------------------------ // COMPUTE //------------------------------------ integral_image_uint8(Y, X8, m, n); //------------------------------------ // DOUBLE image //------------------------------------ } else { //------------------------------------ // INPUT //------------------------------------ //-- // input image //-- X = mxGetPr(prhs[0]); m = mxGetM(prhs[0]); n = mxGetN(prhs[0]); //------------------------------------ // OUTPUT //------------------------------------ //-- // integral image //-- Y = mxGetPr(plhs[0] = mxCreateDoubleMatrix(m,n,mxREAL)); //------------------------------------ // COMPUTE //------------------------------------ integral_image(Y, X, m, n); } }
void detect_object2(CascadeClassifier *cc, cv::Mat &img, float startScale, float endScale, int layers, float offsetFactor, std::vector<cv::Rect> &rects) { cv::Mat gray, sImg; int winX = cc->WIDTH; int winY = cc->HEIGHT; int dx = offsetFactor * winX; int dy = offsetFactor * winY; float *data = new float [winX * winY]; float scaleStep = (endScale - startScale) / layers; if(endScale > startScale) { startScale = endScale; scaleStep = -scaleStep; } if(img.channels() == 3) cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY); else gray = img.clone(); for(int i = 0; i < layers; i++) { cv::resize(gray, sImg, cv::Size(startScale * gray.cols, startScale * gray.rows)); int ws = sImg.cols - winX; int hs = sImg.rows - winY; for(int y = 0; y < hs; y += dy) { for(int x = 0; x < ws; x += dx) { cv::Rect rect = cv::Rect(x, y, winX, winY); cv::Mat patch(sImg, rect); float *pData = data; uchar *iData = patch.data; for(int m = 0; m < winY; m++) { for(int n = 0; n < winX; n++) pData[n] = iData[n] / 255.0; pData += winX; iData += patch.step; } #ifdef USE_HAAR_FEATURE integral_image(data, winX, winY); #endif if(classify(cc, data, winX, 0, 0) == 1) { rect.x /= startScale; rect.y /= startScale; rect.width /= startScale; rect.height /= startScale; rects.push_back(rect); } } } startScale += scaleStep; } delete [] data; }
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; }