Exemplo n.º 1
0
Arquivo: main.cpp Projeto: FaceAR/dlib
int resample_dataset(const command_line_parser& parser)
{
    if (parser.number_of_arguments() != 1)
    {
        cerr << "The --resample option requires you to give one XML file on the command line." << endl;
        return EXIT_FAILURE;
    }

    const size_t obj_size = get_option(parser,"resample",100*100); 
    const double margin_scale = 2.5; // cropped image will be this times wider than the object.
    const size_t image_size = obj_size*margin_scale*margin_scale;

    dlib::image_dataset_metadata::dataset data, resampled_data;
    resampled_data.comment = data.comment;
    resampled_data.name = data.name + " RESAMPLED";

    load_image_dataset_metadata(data, parser[0]);
    locally_change_current_dir chdir(get_parent_directory(file(parser[0])));

    console_progress_indicator pbar(data.images.size());
    for (unsigned long i = 0; i < data.images.size(); ++i)
    {
        // don't even bother loading images that don't have objects.
        if (data.images[i].boxes.size() == 0)
            continue;

        pbar.print_status(i);
        array2d<rgb_pixel> img, chip;
        load_image(img, data.images[i].filename);


        // figure out what chips we want to take from this image
        for (unsigned long j = 0; j < data.images[i].boxes.size(); ++j)
        {
            const rectangle rect = data.images[i].boxes[j].rect;
            if (data.images[i].boxes[j].ignore || !get_rect(img).contains(rect))
                continue;

            const rectangle crop_rect = centered_rect(rect, rect.width()*margin_scale, rect.height()*margin_scale);

            // skip crops that have a lot of border pixels
            if (get_rect(img).intersect(crop_rect).area() < crop_rect.area()*0.8)
                continue;

            const rectangle_transform tform = get_mapping_to_chip(chip_details(crop_rect, image_size));
            extract_image_chip(img, chip_details(crop_rect, image_size), chip);

            image_dataset_metadata::image dimg;
            // Now transform the boxes to the crop and also mark them as ignored if they
            // have already been cropped out or are outside the crop.
            for (size_t k = 0; k < data.images[i].boxes.size(); ++k)
            {
                image_dataset_metadata::box box = data.images[i].boxes[k];
                // ignore boxes outside the cropped image
                if (crop_rect.intersect(box.rect).area() == 0)
                    continue;

                // mark boxes we include in the crop as ignored.  Also mark boxes that
                // aren't totally within the crop as ignored.
                if (crop_rect.contains(grow_rect(box.rect,10)))
                    data.images[i].boxes[k].ignore = true;
                else
                    box.ignore = true;

                box.rect = tform(box.rect);
                for (auto&& p : box.parts)
                    p.second = tform.get_tform()(p.second);
                dimg.boxes.push_back(box);
            }
            dimg.filename = data.images[i].filename + "RESAMPLED"+cast_to_string(j)+".jpg";

            save_jpeg(chip,dimg.filename, 98);
            resampled_data.images.push_back(dimg);
        }
    }

    save_image_dataset_metadata(resampled_data, parser[0] + ".RESAMPLED.xml");

    return EXIT_SUCCESS;
}
Exemplo n.º 2
0
int resample_dataset(const command_line_parser& parser)
{
    if (parser.number_of_arguments() != 1)
    {
        cerr << "The --resample option requires you to give one XML file on the command line." << endl;
        return EXIT_FAILURE;
    }

    const size_t obj_size = get_option(parser,"cropped-object-size",100*100); 
    const double margin_scale =  get_option(parser,"crop-size",2.5); // cropped image will be this times wider than the object.
    const unsigned long min_object_size = get_option(parser,"min-object-size",1);
    const bool one_object_per_image = parser.option("one-object-per-image");

    dlib::image_dataset_metadata::dataset data, resampled_data;
    std::ostringstream sout;
    sout << "\nThe --resample parameters which generated this dataset were:" << endl;
    sout << "   cropped-object-size: "<< obj_size << endl;
    sout << "   crop-size: "<< margin_scale << endl;
    sout << "   min-object-size: "<< min_object_size << endl;
    if (one_object_per_image)
        sout << "   one_object_per_image: true" << endl;
    resampled_data.comment = data.comment + sout.str();
    resampled_data.name = data.name + " RESAMPLED";

    load_image_dataset_metadata(data, parser[0]);
    locally_change_current_dir chdir(get_parent_directory(file(parser[0])));
    dlib::rand rnd;

    const size_t image_size = std::round(std::sqrt(obj_size*margin_scale*margin_scale));
    const chip_dims cdims(image_size, image_size);

    console_progress_indicator pbar(data.images.size());
    for (unsigned long i = 0; i < data.images.size(); ++i)
    {
        // don't even bother loading images that don't have objects.
        if (data.images[i].boxes.size() == 0)
            continue;

        pbar.print_status(i);
        array2d<rgb_pixel> img, chip;
        load_image(img, data.images[i].filename);


        // figure out what chips we want to take from this image
        for (unsigned long j = 0; j < data.images[i].boxes.size(); ++j)
        {
            const rectangle rect = data.images[i].boxes[j].rect;
            if (data.images[i].boxes[j].ignore || rect.area() < min_object_size)
                continue;

            const auto max_dim = std::max(rect.width(), rect.height());

            const double rand_scale_perturb = 1 - 0.3*(rnd.get_random_double()-0.5);
            const rectangle crop_rect = centered_rect(rect, max_dim*margin_scale*rand_scale_perturb, max_dim*margin_scale*rand_scale_perturb);

            const rectangle_transform tform = get_mapping_to_chip(chip_details(crop_rect, cdims));
            extract_image_chip(img, chip_details(crop_rect, cdims), chip);

            image_dataset_metadata::image dimg;
            // Now transform the boxes to the crop and also mark them as ignored if they
            // have already been cropped out or are outside the crop.
            for (size_t k = 0; k < data.images[i].boxes.size(); ++k)
            {
                image_dataset_metadata::box box = data.images[i].boxes[k];
                // ignore boxes outside the cropped image
                if (crop_rect.intersect(box.rect).area() == 0)
                    continue;

                // mark boxes we include in the crop as ignored.  Also mark boxes that
                // aren't totally within the crop as ignored.
                if (crop_rect.contains(grow_rect(box.rect,10)) && (!one_object_per_image || k==j))
                    data.images[i].boxes[k].ignore = true;
                else
                    box.ignore = true;

                if (box.rect.area() < min_object_size)
                    box.ignore = true;

                box.rect = tform(box.rect);
                for (auto&& p : box.parts)
                    p.second = tform.get_tform()(p.second);
                dimg.boxes.push_back(box);
            }
            // Put a 64bit hash of the image data into the name to make sure there are no
            // file name conflicts.
            std::ostringstream sout;
            sout << hex << murmur_hash3_128bit(&chip[0][0], chip.size()*sizeof(chip[0][0])).second;
            dimg.filename = data.images[i].filename + "_RESAMPLED_"+sout.str()+".png";

            if (parser.option("jpg"))
            {
                dimg.filename = to_jpg_name(dimg.filename);
                save_jpeg(chip,dimg.filename, JPEG_QUALITY);
            }
            else
            {
                save_png(chip,dimg.filename);
            }
            resampled_data.images.push_back(dimg);
        }
    }

    save_image_dataset_metadata(resampled_data, parser[0] + ".RESAMPLED.xml");

    return EXIT_SUCCESS;
}