Commit 1bad9a05582061754ce14bffce63987248f14e06
1 parent
3fbc93fe
Add a transform that overlays an image adjacent to some rectangle
Showing
1 changed file
with
96 additions
and
0 deletions
openbr/plugins/draw.cpp
| @@ -15,6 +15,8 @@ | @@ -15,6 +15,8 @@ | ||
| 15 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | 15 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
| 16 | 16 | ||
| 17 | #include <opencv2/highgui/highgui.hpp> | 17 | #include <opencv2/highgui/highgui.hpp> |
| 18 | +#include <opencv2/imgproc/imgproc.hpp> | ||
| 19 | +#include <vector> | ||
| 18 | #include "openbr_internal.h" | 20 | #include "openbr_internal.h" |
| 19 | #include "openbr/core/opencvutils.h" | 21 | #include "openbr/core/opencvutils.h" |
| 20 | 22 | ||
| @@ -248,6 +250,100 @@ class MeanTransform : public Transform | @@ -248,6 +250,100 @@ class MeanTransform : public Transform | ||
| 248 | 250 | ||
| 249 | BR_REGISTER(Transform, MeanTransform) | 251 | BR_REGISTER(Transform, MeanTransform) |
| 250 | 252 | ||
| 253 | +/*! | ||
| 254 | + * \ingroup transforms | ||
| 255 | + * \brief Load the image named in the specified property, draw it on the current matrix adjacent to the rect specified in the other property. | ||
| 256 | + * \author Charles Otto \cite caotto | ||
| 257 | + */ | ||
| 258 | +class AdjacentOverlayTransform : public Transform | ||
| 259 | +{ | ||
| 260 | + Q_OBJECT | ||
| 261 | + | ||
| 262 | + Q_PROPERTY(QString imgName READ get_imgName WRITE set_imgName RESET reset_imgName STORED false) | ||
| 263 | + Q_PROPERTY(QString targetName READ get_targetName WRITE set_targetName RESET reset_targetName STORED false) | ||
| 264 | + BR_PROPERTY(QString, imgName, "") | ||
| 265 | + BR_PROPERTY(QString, targetName, "") | ||
| 266 | + | ||
| 267 | + QSharedPointer<Transform> opener; | ||
| 268 | + void project(const Template &src, Template &dst) const | ||
| 269 | + { | ||
| 270 | + dst = src; | ||
| 271 | + if (imgName.isEmpty() || targetName.isEmpty() || !dst.file.contains(imgName) || !dst.file.contains(targetName)) | ||
| 272 | + return; | ||
| 273 | + | ||
| 274 | + QString im_name = src.file.get<QString>(imgName); | ||
| 275 | + QRectF target_location = src.file.get<QRectF>(targetName); | ||
| 276 | + Template temp_im; | ||
| 277 | + opener->project(File(im_name), temp_im); | ||
| 278 | + cv::Mat im = temp_im.m(); | ||
| 279 | + | ||
| 280 | + // match width with target region | ||
| 281 | + qreal target_width = target_location.width(); | ||
| 282 | + qreal current_width = im.cols; | ||
| 283 | + qreal current_height = im.rows; | ||
| 284 | + | ||
| 285 | + qreal aspect_ratio = current_height / current_width; | ||
| 286 | + qreal target_height = target_width * aspect_ratio; | ||
| 287 | + | ||
| 288 | + cv::resize(im, im, cv::Size(target_width, target_height)); | ||
| 289 | + | ||
| 290 | + cv::Rect clip_roi; | ||
| 291 | + clip_roi.x = 0; | ||
| 292 | + clip_roi.y = 0; | ||
| 293 | + clip_roi.width = im.cols; | ||
| 294 | + clip_roi.height= im.rows; | ||
| 295 | + | ||
| 296 | + int half_width = src.m().cols / 2; | ||
| 297 | + int out_x = 0; | ||
| 298 | + cv::Rect target_roi; | ||
| 299 | + // Place left | ||
| 300 | + if (target_location.center().rx() > half_width) { | ||
| 301 | + out_x = target_location.left() - im.cols; | ||
| 302 | + if (out_x < 0) { | ||
| 303 | + clip_roi.width += out_x; | ||
| 304 | + out_x = 0; | ||
| 305 | + } | ||
| 306 | + } | ||
| 307 | + // place right | ||
| 308 | + else { | ||
| 309 | + out_x = target_location.right(); | ||
| 310 | + int high = out_x + im.cols; | ||
| 311 | + if (high >= src.m().cols) { | ||
| 312 | + clip_roi.width -= high - src.m().cols + 1; | ||
| 313 | + } | ||
| 314 | + } | ||
| 315 | + target_roi.x = out_x; | ||
| 316 | + target_roi.width = clip_roi.width; | ||
| 317 | + target_roi.y = target_location.top(); | ||
| 318 | + target_roi.height = clip_roi.height; | ||
| 319 | + | ||
| 320 | + im = im(clip_roi); | ||
| 321 | + | ||
| 322 | + cv::Mat outIm = dst.m(); | ||
| 323 | + std::vector<cv::Mat> channels; | ||
| 324 | + cv::split(outIm, channels); | ||
| 325 | + | ||
| 326 | + std::vector<cv::Mat> patch_channels; | ||
| 327 | + cv::split(im, patch_channels); | ||
| 328 | + | ||
| 329 | + for (int i=0; i < channels.size(); i++) | ||
| 330 | + { | ||
| 331 | + cv::addWeighted(channels[i](target_roi), 0, patch_channels[i % patch_channels.size()], 1, 0,channels[i](target_roi)); | ||
| 332 | + } | ||
| 333 | + cv::merge(channels, outIm); | ||
| 334 | + dst.m() = outIm; | ||
| 335 | + } | ||
| 336 | + | ||
| 337 | + void init() | ||
| 338 | + { | ||
| 339 | + opener = br::Transform::fromAlgorithm("Cache(Open)"); | ||
| 340 | + | ||
| 341 | + } | ||
| 342 | + | ||
| 343 | +}; | ||
| 344 | + | ||
| 345 | +BR_REGISTER(Transform, AdjacentOverlayTransform) | ||
| 346 | + | ||
| 251 | // TODO: re-implement EditTransform using Qt | 347 | // TODO: re-implement EditTransform using Qt |
| 252 | #if 0 | 348 | #if 0 |
| 253 | /*! | 349 | /*! |