// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt /* When you are training a convolutional neural network using the loss_mmod loss layer, you need to generate a bunch of identically sized training images. The random_cropper is a convenient tool to help you crop out a bunch of identically sized images from a training dataset. This example shows you what it does exactly and talks about some of its options. */ #include #include #include #include using namespace std; using namespace dlib; // ---------------------------------------------------------------------------------------- int main(int argc, char** argv) try { if (argc != 2) { cout << "Give an image dataset XML file to run this program." << endl; cout << "For example, if you are running from the examples folder then run this program by typing" << endl; cout << " ./random_cropper_ex faces/training.xml" << endl; cout << endl; return 0; } // First lets load a dataset std::vector> images; std::vector> boxes; load_image_dataset(images, boxes, argv[1]); // Here we make our random_cropper. It has a number of options. random_cropper cropper; // We can tell it how big we want the cropped images to be. cropper.set_chip_dims(400,400); // Also, when doing cropping, it will map the object annotations from the // dataset to the cropped image as well as perform random scale jittering. // You can tell it how much scale jittering you would like by saying "please // make the objects in the crops have a min and max size of such and such". // You do that by calling these two functions. Here we are saying we want the // objects in our crops to be no more than 0.8*400 pixels in height and width. cropper.set_max_object_size(0.8); // And also that they shouldn't be too small. Specifically, each object's smallest // dimension (i.e. height or width) should be at least 60 pixels and at least one of // the dimensions must be at least 80 pixels. So the smallest objects the cropper will // output will be either 80x60 or 60x80. cropper.set_min_object_size(80,60); // The cropper can also randomly mirror and rotate crops, which we ask it to // perform as well. cropper.set_randomly_flip(true); cropper.set_max_rotation_degrees(50); // This fraction of crops are from random parts of images, rather than being centered // on some object. cropper.set_background_crops_fraction(0.2); // Now ask the cropper to generate a bunch of crops. The output is stored in // crops and crop_boxes. std::vector> crops; std::vector> crop_boxes; // Make 1000 crops. cropper(1000, images, boxes, crops, crop_boxes); // Finally, lets look at the results image_window win; for (size_t i = 0; i < crops.size(); ++i) { win.clear_overlay(); win.set_image(crops[i]); for (auto b : crop_boxes[i]) { // Note that mmod_rect has an ignore field. If an object was labeled // ignore in boxes then it will still be labeled as ignore in // crop_boxes. Moreover, objects that are not well contained within // the crop are also set to ignore. if (b.ignore) win.add_overlay(b.rect, rgb_pixel(255,255,0)); // draw ignored boxes as orange else win.add_overlay(b.rect, rgb_pixel(255,0,0)); // draw other boxes as red } cout << "Hit enter to view the next random crop."; cin.get(); } } catch(std::exception& e) { cout << e.what() << endl; }