Program Listing for File layered_maps.cpp
↰ Return to documentation for file (src/tuw_geometry/layered_maps.cpp
)
/***************************************************************************
* Software License Agreement (BSD License) *
* Copyright (C) 2016 by Horatiu George Todoran <todorangrg@gmail.com> *
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright *
* notice, this list of conditions and the following disclaimer. *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in *
* the documentation and/or other materials provided with the *
* distribution. *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived *
* from this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS *
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE *
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, *
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, *
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; *
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER *
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT *
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY *
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
* POSSIBILITY OF SUCH DAMAGE. *
***************************************************************************/
#include <opencv2/core/core_c.h>
#include <opencv2/core/core.hpp>
#include <opencv2/opencv.hpp>
#include <tuw_geometry/layered_maps.hpp>
using namespace tuw;
using namespace std;
using namespace cv;
LayeredMaps::LayeredMaps() {}
void LayeredMaps::initLayers(
int width_pixel, int height_pixel, double min_x, double max_x, double min_y, double max_y,
double rotation)
{
init(width_pixel, height_pixel, min_x, max_x, min_y, max_y, rotation);
initLayers();
}
size_t LayeredMaps::sizeLayers() const {return mapLayers_.size();}
void LayeredMaps::resizeLayers(const size_t & _n) {mapLayers_.resize(_n);}
void LayeredMaps::initLayers()
{
for (size_t i = 0; i < mapLayers_.size(); i++) {
mapLayers_[i].create(width(), height(), CV_32FC1);
clearLayer(i);
}
}
void LayeredMaps::clearLayers()
{
for (size_t i = 0; i < mapLayers_.size(); i++) {
clearLayer(i);
}
}
void LayeredMaps::clearLayer(const size_t & _layer) {mapLayers_[_layer].setTo(1);}
cv::Mat & LayeredMaps::mapLayer(const size_t & _layer) {return mapLayers_[_layer];}
const cv::Mat & LayeredMaps::mapLayer(const size_t & _layer) const {return mapLayers_[_layer];}
double LayeredMaps::getVal(
const size_t & _layer, const Point2D & _worldPos, Interpolation _interpolationType) const
{
double retVal = -100;
Point2D mapPos = w2m(_worldPos);
if (!mapPos.inside(0, 0, mapLayer(_layer).rows - 1, mapLayer(_layer).cols - 1)) {
return retVal;
}
const double mapPos_row_d = mapPos.y(), mapPos_col_d = mapPos.x();
const int mapPos_row_i = int(mapPos_row_d), mapPos_col_i = int(mapPos_col_d);
switch (_interpolationType) {
case SIMPLE:
retVal = mapLayer(_layer).at<float_t>(mapPos_row_i, mapPos_col_i);
break;
case BILINEAR:
//if((mapPos_y_i+1 >= mapLayer(layer).rows)||(mapPos_x_i+1 >= mapLayer(layer).cols)||(mapPos_y_i <0)||(mapPos_x_i <0)){throw 0;}
const double f00 = mapLayer(_layer).at<float_t>(mapPos_row_i, mapPos_col_i);
const double f10 = mapLayer(_layer).at<float_t>(mapPos_row_i + 1, mapPos_col_i);
const double f01 = mapLayer(_layer).at<float_t>(mapPos_row_i, mapPos_col_i + 1);
const double f11 = mapLayer(_layer).at<float_t>(mapPos_row_i + 1, mapPos_col_i + 1);
const double mapPosRed_row = mapPos_row_d - mapPos_row_i,
mapPosRed_col = mapPos_col_d - mapPos_col_i;
retVal = f00 * (1 - mapPosRed_row) * (1 - mapPosRed_col) +
f10 * mapPosRed_row * (1 - mapPosRed_col) +
f01 * (1 - mapPosRed_row) * mapPosRed_col + f11 * mapPosRed_row * mapPosRed_col;
break;
}
return retVal;
}
float distance2probabilitySigmoid(float d, float threshold)
{
float p = 0;
if (d < threshold) {
p = tanh((2 * M_PI * -d) / threshold + M_PI) * 0.5 + 0.5;
}
return p;
}
float distance2probabilityTriangle(float d, float threshold)
{
float p = 0;
if (d < threshold) {
p = 1. - d / threshold;
}
return p;
}
void LayeredMaps::computeDistanceField(
Mat & _mDst, vector<Point2D> & _pSrc, const double & _radius, bool _flipDistance,
bool connectPoints) const
{
Mat srcMap;
srcMap.create(width(), height(), CV_32FC1);
srcMap.setTo(1);
Scalar colour(0);
if (connectPoints) {
for (size_t i = 1; i < _pSrc.size(); i++) {
line(srcMap, _pSrc[i - 1], _pSrc[i], colour, 8);
}
} else {
for (size_t i = 0; i < _pSrc.size(); i++) {
circle(srcMap, _pSrc[i], 1, colour, 1, 8);
}
}
computeDistanceField(_mDst, srcMap, _radius, _flipDistance);
}
void LayeredMaps::computeDistanceField(
Mat & _mDst, Mat & _mSrc, const double & _radius, bool _flipDistance) const
{
Mat srcMap;
_mSrc.convertTo(srcMap, CV_8U);
int maskSize0 = cv::DIST_MASK_PRECISE;
int voronoiType = -1;
int distType0 = cv::DIST_L2; //CV_DIST_L1;
int maskSize = voronoiType >= 0 ? cv::DIST_MASK_5 : maskSize0;
int distType = voronoiType >= 0 ? cv::DIST_L2 : distType0;
Mat destMap_f, labels;
// destMap_f.create ( width(), height(), CV_32F );
if (voronoiType < 0) {
cv::distanceTransform(srcMap, destMap_f, distType, maskSize);
} else {
cv::distanceTransform(srcMap, destMap_f, labels, distType, maskSize, voronoiType);
}
// destMap_f.convertTo(destMap_ui, CV_8U );
CV_Assert(destMap_f.depth() == CV_32F);
int channels = destMap_f.channels();
int nRows = destMap_f.rows;
int nCols = destMap_f.cols * channels;
if (destMap_f.isContinuous()) {
nCols *= nRows;
nRows = 1;
}
float threshold = _radius * scale_x();
float_t * p_d;
for (int i = 0; i < nRows; ++i) {
p_d = destMap_f.ptr<float_t>(i);
for (int j = 0; j < nCols; ++j) {
if (_flipDistance) {
p_d[j] = (float_t)(distance2probabilityTriangle(p_d[j], threshold));
} else {
p_d[j] = (float_t)((1. - distance2probabilityTriangle(p_d[j], threshold)));
}
}
}
if ((_mDst.channels() != 1) && (_mDst.channels() != 5)) {
cvtColor(destMap_f, _mDst, cv::COLOR_GRAY2BGR);
} else {
_mDst = destMap_f;
}
}