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 | 15 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
| 16 | 16 | |
| 17 | 17 | #include <opencv2/highgui/highgui.hpp> |
| 18 | +#include <opencv2/imgproc/imgproc.hpp> | |
| 19 | +#include <vector> | |
| 18 | 20 | #include "openbr_internal.h" |
| 19 | 21 | #include "openbr/core/opencvutils.h" |
| 20 | 22 | |
| ... | ... | @@ -248,6 +250,100 @@ class MeanTransform : public Transform |
| 248 | 250 | |
| 249 | 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 | 347 | // TODO: re-implement EditTransform using Qt |
| 252 | 348 | #if 0 |
| 253 | 349 | /*! | ... | ... |