Added --sort and also the ability to propagate boxes from one image to the

next using dlib::correlation_tracker.
This commit is contained in:
Davis King 2017-07-18 22:19:29 -04:00
parent fc92774687
commit e7fe423bc4
2 changed files with 73 additions and 4 deletions

View File

@ -20,7 +20,7 @@
#include <dlib/dir_nav.h>
const char* VERSION = "1.10";
const char* VERSION = "1.11";
const int JPEG_QUALITY = 90;
@ -611,6 +611,7 @@ int main(int argc, char** argv)
parser.add_option("rmdiff","Set the ignored flag to true for boxes marked as difficult.");
parser.add_option("rmtrunc","Set the ignored flag to true for boxes that are partially outside the image.");
parser.add_option("sort-num-objects","Sort the images listed an XML file so images with many objects are listed first.");
parser.add_option("sort","Alphabetically sort the images in an XML file.");
parser.add_option("shuffle","Randomly shuffle the order of the images listed in an XML file.");
parser.add_option("seed", "When using --shuffle, set the random seed to the string <arg>.",1);
parser.add_option("split", "Split the contents of an XML file into two separate files. One containing the "
@ -646,7 +647,8 @@ int main(int argc, char** argv)
const char* singles[] = {"h","c","r","l","files","convert","parts","rmdiff", "rmtrunc", "rmdupes", "seed", "shuffle", "split", "add",
"flip", "rotate", "tile", "size", "cluster", "resample", "min-object-size", "rmempty",
"crop-size", "cropped-object-size", "rmlabel", "rm-other-labels", "rm-if-overlaps", "sort-num-objects", "one-object-per-image", "jpg", "rmignore"};
"crop-size", "cropped-object-size", "rmlabel", "rm-other-labels", "rm-if-overlaps", "sort-num-objects",
"one-object-per-image", "jpg", "rmignore", "sort"};
parser.check_one_time_options(singles);
const char* c_sub_ops[] = {"r", "convert"};
parser.check_sub_options("c", c_sub_ops);
@ -701,6 +703,7 @@ int main(int argc, char** argv)
parser.check_incompatible_options("add", "resample");
parser.check_incompatible_options("shuffle", "tile");
parser.check_incompatible_options("sort-num-objects", "tile");
parser.check_incompatible_options("sort", "tile");
parser.check_incompatible_options("convert", "l");
parser.check_incompatible_options("convert", "files");
parser.check_incompatible_options("convert", "rename");
@ -1106,6 +1109,22 @@ int main(int argc, char** argv)
return EXIT_SUCCESS;
}
if (parser.option("sort"))
{
if (parser.number_of_arguments() != 1)
{
cerr << "The --sort option requires you to give one XML file on the command line." << endl;
return EXIT_FAILURE;
}
dlib::image_dataset_metadata::dataset data;
load_image_dataset_metadata(data, parser[0]);
std::sort(data.images.begin(), data.images.end(),
[](const image_dataset_metadata::image& a, const image_dataset_metadata::image& b) { return a.filename < b.filename; });
save_image_dataset_metadata(data, parser[0]);
return EXIT_SUCCESS;
}
if (parser.option("stats"))
{
if (parser.number_of_arguments() != 1)

View File

@ -10,6 +10,7 @@
#include <dlib/array2d.h>
#include <dlib/pixel.h>
#include <dlib/image_transforms.h>
#include <dlib/image_processing.h>
#include <sstream>
#include <ctime>
@ -232,6 +233,31 @@ on_window_resized(
// ----------------------------------------------------------------------------------------
void propagate_boxes(
dlib::image_dataset_metadata::dataset& data,
unsigned long prev,
unsigned long next
)
{
if (prev == next || next >= data.images.size())
return;
array2d<rgb_pixel> img1, img2;
dlib::load_image(img1, data.images[prev].filename);
dlib::load_image(img2, data.images[next].filename);
for (unsigned long i = 0; i < data.images[prev].boxes.size(); ++i)
{
correlation_tracker tracker;
tracker.start_track(img1, data.images[prev].boxes[i].rect);
tracker.update(img2);
dlib::image_dataset_metadata::box box = data.images[prev].boxes[i];
box.rect = tracker.get_position();
data.images[next].boxes.push_back(box);
}
}
// ----------------------------------------------------------------------------------------
void propagate_labels(
const std::string& label,
dlib::image_dataset_metadata::dataset& data,
@ -354,7 +380,18 @@ on_keydown (
if (key == base_window::KEY_UP)
{
if (state&base_window::KBD_MOD_CONTROL)
if ((state&KBD_MOD_CONTROL) && (state&KBD_MOD_SHIFT))
{
// Don't do anything if there are no boxes in the current image.
if (metadata.images[image_pos].boxes.size() == 0)
return;
// Also don't do anything if there *are* boxes in the next image.
if (image_pos > 1 && metadata.images[image_pos-1].boxes.size() != 0)
return;
propagate_boxes(metadata, image_pos, image_pos-1);
}
else if (state&base_window::KBD_MOD_CONTROL)
{
// If the label we are supposed to propagate doesn't exist in the current image
// then don't advance.
@ -371,7 +408,18 @@ on_keydown (
}
else if (key == base_window::KEY_DOWN)
{
if (state&base_window::KBD_MOD_CONTROL)
if ((state&KBD_MOD_CONTROL) && (state&KBD_MOD_SHIFT))
{
// Don't do anything if there are no boxes in the current image.
if (metadata.images[image_pos].boxes.size() == 0)
return;
// Also don't do anything if there *are* boxes in the next image.
if (image_pos+1 < metadata.images.size() && metadata.images[image_pos+1].boxes.size() != 0)
return;
propagate_boxes(metadata, image_pos, image_pos+1);
}
else if (state&base_window::KBD_MOD_CONTROL)
{
// If the label we are supposed to propagate doesn't exist in the current image
// then don't advance.
@ -604,6 +652,8 @@ display_about(
"Holding shift + right click and then dragging allows you to move things around. "
"Holding ctrl and pressing the up or down keyboard keys will propagate "
"rectangle labels from one image to the next and also skip empty images. "
"Similarly, holding ctrl+shift will propagate entire boxes via a visual tracking "
"algorithm from one image to the next. "
"Finally, typing a number on the keyboard will jump you to a specific image.",0,0) << endl << endl;
sout << wrap_string("You can also toggle image histogram equalization by pressing the e key."