in src/io/image_det_aug_default.cc [509:670]
cv::Mat Process(const cv::Mat &src, std::vector<float> *label,
common::RANDOM_ENGINE *prnd) override {
using mshadow::index_t;
cv::Mat res;
if (param_.resize != -1) {
int new_height, new_width;
if (src.rows > src.cols) {
new_height = param_.resize*src.rows/src.cols;
new_width = param_.resize;
} else {
new_height = param_.resize;
new_width = param_.resize*src.cols/src.rows;
}
int interpolation_method = GetInterMethod(param_.inter_method,
src.cols, src.rows, new_width, new_height, prnd);
cv::resize(src, res, cv::Size(new_width, new_height),
0, 0, interpolation_method);
} else {
res = src;
}
// build a helper class for processing labels
ImageDetLabel det_label(*label);
// random engine
std::uniform_real_distribution<float> rand_uniform(0, 1);
// color space augmentation
if (param_.random_hue_prob > 0.f || param_.random_saturation_prob > 0.f ||
param_.random_illumination_prob > 0.f || param_.random_contrast_prob > 0.f) {
std::uniform_real_distribution<float> uniform_range(-1.f, 1.f);
int h = uniform_range(*prnd) * param_.max_random_hue;
int s = uniform_range(*prnd) * param_.max_random_saturation;
int l = uniform_range(*prnd) * param_.max_random_illumination;
float c = uniform_range(*prnd) * param_.max_random_contrast;
h = rand_uniform(*prnd) < param_.random_hue_prob ? h : 0;
s = rand_uniform(*prnd) < param_.random_saturation_prob ? s : 0;
l = rand_uniform(*prnd) < param_.random_illumination_prob ? l : 0;
c = rand_uniform(*prnd) < param_.random_contrast_prob ? c : 0;
if (h != 0 || s != 0 || l != 0) {
int temp[3] = {h, l, s};
int limit[3] = {180, 255, 255};
cv::cvtColor(res, res, CV_BGR2HLS);
for (int i = 0; i < res.rows; ++i) {
for (int j = 0; j < res.cols; ++j) {
for (int k = 0; k < 3; ++k) {
int v = res.at<cv::Vec3b>(i, j)[k];
v += temp[k];
v = std::max(0, std::min(limit[k], v));
res.at<cv::Vec3b>(i, j)[k] = v;
}
}
}
cv::cvtColor(res, res, CV_HLS2BGR);
}
if (std::fabs(c) > 1e-3) {
cv::Mat tmp = res;
tmp.convertTo(res, -1, c + 1.f, 0);
}
}
// random mirror logic
if (param_.rand_mirror_prob > 0 && rand_uniform(*prnd) < param_.rand_mirror_prob) {
if (det_label.TryMirror()) {
// flip image
cv::flip(res, temp_, 1);
res = temp_;
}
}
// random padding logic
if (param_.rand_pad_prob > 0 && param_.max_pad_scale > 1.f) {
if (rand_uniform(*prnd) < param_.rand_pad_prob) {
Rect pad_box = GeneratePadBox(param_.max_pad_scale, prnd);
if (pad_box.area() > 0) {
if (det_label.TryPad(pad_box)) {
// pad image
temp_ = res;
int left = static_cast<int>(-pad_box.x * res.cols);
int top = static_cast<int>(-pad_box.y * res.rows);
int right = static_cast<int>((pad_box.width + pad_box.x - 1) * res.cols);
int bot = static_cast<int>((pad_box.height + pad_box.y - 1) * res.rows);
cv::copyMakeBorder(temp_, res, top, bot, left, right, cv::BORDER_ISOLATED,
cv::Scalar(param_.fill_value, param_.fill_value, param_.fill_value));
}
}
}
}
// random crop logic
if (param_.rand_crop_prob > 0 && param_.num_crop_sampler > 0) {
if (rand_uniform(*prnd) < param_.rand_crop_prob) {
// random crop sampling logic: randomly pick a sampler, return if success
// continue to next sampler if failed(exceed max_trial)
// return original sample if every sampler has failed
std::vector<int> indices(param_.num_crop_sampler);
for (int i = 0; i < param_.num_crop_sampler; ++i) {
indices[i] = i;
}
std::shuffle(indices.begin(), indices.end(), *prnd);
int num_processed = 0;
for (auto idx : indices) {
if (num_processed > 0) break;
for (int t = 0; t < param_.max_crop_trials[idx]; ++t) {
Rect crop_box = GenerateCropBox(param_.min_crop_scales[idx],
param_.max_crop_scales[idx], param_.min_crop_aspect_ratios[idx],
param_.max_crop_aspect_ratios[idx], prnd,
static_cast<float>(res.cols) / res.rows);
if (det_label.TryCrop(crop_box, param_.min_crop_overlaps[idx],
param_.max_crop_overlaps[idx], param_.min_crop_sample_coverages[idx],
param_.max_crop_sample_coverages[idx], param_.min_crop_object_coverages[idx],
param_.max_crop_object_coverages[idx], param_.crop_emit_mode,
param_.emit_overlap_thresh)) {
++num_processed;
// crop image
int left = static_cast<int>(crop_box.x * res.cols);
int top = static_cast<int>(crop_box.y * res.rows);
int width = static_cast<int>(crop_box.width * res.cols);
int height = static_cast<int>(crop_box.height * res.rows);
res = res(cv::Rect(left, top, width, height));
break;
}
}
}
}
}
if (image_det_aug_default_enum::kForce == param_.resize_mode) {
// force resize to specified data_shape, regardless of aspect ratio
int new_height = param_.data_shape[1];
int new_width = param_.data_shape[2];
int interpolation_method = GetInterMethod(param_.inter_method,
res.cols, res.rows, new_width, new_height, prnd);
cv::resize(res, res, cv::Size(new_width, new_height),
0, 0, interpolation_method);
} else if (image_det_aug_default_enum::kShrink == param_.resize_mode) {
// try to keep original size, shrink if too large
float h = param_.data_shape[1];
float w = param_.data_shape[2];
if (res.rows > h || res.cols > w) {
float ratio = std::min(h / res.rows, w / res.cols);
int new_height = ratio * res.rows;
int new_width = ratio * res.cols;
int interpolation_method = GetInterMethod(param_.inter_method,
res.cols, res.rows, new_width, new_height, prnd);
cv::resize(res, res, cv::Size(new_width, new_height),
0, 0, interpolation_method);
}
} else if (image_det_aug_default_enum::kFit == param_.resize_mode) {
float h = param_.data_shape[1];
float w = param_.data_shape[2];
float ratio = std::min(h / res.rows, w / res.cols);
int new_height = ratio * res.rows;
int new_width = ratio * res.cols;
int interpolation_method = GetInterMethod(param_.inter_method,
res.cols, res.rows, new_width, new_height, prnd);
cv::resize(res, res, cv::Size(new_width, new_height),
0, 0, interpolation_method);
}
*label = det_label.ToArray(); // put back processed labels
return res;
}