Beispiel #1
0
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);
    }
}
Beispiel #2
0
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;
}
Beispiel #5
0
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);
  		
  	}	  

}    
Beispiel #7
0
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;
}
Beispiel #8
0
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;
}