summaryrefslogtreecommitdiffstats
path: root/ml/dlib/tools/imglab/src/flip_dataset.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ml/dlib/tools/imglab/src/flip_dataset.cpp')
-rw-r--r--ml/dlib/tools/imglab/src/flip_dataset.cpp249
1 files changed, 0 insertions, 249 deletions
diff --git a/ml/dlib/tools/imglab/src/flip_dataset.cpp b/ml/dlib/tools/imglab/src/flip_dataset.cpp
deleted file mode 100644
index e072dc790..000000000
--- a/ml/dlib/tools/imglab/src/flip_dataset.cpp
+++ /dev/null
@@ -1,249 +0,0 @@
-// Copyright (C) 2011 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-
-#include "flip_dataset.h"
-#include <dlib/data_io.h>
-#include <dlib/dir_nav.h>
-#include <string>
-#include "common.h"
-#include <dlib/image_transforms.h>
-#include <dlib/optimization.h>
-#include <dlib/image_processing.h>
-
-using namespace dlib;
-using namespace std;
-
-// ----------------------------------------------------------------------------------------
-
-std::vector<long> align_points(
- const std::vector<dpoint>& from,
- const std::vector<dpoint>& to,
- double min_angle = -90*pi/180.0,
- double max_angle = 90*pi/180.0,
- long num_angles = 181
-)
-/*!
- ensures
- - Figures out how to align the points in from with the points in to. Returns an
- assignment array A that indicates that from[i] matches with to[A[i]].
-
- We use the Hungarian algorithm with a search over reasonable angles. This method
- works because we just need to account for a translation and a mild rotation and
- nothing else. If there is any other more complex mapping then you probably don't
- have landmarks that make sense to flip.
-!*/
-{
- DLIB_CASSERT(from.size() == to.size());
-
- std::vector<long> best_assignment;
- double best_assignment_cost = std::numeric_limits<double>::infinity();
-
- matrix<double> dists(from.size(), to.size());
- matrix<long long> idists;
-
- for (auto angle : linspace(min_angle, max_angle, num_angles))
- {
- auto rot = rotation_matrix(angle);
- for (long r = 0; r < dists.nr(); ++r)
- {
- for (long c = 0; c < dists.nc(); ++c)
- {
- dists(r,c) = length_squared(rot*from[r]-to[c]);
- }
- }
-
- idists = matrix_cast<long long>(-round(std::numeric_limits<long long>::max()*(dists/max(dists))));
-
- auto assignment = max_cost_assignment(idists);
- auto cost = assignment_cost(dists, assignment);
- if (cost < best_assignment_cost)
- {
- best_assignment_cost = cost;
- best_assignment = std::move(assignment);
- }
- }
-
-
- // Now compute the alignment error in terms of average distance moved by each part. We
- // do this so we can give the user a warning if it's impossible to make a good
- // alignment.
- running_stats<double> rs;
- std::vector<dpoint> tmp(to.size());
- for (size_t i = 0; i < to.size(); ++i)
- tmp[best_assignment[i]] = to[i];
- auto tform = find_similarity_transform(from, tmp);
- for (size_t i = 0; i < from.size(); ++i)
- rs.add(length(tform(from[i])-tmp[i]));
- if (rs.mean() > 0.05)
- {
- cout << "WARNING, your dataset has object part annotations and you asked imglab to " << endl;
- cout << "flip the data. Imglab tried to adjust the part labels so that the average" << endl;
- cout << "part layout in the flipped dataset is the same as the source dataset. " << endl;
- cout << "However, the part annotation scheme doesn't seem to be left-right symmetric." << endl;
- cout << "You should manually review the output to make sure the part annotations are " << endl;
- cout << "labeled as you expect." << endl;
- }
-
-
- return best_assignment;
-}
-
-// ----------------------------------------------------------------------------------------
-
-std::map<string,dpoint> normalized_parts (
- const image_dataset_metadata::box& b
-)
-{
- auto tform = dlib::impl::normalizing_tform(b.rect);
- std::map<string,dpoint> temp;
- for (auto& p : b.parts)
- temp[p.first] = tform(p.second);
- return temp;
-}
-
-// ----------------------------------------------------------------------------------------
-
-std::map<string,dpoint> average_parts (
- const image_dataset_metadata::dataset& data
-)
-/*!
- ensures
- - returns the average part layout over all objects in data. This is done by
- centering the parts inside their rects and then averaging all the objects.
-!*/
-{
- std::map<string,dpoint> psum;
- std::map<string,double> pcnt;
- for (auto& image : data.images)
- {
- for (auto& box : image.boxes)
- {
- for (auto& p : normalized_parts(box))
- {
- psum[p.first] += p.second;
- pcnt[p.first] += 1;
- }
- }
- }
-
- // make into an average
- for (auto& p : psum)
- p.second /= pcnt[p.first];
-
- return psum;
-}
-
-// ----------------------------------------------------------------------------------------
-
-void make_part_labeling_match_target_dataset (
- const image_dataset_metadata::dataset& target,
- image_dataset_metadata::dataset& data
-)
-/*!
- This function tries to adjust the part labels in data so that the average part layout
- in data is the same as target, according to the string labels. Therefore, it doesn't
- adjust part positions, instead it changes the string labels on the parts to achieve
- this. This really only makes sense when you flipped a dataset that contains left-right
- symmetric objects and you want to remap the part labels of the flipped data so that
- they match the unflipped data's annotation scheme.
-!*/
-{
- auto target_parts = average_parts(target);
- auto data_parts = average_parts(data);
-
- // Convert to a form align_points() understands. We also need to keep track of the
- // labels for later.
- std::vector<dpoint> from, to;
- std::vector<string> from_labels, to_labels;
- for (auto& p : target_parts)
- {
- from_labels.emplace_back(p.first);
- from.emplace_back(p.second);
- }
- for (auto& p : data_parts)
- {
- to_labels.emplace_back(p.first);
- to.emplace_back(p.second);
- }
-
- auto assignment = align_points(from, to);
- // so now we know that from_labels[i] should replace to_labels[assignment[i]]
- std::map<string,string> label_mapping;
- for (size_t i = 0; i < assignment.size(); ++i)
- label_mapping[to_labels[assignment[i]]] = from_labels[i];
-
- // now apply the label mapping to the dataset
- for (auto& image : data.images)
- {
- for (auto& box : image.boxes)
- {
- std::map<string,point> temp;
- for (auto& p : box.parts)
- temp[label_mapping[p.first]] = p.second;
- box.parts = std::move(temp);
- }
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
-void flip_dataset(const command_line_parser& parser)
-{
- image_dataset_metadata::dataset metadata, orig_metadata;
- string datasource;
- if (parser.option("flip"))
- datasource = parser.option("flip").argument();
- else
- datasource = parser.option("flip-basic").argument();
- load_image_dataset_metadata(metadata,datasource);
- orig_metadata = metadata;
-
- // Set the current directory to be the one that contains the
- // metadata file. We do this because the file might contain
- // file paths which are relative to this folder.
- set_current_dir(get_parent_directory(file(datasource)));
-
- const string metadata_filename = get_parent_directory(file(datasource)).full_name() +
- directory::get_separator() + "flipped_" + file(datasource).name();
-
-
- array2d<rgb_pixel> img, temp;
- for (unsigned long i = 0; i < metadata.images.size(); ++i)
- {
- file f(metadata.images[i].filename);
- string filename = get_parent_directory(f).full_name() + directory::get_separator() + "flipped_" + to_png_name(f.name());
-
- load_image(img, metadata.images[i].filename);
- flip_image_left_right(img, temp);
- if (parser.option("jpg"))
- {
- filename = to_jpg_name(filename);
- save_jpeg(temp, filename,JPEG_QUALITY);
- }
- else
- {
- save_png(temp, filename);
- }
-
- for (unsigned long j = 0; j < metadata.images[i].boxes.size(); ++j)
- {
- metadata.images[i].boxes[j].rect = impl::flip_rect_left_right(metadata.images[i].boxes[j].rect, get_rect(img));
-
- // flip all the object parts
- for (auto& part : metadata.images[i].boxes[j].parts)
- {
- part.second = impl::flip_rect_left_right(rectangle(part.second,part.second), get_rect(img)).tl_corner();
- }
- }
-
- metadata.images[i].filename = filename;
- }
-
- if (!parser.option("flip-basic"))
- make_part_labeling_match_target_dataset(orig_metadata, metadata);
-
- save_image_dataset_metadata(metadata, metadata_filename);
-}
-
-// ----------------------------------------------------------------------------------------
-