OSVR-Core
RealtimeLaplacian.h
Go to the documentation of this file.
1 
11 // Copyright 2016 Sensics, Inc.
12 //
13 // Licensed under the Apache License, Version 2.0 (the "License");
14 // you may not use this file except in compliance with the License.
15 // You may obtain a copy of the License at
16 //
17 // http://www.apache.org/licenses/LICENSE-2.0
18 //
19 // Unless required by applicable law or agreed to in writing, software
20 // distributed under the License is distributed on an "AS IS" BASIS,
21 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 // See the License for the specific language governing permissions and
23 // limitations under the License.
24 
26 // Portions based on modules/imgproc/src/deriv.cpp from the OpenCV 2.4 branch,
27 // with this license header:
29 // clang-format off
30 
31 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
32 //
33 // By downloading, copying, installing or using the software you agree to this license.
34 // If you do not agree to this license, do not download, install,
35 // copy or use the software.
36 //
37 //
38 // Intel License Agreement
39 // For Open Source Computer Vision Library
40 //
41 // Copyright (C) 2000, Intel Corporation, all rights reserved.
42 // Third party copyrights are property of their respective owners.
43 //
44 // Redistribution and use in source and binary forms, with or without modification,
45 // are permitted provided that the following conditions are met:
46 //
47 // * Redistribution's of source code must retain the above copyright notice,
48 // this list of conditions and the following disclaimer.
49 //
50 // * Redistribution's in binary form must reproduce the above copyright notice,
51 // this list of conditions and the following disclaimer in the documentation
52 // and/or other materials provided with the distribution.
53 //
54 // * The name of Intel Corporation may not be used to endorse or promote products
55 // derived from this software without specific prior written permission.
56 //
57 // This software is provided by the copyright holders and contributors "as is" and
58 // any express or implied warranties, including, but not limited to, the implied
59 // warranties of merchantability and fitness for a particular purpose are disclaimed.
60 // In no event shall the Intel Corporation or contributors be liable for any direct,
61 // indirect, incidental, special, exemplary, or consequential damages
62 // (including, but not limited to, procurement of substitute goods or services;
63 // loss of use, data, or profits; or business interruption) however caused
64 // and on any theory of liability, whether in contract, strict liability,
65 // or tort (including negligence or otherwise) arising in any way out of
66 // the use of this software, even if advised of the possibility of such damage.
67 
68 // clang-format on
69 
70 #ifndef INCLUDED_RealtimeLaplacian_h_GUID_1ECD4EFB_BF33_479D_0ED7_890BF096056E
71 #define INCLUDED_RealtimeLaplacian_h_GUID_1ECD4EFB_BF33_479D_0ED7_890BF096056E
72 
73 // Internal Includes
74 // - none
75 
76 // Library/third-party includes
77 #include <opencv2/core/core.hpp>
78 #include <opencv2/imgproc/imgproc.hpp>
79 
80 // Standard includes
81 // - none
82 
83 namespace osvr {
84 namespace vbtracker {
85 
90  public:
91  RealtimeLaplacian(int destDepth, int kSize = 3, double scale = 1.,
92  double delta = 0.,
93  int borderType = cv::BORDER_DEFAULT)
94  : kSize_(kSize), destDepth_(destDepth), scale_(scale),
95  delta_(delta), borderType_(borderType) {}
96 
97  void apply(cv::InputArray mySrc, cv::OutputArray myDst) {
98  if (kSize_ == 1 || kSize_ == 3) {
99  // small enough to just use the stock stuff, which doesn't
100  // allocate things
101  cv::Laplacian(mySrc, myDst, destDepth_, kSize_, scale_, delta_,
102  borderType_);
103  return;
104  }
105  cv::Mat src = mySrc.getMat();
106  if (setup_) {
109  setup_ = doesImageMatchCache(src);
110  }
111  if (!setup_) {
114  srcDepth_ = src.depth();
115  srcChannels_ = src.channels();
116  srcCols_ = src.cols;
117  srcRows_ = src.rows;
118  srcType_ = src.type();
120  setupImpl();
121  }
122 
124  myDst.create(src.size(), CV_MAKETYPE(destDepth_, src.channels()));
125 
126  cv::Mat dst = myDst.getMat();
127 
130  int y = fx_->start(src), dsty = 0, dy = 0;
131  fy_->start(src);
132  const uchar *sptr = src.data + y * src.step;
133 
134  for (; dsty < src.rows; sptr += dy0_ * src.step, dsty += dy) {
135  fx_->proceed(sptr, (int)src.step, dy0_, d2x_.data,
136  (int)d2x_.step);
137  dy = fy_->proceed(sptr, (int)src.step, dy0_, d2y_.data,
138  (int)d2y_.step);
139  if (dy > 0) {
142  cv::Mat dstripe = dst.rowRange(dsty, dsty + dy);
143  d2x_.rows = d2y_.rows =
144  dy; // modify the headers, which should work
145  d2x_ += d2y_;
146  d2x_.convertTo(dstripe, destType_, scale_, delta_);
147  }
148  }
149  }
150 
151  private:
152  bool doesImageMatchCache(cv::Mat const &src) const {
154  return (srcDepth_ == src.depth()) &&
155  (srcChannels_ == src.channels()) && (srcCols_ == src.cols) &&
156  (srcRows_ == src.rows) && (srcType_ == src.type());
157  }
158  int ktype() const {
159  return std::max<int>({CV_32F, destDepth_, srcDepth_});
160  }
161  void setupImpl() {
162 
163  int ktype = std::max(CV_32F, std::max(destDepth_, srcDepth_));
164  int wdepth = srcDepth_ == CV_8U && kSize_ <= 5
165  ? CV_16S
166  : srcDepth_ <= CV_32F ? CV_32F : CV_64F;
167  workType_ = CV_MAKETYPE(wdepth, srcChannels_);
168 
169  // internally calls getSobelKernels
170  cv::getDerivKernels(kd_, ks_, 2, 0, kSize_, false, ktype);
171 
172  destType_ = CV_MAKETYPE(destDepth_, srcChannels_);
173  dy0_ =
174  std::min(std::max((int)(STRIPE_SIZE /
175  (cv::getElemSize(srcType_) * srcCols_)),
176  1),
177  srcRows_);
178  fx_ = cv::createSeparableLinearFilter(
179  srcType_, workType_, kd_, ks_, cv::Point(-1, -1), 0,
180  borderType_, borderType_, cv::Scalar());
181  fy_ = cv::createSeparableLinearFilter(
182  srcType_, workType_, ks_, kd_, cv::Point(-1, -1), 0,
183  borderType_, borderType_, cv::Scalar());
184  makeD2mats();
185  setup_ = true;
186  }
187  void makeD2mats() {
188  d2x_ = cv::Mat(dy0_ + kd_.rows - 1, srcCols_, workType_);
189  d2y_ = cv::Mat(dy0_ + kd_.rows - 1, srcCols_, workType_);
190  }
191 
194  const int kSize_;
195  const int destDepth_;
196  const double scale_;
197  const double delta_;
198  const int borderType_;
200 
203  bool setup_ = false;
204 
207  int srcDepth_ = 0;
208  int srcChannels_ = 0;
209  int srcCols_ = 0;
210  int srcRows_ = 0;
211  int srcType_ = 0;
215  int workType_;
216  int destType_;
217  cv::Mat kd_;
218  cv::Mat ks_;
219  int dy0_;
220  cv::Ptr<cv::FilterEngine> fx_;
221  cv::Ptr<cv::FilterEngine> fy_;
222  cv::Mat d2x_;
223  cv::Mat d2y_;
225 
227  static const size_t STRIPE_SIZE = 1 << 14;
228  };
229 
230 } // namespace vbtracker
231 } // namespace osvr
232 #endif // INCLUDED_RealtimeLaplacian_h_GUID_1ECD4EFB_BF33_479D_0ED7_890BF096056E
The main namespace for all C++ elements of the framework, internal and external.
Definition: namespace_osvr.dox:3
A class designed for real-time use of a Laplacian on similar images over and over, based on the OpenCV implementation but avoiding duplicate work and using persistent temporary storage when possible.
Definition: RealtimeLaplacian.h:89
void apply(cv::InputArray mySrc, cv::OutputArray myDst)
Definition: RealtimeLaplacian.h:97
double Scalar
Common scalar type.
Definition: FlexibleKalmanBase.h:48