merge with origin
This commit is contained in:
@@ -115,7 +115,7 @@ void computeProjectiveMatrix( const Mat& ksi, Mat& Rt )
|
||||
{
|
||||
CV_Assert( ksi.size() == Size(1,6) && ksi.type() == CV_64FC1 );
|
||||
|
||||
#if defined(HAVE_EIGEN) && EIGEN_WORLD_VERSION == 3
|
||||
#if defined(HAVE_EIGEN) && EIGEN_WORLD_VERSION == 3 && (!defined _MSC_VER || !defined _M_X64 || _MSC_VER > 1500)
|
||||
const double* ksi_ptr = reinterpret_cast<const double*>(ksi.ptr(0));
|
||||
Eigen::Matrix<double,4,4> twist, g;
|
||||
twist << 0., -ksi_ptr[2], ksi_ptr[1], ksi_ptr[3],
|
||||
|
@@ -25,7 +25,7 @@ endif()
|
||||
|
||||
if(HAVE_CUDA)
|
||||
ocv_include_directories("${OpenCV_SOURCE_DIR}/modules/gpu/include")
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef)
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef -Wshadow)
|
||||
endif()
|
||||
|
||||
file(GLOB lib_cuda_hdrs "include/opencv2/${name}/cuda/*.hpp" "include/opencv2/${name}/cuda/*.h")
|
||||
|
@@ -1355,7 +1355,7 @@ The method copies the matrix data to another matrix. Before copying the data, th
|
||||
|
||||
so that the destination matrix is reallocated if needed. While ``m.copyTo(m);`` works flawlessly, the function does not handle the case of a partial overlap between the source and the destination matrices.
|
||||
|
||||
When the operation mask is specified, and the ``Mat::create`` call shown above reallocated the matrix, the newly allocated matrix is initialized with all zeros before copying the data.
|
||||
When the operation mask is specified, if the ``Mat::create`` call shown above reallocates the matrix, the newly allocated matrix is initialized with all zeros before copying the data.
|
||||
|
||||
.. _Mat::convertTo:
|
||||
|
||||
|
509
modules/core/include/opencv2/core/affine.hpp
Normal file
509
modules/core/include/opencv2/core/affine.hpp
Normal file
@@ -0,0 +1,509 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's 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.
|
||||
//
|
||||
// * The name of the copyright holders may not 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 Intel Corporation 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.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __OPENCV_CORE_AFFINE3_HPP__
|
||||
#define __OPENCV_CORE_AFFINE3_HPP__
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <opencv2/core/core.hpp>
|
||||
|
||||
namespace cv
|
||||
{
|
||||
template<typename T>
|
||||
class Affine3
|
||||
{
|
||||
public:
|
||||
typedef T float_type;
|
||||
typedef Matx<float_type, 3, 3> Mat3;
|
||||
typedef Matx<float_type, 4, 4> Mat4;
|
||||
typedef Vec<float_type, 3> Vec3;
|
||||
|
||||
Affine3();
|
||||
|
||||
//Augmented affine matrix
|
||||
Affine3(const Mat4& affine);
|
||||
|
||||
//Rotation matrix
|
||||
Affine3(const Mat3& R, const Vec3& t = Vec3::all(0));
|
||||
|
||||
//Rodrigues vector
|
||||
Affine3(const Vec3& rvec, const Vec3& t = Vec3::all(0));
|
||||
|
||||
//Combines all contructors above. Supports 4x4, 4x3, 3x3, 1x3, 3x1 sizes of data matrix
|
||||
explicit Affine3(const Mat& data, const Vec3& t = Vec3::all(0));
|
||||
|
||||
//From 16th element array
|
||||
explicit Affine3(const float_type* vals);
|
||||
|
||||
static Affine3 Identity();
|
||||
|
||||
//Rotation matrix
|
||||
void rotation(const Mat3& R);
|
||||
|
||||
//Rodrigues vector
|
||||
void rotation(const Vec3& rvec);
|
||||
|
||||
//Combines rotation methods above. Suports 3x3, 1x3, 3x1 sizes of data matrix;
|
||||
void rotation(const Mat& data);
|
||||
|
||||
void linear(const Mat3& L);
|
||||
void translation(const Vec3& t);
|
||||
|
||||
Mat3 rotation() const;
|
||||
Mat3 linear() const;
|
||||
Vec3 translation() const;
|
||||
|
||||
//Rodrigues vector
|
||||
Vec3 rvec() const;
|
||||
|
||||
Affine3 inv(int method = cv::DECOMP_SVD) const;
|
||||
|
||||
// a.rotate(R) is equivalent to Affine(R, 0) * a;
|
||||
Affine3 rotate(const Mat3& R) const;
|
||||
|
||||
// a.rotate(R) is equivalent to Affine(rvec, 0) * a;
|
||||
Affine3 rotate(const Vec3& rvec) const;
|
||||
|
||||
// a.translate(t) is equivalent to Affine(E, t) * a;
|
||||
Affine3 translate(const Vec3& t) const;
|
||||
|
||||
// a.concatenate(affine) is equivalent to affine * a;
|
||||
Affine3 concatenate(const Affine3& affine) const;
|
||||
|
||||
template <typename Y> operator Affine3<Y>() const;
|
||||
|
||||
template <typename Y> Affine3<Y> cast() const;
|
||||
|
||||
Mat4 matrix;
|
||||
|
||||
#if defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H
|
||||
Affine3(const Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>& affine);
|
||||
Affine3(const Eigen::Transform<T, 3, Eigen::Affine>& affine);
|
||||
operator Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>() const;
|
||||
operator Eigen::Transform<T, 3, Eigen::Affine>() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
template<typename T> static
|
||||
Affine3<T> operator*(const Affine3<T>& affine1, const Affine3<T>& affine2);
|
||||
|
||||
template<typename T, typename V> static
|
||||
V operator*(const Affine3<T>& affine, const V& vector);
|
||||
|
||||
typedef Affine3<float> Affine3f;
|
||||
typedef Affine3<double> Affine3d;
|
||||
|
||||
static Vec3f operator*(const Affine3f& affine, const Vec3f& vector);
|
||||
static Vec3d operator*(const Affine3d& affine, const Vec3d& vector);
|
||||
|
||||
template<typename _Tp> class DataType< Affine3<_Tp> >
|
||||
{
|
||||
public:
|
||||
typedef Affine3<_Tp> value_type;
|
||||
typedef Affine3<typename DataType<_Tp>::work_type> work_type;
|
||||
typedef _Tp channel_type;
|
||||
|
||||
enum { generic_type = 0,
|
||||
depth = DataType<channel_type>::depth,
|
||||
channels = 16,
|
||||
fmt = DataType<channel_type>::fmt + ((channels - 1) << 8),
|
||||
type = CV_MAKETYPE(depth, channels)
|
||||
};
|
||||
|
||||
typedef Vec<channel_type, channels> vec_type;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
/// Implementaiton
|
||||
|
||||
template<typename T> inline
|
||||
cv::Affine3<T>::Affine3()
|
||||
: matrix(Mat4::eye())
|
||||
{}
|
||||
|
||||
template<typename T> inline
|
||||
cv::Affine3<T>::Affine3(const Mat4& affine)
|
||||
: matrix(affine)
|
||||
{}
|
||||
|
||||
template<typename T> inline
|
||||
cv::Affine3<T>::Affine3(const Mat3& R, const Vec3& t)
|
||||
{
|
||||
rotation(R);
|
||||
translation(t);
|
||||
matrix.val[12] = matrix.val[13] = matrix.val[14] = 0;
|
||||
matrix.val[15] = 1;
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
cv::Affine3<T>::Affine3(const Vec3& _rvec, const Vec3& t)
|
||||
{
|
||||
rotation(_rvec);
|
||||
translation(t);
|
||||
matrix.val[12] = matrix.val[13] = matrix.val[14] = 0;
|
||||
matrix.val[15] = 1;
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
cv::Affine3<T>::Affine3(const cv::Mat& data, const Vec3& t)
|
||||
{
|
||||
CV_Assert(data.type() == cv::DataType<T>::type);
|
||||
|
||||
if (data.cols == 4 && data.rows == 4)
|
||||
{
|
||||
data.copyTo(matrix);
|
||||
return;
|
||||
}
|
||||
else if (data.cols == 4 && data.rows == 3)
|
||||
{
|
||||
rotation(data(Rect(0, 0, 3, 3)));
|
||||
translation(data(Rect(3, 0, 1, 3)));
|
||||
return;
|
||||
}
|
||||
|
||||
rotation(data);
|
||||
translation(t);
|
||||
matrix.val[12] = matrix.val[13] = matrix.val[14] = 0;
|
||||
matrix.val[15] = 1;
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
cv::Affine3<T>::Affine3(const float_type* vals) : matrix(vals)
|
||||
{}
|
||||
|
||||
template<typename T> inline
|
||||
cv::Affine3<T> cv::Affine3<T>::Identity()
|
||||
{
|
||||
return Affine3<T>(cv::Affine3<T>::Mat4::eye());
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
void cv::Affine3<T>::rotation(const Mat3& R)
|
||||
{
|
||||
linear(R);
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
void cv::Affine3<T>::rotation(const Vec3& _rvec)
|
||||
{
|
||||
double rx = _rvec[0], ry = _rvec[1], rz = _rvec[2];
|
||||
double theta = std::sqrt(rx*rx + ry*ry + rz*rz);
|
||||
|
||||
if (theta < DBL_EPSILON)
|
||||
rotation(Mat3::eye());
|
||||
else
|
||||
{
|
||||
const double I[] = { 1, 0, 0, 0, 1, 0, 0, 0, 1 };
|
||||
|
||||
double c = std::cos(theta);
|
||||
double s = std::sin(theta);
|
||||
double c1 = 1. - c;
|
||||
double itheta = theta ? 1./theta : 0.;
|
||||
|
||||
rx *= itheta; ry *= itheta; rz *= itheta;
|
||||
|
||||
double rrt[] = { rx*rx, rx*ry, rx*rz, rx*ry, ry*ry, ry*rz, rx*rz, ry*rz, rz*rz };
|
||||
double _r_x_[] = { 0, -rz, ry, rz, 0, -rx, -ry, rx, 0 };
|
||||
Mat3 R;
|
||||
|
||||
// R = cos(theta)*I + (1 - cos(theta))*r*rT + sin(theta)*[r_x]
|
||||
// where [r_x] is [0 -rz ry; rz 0 -rx; -ry rx 0]
|
||||
for(int k = 0; k < 9; ++k)
|
||||
R.val[k] = static_cast<float_type>(c*I[k] + c1*rrt[k] + s*_r_x_[k]);
|
||||
|
||||
rotation(R);
|
||||
}
|
||||
}
|
||||
|
||||
//Combines rotation methods above. Suports 3x3, 1x3, 3x1 sizes of data matrix;
|
||||
template<typename T> inline
|
||||
void cv::Affine3<T>::rotation(const cv::Mat& data)
|
||||
{
|
||||
CV_Assert(data.type() == cv::DataType<T>::type);
|
||||
|
||||
if (data.cols == 3 && data.rows == 3)
|
||||
{
|
||||
Mat3 R;
|
||||
data.copyTo(R);
|
||||
rotation(R);
|
||||
}
|
||||
else if ((data.cols == 3 && data.rows == 1) || (data.cols == 1 && data.rows == 3))
|
||||
{
|
||||
Vec3 _rvec;
|
||||
data.reshape(1, 3).copyTo(_rvec);
|
||||
rotation(_rvec);
|
||||
}
|
||||
else
|
||||
CV_Assert(!"Input marix can be 3x3, 1x3 or 3x1");
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
void cv::Affine3<T>::linear(const Mat3& L)
|
||||
{
|
||||
matrix.val[0] = L.val[0]; matrix.val[1] = L.val[1]; matrix.val[ 2] = L.val[2];
|
||||
matrix.val[4] = L.val[3]; matrix.val[5] = L.val[4]; matrix.val[ 6] = L.val[5];
|
||||
matrix.val[8] = L.val[6]; matrix.val[9] = L.val[7]; matrix.val[10] = L.val[8];
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
void cv::Affine3<T>::translation(const Vec3& t)
|
||||
{
|
||||
matrix.val[3] = t[0]; matrix.val[7] = t[1]; matrix.val[11] = t[2];
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
typename cv::Affine3<T>::Mat3 cv::Affine3<T>::rotation() const
|
||||
{
|
||||
return linear();
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
typename cv::Affine3<T>::Mat3 cv::Affine3<T>::linear() const
|
||||
{
|
||||
typename cv::Affine3<T>::Mat3 R;
|
||||
R.val[0] = matrix.val[0]; R.val[1] = matrix.val[1]; R.val[2] = matrix.val[ 2];
|
||||
R.val[3] = matrix.val[4]; R.val[4] = matrix.val[5]; R.val[5] = matrix.val[ 6];
|
||||
R.val[6] = matrix.val[8]; R.val[7] = matrix.val[9]; R.val[8] = matrix.val[10];
|
||||
return R;
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
typename cv::Affine3<T>::Vec3 cv::Affine3<T>::translation() const
|
||||
{
|
||||
return Vec3(matrix.val[3], matrix.val[7], matrix.val[11]);
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
typename cv::Affine3<T>::Vec3 cv::Affine3<T>::rvec() const
|
||||
{
|
||||
cv::Vec3d w;
|
||||
cv::Matx33d u, vt, R = rotation();
|
||||
cv::SVD::compute(R, w, u, vt, cv::SVD::FULL_UV + cv::SVD::MODIFY_A);
|
||||
R = u * vt;
|
||||
|
||||
double rx = R.val[7] - R.val[5];
|
||||
double ry = R.val[2] - R.val[6];
|
||||
double rz = R.val[3] - R.val[1];
|
||||
|
||||
double s = std::sqrt((rx*rx + ry*ry + rz*rz)*0.25);
|
||||
double c = (R.val[0] + R.val[4] + R.val[8] - 1) * 0.5;
|
||||
c = c > 1.0 ? 1.0 : c < -1.0 ? -1.0 : c;
|
||||
double theta = acos(c);
|
||||
|
||||
if( s < 1e-5 )
|
||||
{
|
||||
if( c > 0 )
|
||||
rx = ry = rz = 0;
|
||||
else
|
||||
{
|
||||
double t;
|
||||
t = (R.val[0] + 1) * 0.5;
|
||||
rx = std::sqrt(std::max(t, 0.0));
|
||||
t = (R.val[4] + 1) * 0.5;
|
||||
ry = std::sqrt(std::max(t, 0.0)) * (R.val[1] < 0 ? -1.0 : 1.0);
|
||||
t = (R.val[8] + 1) * 0.5;
|
||||
rz = std::sqrt(std::max(t, 0.0)) * (R.val[2] < 0 ? -1.0 : 1.0);
|
||||
|
||||
if( fabs(rx) < fabs(ry) && fabs(rx) < fabs(rz) && (R.val[5] > 0) != (ry*rz > 0) )
|
||||
rz = -rz;
|
||||
theta /= std::sqrt(rx*rx + ry*ry + rz*rz);
|
||||
rx *= theta;
|
||||
ry *= theta;
|
||||
rz *= theta;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
double vth = 1/(2*s);
|
||||
vth *= theta;
|
||||
rx *= vth; ry *= vth; rz *= vth;
|
||||
}
|
||||
|
||||
return cv::Vec3d(rx, ry, rz);
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
cv::Affine3<T> cv::Affine3<T>::inv(int method) const
|
||||
{
|
||||
return matrix.inv(method);
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
cv::Affine3<T> cv::Affine3<T>::rotate(const Mat3& R) const
|
||||
{
|
||||
Mat3 Lc = linear();
|
||||
Vec3 tc = translation();
|
||||
Mat4 result;
|
||||
result.val[12] = result.val[13] = result.val[14] = 0;
|
||||
result.val[15] = 1;
|
||||
|
||||
for(int j = 0; j < 3; ++j)
|
||||
{
|
||||
for(int i = 0; i < 3; ++i)
|
||||
{
|
||||
float_type value = 0;
|
||||
for(int k = 0; k < 3; ++k)
|
||||
value += R(j, k) * Lc(k, i);
|
||||
result(j, i) = value;
|
||||
}
|
||||
|
||||
result(j, 3) = R.row(j).dot(tc.t());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
cv::Affine3<T> cv::Affine3<T>::rotate(const Vec3& _rvec) const
|
||||
{
|
||||
return rotate(Affine3f(_rvec).rotation());
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
cv::Affine3<T> cv::Affine3<T>::translate(const Vec3& t) const
|
||||
{
|
||||
Mat4 m = matrix;
|
||||
m.val[ 3] += t[0];
|
||||
m.val[ 7] += t[1];
|
||||
m.val[11] += t[2];
|
||||
return m;
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
cv::Affine3<T> cv::Affine3<T>::concatenate(const Affine3<T>& affine) const
|
||||
{
|
||||
return (*this).rotate(affine.rotation()).translate(affine.translation());
|
||||
}
|
||||
|
||||
template<typename T> template <typename Y> inline
|
||||
cv::Affine3<T>::operator Affine3<Y>() const
|
||||
{
|
||||
return Affine3<Y>(matrix);
|
||||
}
|
||||
|
||||
template<typename T> template <typename Y> inline
|
||||
cv::Affine3<Y> cv::Affine3<T>::cast() const
|
||||
{
|
||||
return Affine3<Y>(matrix);
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
cv::Affine3<T> cv::operator*(const cv::Affine3<T>& affine1, const cv::Affine3<T>& affine2)
|
||||
{
|
||||
return affine2.concatenate(affine1);
|
||||
}
|
||||
|
||||
template<typename T, typename V> inline
|
||||
V cv::operator*(const cv::Affine3<T>& affine, const V& v)
|
||||
{
|
||||
const typename Affine3<T>::Mat4& m = affine.matrix;
|
||||
|
||||
V r;
|
||||
r.x = m.val[0] * v.x + m.val[1] * v.y + m.val[ 2] * v.z + m.val[ 3];
|
||||
r.y = m.val[4] * v.x + m.val[5] * v.y + m.val[ 6] * v.z + m.val[ 7];
|
||||
r.z = m.val[8] * v.x + m.val[9] * v.y + m.val[10] * v.z + m.val[11];
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline
|
||||
cv::Vec3f cv::operator*(const cv::Affine3f& affine, const cv::Vec3f& v)
|
||||
{
|
||||
const cv::Matx44f& m = affine.matrix;
|
||||
cv::Vec3f r;
|
||||
r.val[0] = m.val[0] * v[0] + m.val[1] * v[1] + m.val[ 2] * v[2] + m.val[ 3];
|
||||
r.val[1] = m.val[4] * v[0] + m.val[5] * v[1] + m.val[ 6] * v[2] + m.val[ 7];
|
||||
r.val[2] = m.val[8] * v[0] + m.val[9] * v[1] + m.val[10] * v[2] + m.val[11];
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline
|
||||
cv::Vec3d cv::operator*(const cv::Affine3d& affine, const cv::Vec3d& v)
|
||||
{
|
||||
const cv::Matx44d& m = affine.matrix;
|
||||
cv::Vec3d r;
|
||||
r.val[0] = m.val[0] * v[0] + m.val[1] * v[1] + m.val[ 2] * v[2] + m.val[ 3];
|
||||
r.val[1] = m.val[4] * v[0] + m.val[5] * v[1] + m.val[ 6] * v[2] + m.val[ 7];
|
||||
r.val[2] = m.val[8] * v[0] + m.val[9] * v[1] + m.val[10] * v[2] + m.val[11];
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H
|
||||
|
||||
template<typename T> inline
|
||||
cv::Affine3<T>::Affine3(const Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>& affine)
|
||||
{
|
||||
cv::Mat(4, 4, cv::DataType<T>::type, affine.matrix().data()).copyTo(matrix);
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
cv::Affine3<T>::Affine3(const Eigen::Transform<T, 3, Eigen::Affine>& affine)
|
||||
{
|
||||
Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)> a = affine;
|
||||
cv::Mat(4, 4, cv::DataType<T>::type, a.matrix().data()).copyTo(matrix);
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
cv::Affine3<T>::operator Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>() const
|
||||
{
|
||||
Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)> r;
|
||||
cv::Mat hdr(4, 4, cv::DataType<T>::type, r.matrix().data());
|
||||
cv::Mat(matrix, false).copyTo(hdr);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
cv::Affine3<T>::operator Eigen::Transform<T, 3, Eigen::Affine>() const
|
||||
{
|
||||
return this->operator Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>();
|
||||
}
|
||||
|
||||
#endif /* defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H */
|
||||
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __OPENCV_CORE_AFFINE3_HPP__ */
|
@@ -892,6 +892,7 @@ public:
|
||||
typedef Point_<int> Point2i;
|
||||
typedef Point2i Point;
|
||||
typedef Size_<int> Size2i;
|
||||
typedef Size_<double> Size2d;
|
||||
typedef Size2i Size;
|
||||
typedef Rect_<int> Rect;
|
||||
typedef Point_<float> Point2f;
|
||||
|
@@ -245,7 +245,7 @@ enum {
|
||||
CV_StsVecLengthErr= -28, /* incorrect vector length */
|
||||
CV_StsFilterStructContentErr= -29, /* incorr. filter structure content */
|
||||
CV_StsKernelStructContentErr= -30, /* incorr. transform kernel content */
|
||||
CV_StsFilterOffsetErr= -31, /* incorrect filter ofset value */
|
||||
CV_StsFilterOffsetErr= -31, /* incorrect filter offset value */
|
||||
CV_StsBadSize= -201, /* the input/output structure size is incorrect */
|
||||
CV_StsDivByZero= -202, /* division by zero */
|
||||
CV_StsInplaceNotSupported= -203, /* in-place operation is not supported */
|
||||
|
@@ -47,22 +47,27 @@
|
||||
#include "gl_core_3_1.hpp"
|
||||
|
||||
#ifdef HAVE_OPENGL
|
||||
#if defined(__APPLE__)
|
||||
#include <mach-o/dyld.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <dlfcn.h>
|
||||
|
||||
static void* AppleGLGetProcAddress (const char* name)
|
||||
{
|
||||
static const struct mach_header* image = 0;
|
||||
if (!image)
|
||||
image = NSAddImage("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", NSADDIMAGE_OPTION_RETURN_ON_ERROR);
|
||||
static bool initialized = false;
|
||||
static void * handle = NULL;
|
||||
if (!handle)
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
initialized = true;
|
||||
const char * const path = "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL";
|
||||
|
||||
// prepend a '_' for the Unix C symbol mangling convention
|
||||
std::string symbolName = "_";
|
||||
symbolName += std::string(name);
|
||||
|
||||
NSSymbol symbol = image ? NSLookupSymbolInImage(image, &symbolName[0], NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR) : 0;
|
||||
|
||||
return symbol ? NSAddressOfSymbol(symbol) : 0;
|
||||
handle = dlopen(path, RTLD_LAZY | RTLD_GLOBAL);
|
||||
}
|
||||
if (!handle)
|
||||
return NULL;
|
||||
}
|
||||
return dlsym(handle, name);
|
||||
}
|
||||
#endif // __APPLE__
|
||||
|
||||
|
@@ -2392,16 +2392,14 @@ TYPED_TEST_P(Core_CheckRange, Negative)
|
||||
double min_bound = 4.5;
|
||||
double max_bound = 16.0;
|
||||
|
||||
TypeParam data[] = {5, 10, 15, 4, 10 ,2, 8, 12, 14};
|
||||
TypeParam data[] = {5, 10, 15, 4, 10, 2, 8, 12, 14};
|
||||
cv::Mat src = cv::Mat(3,3, cv::DataDepth<TypeParam>::value, data);
|
||||
|
||||
cv::Point* bad_pt = new cv::Point(0, 0);
|
||||
cv::Point bad_pt(0, 0);
|
||||
|
||||
ASSERT_FALSE(checkRange(src, true, bad_pt, min_bound, max_bound));
|
||||
ASSERT_EQ(bad_pt->x,0);
|
||||
ASSERT_EQ(bad_pt->y,1);
|
||||
|
||||
delete bad_pt;
|
||||
ASSERT_FALSE(checkRange(src, true, &bad_pt, min_bound, max_bound));
|
||||
ASSERT_EQ(bad_pt.x, 0);
|
||||
ASSERT_EQ(bad_pt.y, 1);
|
||||
}
|
||||
|
||||
TYPED_TEST_P(Core_CheckRange, Positive)
|
||||
@@ -2409,16 +2407,14 @@ TYPED_TEST_P(Core_CheckRange, Positive)
|
||||
double min_bound = -1;
|
||||
double max_bound = 16.0;
|
||||
|
||||
TypeParam data[] = {5, 10, 15, 4, 10 ,2, 8, 12, 14};
|
||||
TypeParam data[] = {5, 10, 15, 4, 10, 2, 8, 12, 14};
|
||||
cv::Mat src = cv::Mat(3,3, cv::DataDepth<TypeParam>::value, data);
|
||||
|
||||
cv::Point* bad_pt = new cv::Point(0, 0);
|
||||
cv::Point bad_pt(0, 0);
|
||||
|
||||
ASSERT_TRUE(checkRange(src, true, bad_pt, min_bound, max_bound));
|
||||
ASSERT_EQ(bad_pt->x,0);
|
||||
ASSERT_EQ(bad_pt->y,0);
|
||||
|
||||
delete bad_pt;
|
||||
ASSERT_TRUE(checkRange(src, true, &bad_pt, min_bound, max_bound));
|
||||
ASSERT_EQ(bad_pt.x, 0);
|
||||
ASSERT_EQ(bad_pt.y, 0);
|
||||
}
|
||||
|
||||
TYPED_TEST_P(Core_CheckRange, Bounds)
|
||||
@@ -2426,16 +2422,14 @@ TYPED_TEST_P(Core_CheckRange, Bounds)
|
||||
double min_bound = 24.5;
|
||||
double max_bound = 1.0;
|
||||
|
||||
TypeParam data[] = {5, 10, 15, 4, 10 ,2, 8, 12, 14};
|
||||
TypeParam data[] = {5, 10, 15, 4, 10, 2, 8, 12, 14};
|
||||
cv::Mat src = cv::Mat(3,3, cv::DataDepth<TypeParam>::value, data);
|
||||
|
||||
cv::Point* bad_pt = new cv::Point(0, 0);
|
||||
cv::Point bad_pt(0, 0);
|
||||
|
||||
ASSERT_FALSE(checkRange(src, true, bad_pt, min_bound, max_bound));
|
||||
ASSERT_EQ(bad_pt->x,0);
|
||||
ASSERT_EQ(bad_pt->y,0);
|
||||
|
||||
delete bad_pt;
|
||||
ASSERT_FALSE(checkRange(src, true, &bad_pt, min_bound, max_bound));
|
||||
ASSERT_EQ(bad_pt.x, 0);
|
||||
ASSERT_EQ(bad_pt.y, 0);
|
||||
}
|
||||
|
||||
TYPED_TEST_P(Core_CheckRange, Zero)
|
||||
|
@@ -129,15 +129,20 @@ public:
|
||||
|
||||
#if defined(USE_CUDA)
|
||||
|
||||
#define cudaSafeCall(expr) ___cudaSafeCall(expr, __FILE__, __LINE__, CV_Func)
|
||||
#define nppSafeCall(expr) ___nppSafeCall(expr, __FILE__, __LINE__, CV_Func)
|
||||
// Disable NPP for this file
|
||||
//#define USE_NPP
|
||||
#undef USE_NPP
|
||||
|
||||
#define cudaSafeCall(expr) ___cudaSafeCall(expr, __FILE__, __LINE__, CV_Func)
|
||||
inline void ___cudaSafeCall(cudaError_t err, const char *file, const int line, const char *func = "")
|
||||
{
|
||||
if (cudaSuccess != err)
|
||||
cv::gpu::error(cudaGetErrorString(err), file, line, func);
|
||||
}
|
||||
|
||||
#ifdef USE_NPP
|
||||
|
||||
#define nppSafeCall(expr) ___nppSafeCall(expr, __FILE__, __LINE__, CV_Func)
|
||||
inline void ___nppSafeCall(int err, const char *file, const int line, const char *func = "")
|
||||
{
|
||||
if (err < 0)
|
||||
@@ -148,6 +153,8 @@ inline void ___nppSafeCall(int err, const char *file, const int line, const char
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
namespace cv { namespace gpu { namespace device
|
||||
{
|
||||
void copyToWithMask_gpu(PtrStepSzb src, PtrStepSzb dst, size_t elemSize1, int cn, PtrStepSzb mask, bool colorMask, cudaStream_t stream);
|
||||
@@ -173,6 +180,8 @@ template <typename T> void kernelSetCaller(GpuMat& src, Scalar s, const GpuMat&
|
||||
cv::gpu::device::set_to_gpu(src, sf.val, mask, src.channels(), stream);
|
||||
}
|
||||
|
||||
#ifdef USE_NPP
|
||||
|
||||
template<int n> struct NPPTypeTraits;
|
||||
template<> struct NPPTypeTraits<CV_8U> { typedef Npp8u npp_type; };
|
||||
template<> struct NPPTypeTraits<CV_8S> { typedef Npp8s npp_type; };
|
||||
@@ -182,9 +191,13 @@ template<> struct NPPTypeTraits<CV_32S> { typedef Npp32s npp_type; };
|
||||
template<> struct NPPTypeTraits<CV_32F> { typedef Npp32f npp_type; };
|
||||
template<> struct NPPTypeTraits<CV_64F> { typedef Npp64f npp_type; };
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Convert
|
||||
|
||||
#ifdef USE_NPP
|
||||
|
||||
template<int SDEPTH, int DDEPTH> struct NppConvertFunc
|
||||
{
|
||||
typedef typename NPPTypeTraits<SDEPTH>::npp_type src_t;
|
||||
@@ -232,9 +245,13 @@ template<int DDEPTH, typename NppConvertFunc<CV_32F, DDEPTH>::func_ptr func> str
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Set
|
||||
|
||||
#ifdef USE_NPP
|
||||
|
||||
template<int SDEPTH, int SCN> struct NppSetFunc
|
||||
{
|
||||
typedef typename NPPTypeTraits<SDEPTH>::npp_type src_t;
|
||||
@@ -339,9 +356,13 @@ template<int SDEPTH, typename NppSetMaskFunc<SDEPTH, 1>::func_ptr func> struct N
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CopyMasked
|
||||
|
||||
#ifdef USE_NPP
|
||||
|
||||
template<int SDEPTH> struct NppCopyMaskedFunc
|
||||
{
|
||||
typedef typename NPPTypeTraits<SDEPTH>::npp_type src_t;
|
||||
@@ -365,6 +386,8 @@ template<int SDEPTH, typename NppCopyMaskedFunc<SDEPTH>::func_ptr func> struct N
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <typename T> static inline bool isAligned(const T* ptr, size_t size)
|
||||
{
|
||||
return reinterpret_cast<size_t>(ptr) % size == 0;
|
||||
@@ -877,6 +900,8 @@ public:
|
||||
}
|
||||
|
||||
typedef void (*func_t)(const GpuMat& src, GpuMat& dst, const GpuMat& mask, cudaStream_t stream);
|
||||
|
||||
#ifdef USE_NPP
|
||||
static const func_t funcs[7][4] =
|
||||
{
|
||||
/* 8U */ {NppCopyMasked<CV_8U , nppiCopy_8u_C1MR >::call, cv::gpu::device::copyWithMask, NppCopyMasked<CV_8U , nppiCopy_8u_C3MR >::call, NppCopyMasked<CV_8U , nppiCopy_8u_C4MR >::call},
|
||||
@@ -889,6 +914,9 @@ public:
|
||||
};
|
||||
|
||||
const func_t func = mask.channels() == src.channels() ? funcs[src.depth()][src.channels() - 1] : cv::gpu::device::copyWithMask;
|
||||
#else
|
||||
const func_t func = cv::gpu::device::copyWithMask;
|
||||
#endif
|
||||
|
||||
func(src, dst, mask, 0);
|
||||
}
|
||||
@@ -896,6 +924,8 @@ public:
|
||||
void convert(const GpuMat& src, GpuMat& dst) const
|
||||
{
|
||||
typedef void (*func_t)(const GpuMat& src, GpuMat& dst);
|
||||
|
||||
#ifdef USE_NPP
|
||||
static const func_t funcs[7][7][4] =
|
||||
{
|
||||
{
|
||||
@@ -962,6 +992,7 @@ public:
|
||||
/* 64F -> 64F */ {0,0,0,0}
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
CV_Assert(src.depth() <= CV_64F && src.channels() <= 4);
|
||||
CV_Assert(dst.depth() <= CV_64F);
|
||||
@@ -980,8 +1011,12 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef USE_NPP
|
||||
const func_t func = funcs[src.depth()][dst.depth()][src.channels() - 1];
|
||||
CV_DbgAssert(func != 0);
|
||||
#else
|
||||
const func_t func = cv::gpu::device::convertTo;
|
||||
#endif
|
||||
|
||||
func(src, dst);
|
||||
}
|
||||
@@ -1023,6 +1058,8 @@ public:
|
||||
}
|
||||
|
||||
typedef void (*func_t)(GpuMat& src, Scalar s);
|
||||
|
||||
#ifdef USE_NPP
|
||||
static const func_t funcs[7][4] =
|
||||
{
|
||||
{NppSet<CV_8U , 1, nppiSet_8u_C1R >::call, cv::gpu::device::setTo , cv::gpu::device::setTo , NppSet<CV_8U , 4, nppiSet_8u_C4R >::call},
|
||||
@@ -1033,6 +1070,7 @@ public:
|
||||
{NppSet<CV_32F, 1, nppiSet_32f_C1R>::call, cv::gpu::device::setTo , cv::gpu::device::setTo , NppSet<CV_32F, 4, nppiSet_32f_C4R>::call},
|
||||
{cv::gpu::device::setTo , cv::gpu::device::setTo , cv::gpu::device::setTo , cv::gpu::device::setTo }
|
||||
};
|
||||
#endif
|
||||
|
||||
CV_Assert(m.depth() <= CV_64F && m.channels() <= 4);
|
||||
|
||||
@@ -1042,14 +1080,22 @@ public:
|
||||
CV_Error(CV_StsUnsupportedFormat, "The device doesn't support double");
|
||||
}
|
||||
|
||||
#ifdef USE_NPP
|
||||
const func_t func = funcs[m.depth()][m.channels() - 1];
|
||||
#else
|
||||
const func_t func = cv::gpu::device::setTo;
|
||||
#endif
|
||||
|
||||
if (stream)
|
||||
cv::gpu::device::setTo(m, s, stream);
|
||||
else
|
||||
funcs[m.depth()][m.channels() - 1](m, s);
|
||||
func(m, s);
|
||||
}
|
||||
else
|
||||
{
|
||||
typedef void (*func_t)(GpuMat& src, Scalar s, const GpuMat& mask);
|
||||
|
||||
#ifdef USE_NPP
|
||||
static const func_t funcs[7][4] =
|
||||
{
|
||||
{NppSetMask<CV_8U , 1, nppiSet_8u_C1MR >::call, cv::gpu::device::setTo, cv::gpu::device::setTo, NppSetMask<CV_8U , 4, nppiSet_8u_C4MR >::call},
|
||||
@@ -1060,6 +1106,7 @@ public:
|
||||
{NppSetMask<CV_32F, 1, nppiSet_32f_C1MR>::call, cv::gpu::device::setTo, cv::gpu::device::setTo, NppSetMask<CV_32F, 4, nppiSet_32f_C4MR>::call},
|
||||
{cv::gpu::device::setTo , cv::gpu::device::setTo, cv::gpu::device::setTo, cv::gpu::device::setTo }
|
||||
};
|
||||
#endif
|
||||
|
||||
CV_Assert(m.depth() <= CV_64F && m.channels() <= 4);
|
||||
|
||||
@@ -1069,10 +1116,16 @@ public:
|
||||
CV_Error(CV_StsUnsupportedFormat, "The device doesn't support double");
|
||||
}
|
||||
|
||||
#ifdef USE_NPP
|
||||
const func_t func = funcs[m.depth()][m.channels() - 1];
|
||||
#else
|
||||
const func_t func = cv::gpu::device::setTo;
|
||||
#endif
|
||||
|
||||
if (stream)
|
||||
cv::gpu::device::setTo(m, s, mask, stream);
|
||||
else
|
||||
funcs[m.depth()][m.channels() - 1](m, s, mask);
|
||||
func(m, s, mask);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -93,7 +93,7 @@ PERF_TEST_P(ImagePair, Calib3D_StereoBM,
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// StereoBeliefPropagation
|
||||
|
||||
PERF_TEST_P(ImagePair, Calib3D_StereoBeliefPropagation,
|
||||
PERF_TEST_P(ImagePair, DISABLED_Calib3D_StereoBeliefPropagation,
|
||||
Values(pair_string("gpu/stereobp/aloe-L.png", "gpu/stereobp/aloe-R.png")))
|
||||
{
|
||||
declare.time(300.0);
|
||||
|
@@ -851,6 +851,8 @@ PERF_TEST_P(Sz_Depth_Cn, ImgProc_BlendLinear,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_CUFFT
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Convolve
|
||||
|
||||
@@ -1085,6 +1087,8 @@ PERF_TEST_P(Sz_Flags, ImgProc_Dft,
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// CornerHarris
|
||||
|
||||
@@ -1538,7 +1542,7 @@ CV_ENUM(AlphaOp, ALPHA_OVER, ALPHA_IN, ALPHA_OUT, ALPHA_ATOP, ALPHA_XOR, ALPHA_P
|
||||
|
||||
DEF_PARAM_TEST(Sz_Type_Op, cv::Size, MatType, AlphaOp);
|
||||
|
||||
PERF_TEST_P(Sz_Type_Op, ImgProc_AlphaComp,
|
||||
PERF_TEST_P(Sz_Type_Op, DISABLED_ImgProc_AlphaComp,
|
||||
Combine(GPU_TYPICAL_MAT_SIZES,
|
||||
Values(CV_8UC4, CV_16UC4, CV_32SC4, CV_32FC4),
|
||||
AlphaOp::all()))
|
||||
@@ -1559,7 +1563,14 @@ PERF_TEST_P(Sz_Type_Op, ImgProc_AlphaComp,
|
||||
|
||||
TEST_CYCLE() cv::gpu::alphaComp(d_img1, d_img2, dst, alpha_op);
|
||||
|
||||
GPU_SANITY_CHECK(dst, 1e-3, ERROR_RELATIVE);
|
||||
if (CV_MAT_DEPTH(type) < CV_32F)
|
||||
{
|
||||
GPU_SANITY_CHECK(dst, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
GPU_SANITY_CHECK(dst, 1e-3, ERROR_RELATIVE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1825,7 +1836,7 @@ CV_FLAGS(GHMethod, GHT_POSITION, GHT_SCALE, GHT_ROTATION)
|
||||
|
||||
DEF_PARAM_TEST(Method_Sz, GHMethod, cv::Size);
|
||||
|
||||
PERF_TEST_P(Method_Sz, ImgProc_GeneralizedHough,
|
||||
PERF_TEST_P(Method_Sz, DISABLED_ImgProc_GeneralizedHough,
|
||||
Combine(Values(GHMethod(cv::GHT_POSITION), GHMethod(cv::GHT_POSITION | cv::GHT_SCALE), GHMethod(cv::GHT_POSITION | cv::GHT_ROTATION), GHMethod(cv::GHT_POSITION | cv::GHT_SCALE | cv::GHT_ROTATION)),
|
||||
GPU_TYPICAL_MAT_SIZES))
|
||||
{
|
||||
|
@@ -42,8 +42,6 @@
|
||||
|
||||
#if !defined CUDA_DISABLER
|
||||
|
||||
#include <utility>
|
||||
#include <algorithm>//std::swap
|
||||
#include "opencv2/gpu/device/common.hpp"
|
||||
#include "opencv2/gpu/device/emulation.hpp"
|
||||
#include "opencv2/gpu/device/transform.hpp"
|
||||
@@ -239,30 +237,35 @@ namespace canny
|
||||
{
|
||||
__device__ int counter = 0;
|
||||
|
||||
__global__ void edgesHysteresisLocalKernel(PtrStepSzi map, ushort2* st)
|
||||
__device__ __forceinline__ bool checkIdx(int y, int x, int rows, int cols)
|
||||
{
|
||||
return (y >= 0) && (y < rows) && (x >= 0) && (x < cols);
|
||||
}
|
||||
|
||||
__global__ void edgesHysteresisLocalKernel(PtrStepSzi map, short2* st)
|
||||
{
|
||||
__shared__ volatile int smem[18][18];
|
||||
|
||||
const int x = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
const int y = blockIdx.y * blockDim.y + threadIdx.y;
|
||||
|
||||
smem[threadIdx.y + 1][threadIdx.x + 1] = x < map.cols && y < map.rows ? map(y, x) : 0;
|
||||
smem[threadIdx.y + 1][threadIdx.x + 1] = checkIdx(y, x, map.rows, map.cols) ? map(y, x) : 0;
|
||||
if (threadIdx.y == 0)
|
||||
smem[0][threadIdx.x + 1] = y > 0 ? map(y - 1, x) : 0;
|
||||
smem[0][threadIdx.x + 1] = checkIdx(y - 1, x, map.rows, map.cols) ? map(y - 1, x) : 0;
|
||||
if (threadIdx.y == blockDim.y - 1)
|
||||
smem[blockDim.y + 1][threadIdx.x + 1] = y + 1 < map.rows ? map(y + 1, x) : 0;
|
||||
smem[blockDim.y + 1][threadIdx.x + 1] = checkIdx(y + 1, x, map.rows, map.cols) ? map(y + 1, x) : 0;
|
||||
if (threadIdx.x == 0)
|
||||
smem[threadIdx.y + 1][0] = x > 0 ? map(y, x - 1) : 0;
|
||||
smem[threadIdx.y + 1][0] = checkIdx(y, x - 1, map.rows, map.cols) ? map(y, x - 1) : 0;
|
||||
if (threadIdx.x == blockDim.x - 1)
|
||||
smem[threadIdx.y + 1][blockDim.x + 1] = x + 1 < map.cols ? map(y, x + 1) : 0;
|
||||
smem[threadIdx.y + 1][blockDim.x + 1] = checkIdx(y, x + 1, map.rows, map.cols) ? map(y, x + 1) : 0;
|
||||
if (threadIdx.x == 0 && threadIdx.y == 0)
|
||||
smem[0][0] = y > 0 && x > 0 ? map(y - 1, x - 1) : 0;
|
||||
smem[0][0] = checkIdx(y - 1, x - 1, map.rows, map.cols) ? map(y - 1, x - 1) : 0;
|
||||
if (threadIdx.x == blockDim.x - 1 && threadIdx.y == 0)
|
||||
smem[0][blockDim.x + 1] = y > 0 && x + 1 < map.cols ? map(y - 1, x + 1) : 0;
|
||||
smem[0][blockDim.x + 1] = checkIdx(y - 1, x + 1, map.rows, map.cols) ? map(y - 1, x + 1) : 0;
|
||||
if (threadIdx.x == 0 && threadIdx.y == blockDim.y - 1)
|
||||
smem[blockDim.y + 1][0] = y + 1 < map.rows && x > 0 ? map(y + 1, x - 1) : 0;
|
||||
smem[blockDim.y + 1][0] = checkIdx(y + 1, x - 1, map.rows, map.cols) ? map(y + 1, x - 1) : 0;
|
||||
if (threadIdx.x == blockDim.x - 1 && threadIdx.y == blockDim.y - 1)
|
||||
smem[blockDim.y + 1][blockDim.x + 1] = y + 1 < map.rows && x + 1 < map.cols ? map(y + 1, x + 1) : 0;
|
||||
smem[blockDim.y + 1][blockDim.x + 1] = checkIdx(y + 1, x + 1, map.rows, map.cols) ? map(y + 1, x + 1) : 0;
|
||||
|
||||
__syncthreads();
|
||||
|
||||
@@ -290,8 +293,12 @@ namespace canny
|
||||
n += smem[threadIdx.y + 2][threadIdx.x + 2] == 2;
|
||||
}
|
||||
|
||||
__syncthreads();
|
||||
|
||||
if (n > 0)
|
||||
smem[threadIdx.y + 1][threadIdx.x + 1] = 2;
|
||||
|
||||
__syncthreads();
|
||||
}
|
||||
|
||||
const int e = smem[threadIdx.y + 1][threadIdx.x + 1];
|
||||
@@ -317,11 +324,11 @@ namespace canny
|
||||
if (n > 0)
|
||||
{
|
||||
const int ind = ::atomicAdd(&counter, 1);
|
||||
st[ind] = make_ushort2(x, y);
|
||||
st[ind] = make_short2(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
void edgesHysteresisLocal(PtrStepSzi map, ushort2* st1)
|
||||
void edgesHysteresisLocal(PtrStepSzi map, short2* st1)
|
||||
{
|
||||
void* counter_ptr;
|
||||
cudaSafeCall( cudaGetSymbolAddress(&counter_ptr, counter) );
|
||||
@@ -345,13 +352,13 @@ namespace canny
|
||||
__constant__ int c_dx[8] = {-1, 0, 1, -1, 1, -1, 0, 1};
|
||||
__constant__ int c_dy[8] = {-1, -1, -1, 0, 0, 1, 1, 1};
|
||||
|
||||
__global__ void edgesHysteresisGlobalKernel(PtrStepSzi map, ushort2* st1, ushort2* st2, const int count)
|
||||
__global__ void edgesHysteresisGlobalKernel(PtrStepSzi map, short2* st1, short2* st2, const int count)
|
||||
{
|
||||
const int stack_size = 512;
|
||||
|
||||
__shared__ int s_counter;
|
||||
__shared__ int s_ind;
|
||||
__shared__ ushort2 s_st[stack_size];
|
||||
__shared__ short2 s_st[stack_size];
|
||||
|
||||
if (threadIdx.x == 0)
|
||||
s_counter = 0;
|
||||
@@ -363,14 +370,14 @@ namespace canny
|
||||
if (ind >= count)
|
||||
return;
|
||||
|
||||
ushort2 pos = st1[ind];
|
||||
short2 pos = st1[ind];
|
||||
|
||||
if (threadIdx.x < 8)
|
||||
{
|
||||
pos.x += c_dx[threadIdx.x];
|
||||
pos.y += c_dy[threadIdx.x];
|
||||
|
||||
if (pos.x > 0 && pos.x < map.cols && pos.y > 0 && pos.y < map.rows && map(pos.y, pos.x) == 1)
|
||||
if (pos.x > 0 && pos.x < map.cols - 1 && pos.y > 0 && pos.y < map.rows - 1 && map(pos.y, pos.x) == 1)
|
||||
{
|
||||
map(pos.y, pos.x) = 2;
|
||||
|
||||
@@ -402,7 +409,7 @@ namespace canny
|
||||
pos.x += c_dx[threadIdx.x & 7];
|
||||
pos.y += c_dy[threadIdx.x & 7];
|
||||
|
||||
if (pos.x > 0 && pos.x < map.cols && pos.y > 0 && pos.y < map.rows && map(pos.y, pos.x) == 1)
|
||||
if (pos.x > 0 && pos.x < map.cols - 1 && pos.y > 0 && pos.y < map.rows - 1 && map(pos.y, pos.x) == 1)
|
||||
{
|
||||
map(pos.y, pos.x) = 2;
|
||||
|
||||
@@ -419,8 +426,10 @@ namespace canny
|
||||
{
|
||||
if (threadIdx.x == 0)
|
||||
{
|
||||
ind = ::atomicAdd(&counter, s_counter);
|
||||
s_ind = ind - s_counter;
|
||||
s_ind = ::atomicAdd(&counter, s_counter);
|
||||
|
||||
if (s_ind + s_counter > map.cols * map.rows)
|
||||
s_counter = 0;
|
||||
}
|
||||
|
||||
__syncthreads();
|
||||
@@ -432,7 +441,7 @@ namespace canny
|
||||
}
|
||||
}
|
||||
|
||||
void edgesHysteresisGlobal(PtrStepSzi map, ushort2* st1, ushort2* st2)
|
||||
void edgesHysteresisGlobal(PtrStepSzi map, short2* st1, short2* st2)
|
||||
{
|
||||
void* counter_ptr;
|
||||
cudaSafeCall( cudaGetSymbolAddress(&counter_ptr, canny::counter) );
|
||||
@@ -454,7 +463,12 @@ namespace canny
|
||||
|
||||
cudaSafeCall( cudaMemcpy(&count, counter_ptr, sizeof(int), cudaMemcpyDeviceToHost) );
|
||||
|
||||
std::swap(st1, st2);
|
||||
count = min(count, map.cols * map.rows);
|
||||
|
||||
//std::swap(st1, st2);
|
||||
short2* tmp = st1;
|
||||
st1 = st2;
|
||||
st2 = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -40,8 +40,6 @@
|
||||
//
|
||||
//M*/
|
||||
|
||||
#define CUDA_DISABLER
|
||||
|
||||
#if !defined CUDA_DISABLER
|
||||
|
||||
#include <thrust/device_ptr.h>
|
||||
|
@@ -266,7 +266,7 @@ namespace cv { namespace gpu { namespace device
|
||||
__device__ __forceinline__ int calcDist(const uchar2& a, const uchar2& b) { return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y); }
|
||||
__device__ __forceinline__ int calcDist(const uchar3& a, const uchar3& b) { return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) + (a.z-b.z)*(a.z-b.z); }
|
||||
|
||||
template <class T> struct FastNonLocalMenas
|
||||
template <class T> struct FastNonLocalMeans
|
||||
{
|
||||
enum
|
||||
{
|
||||
@@ -290,7 +290,7 @@ namespace cv { namespace gpu { namespace device
|
||||
int block_window;
|
||||
float minus_h2_inv;
|
||||
|
||||
FastNonLocalMenas(int search_window_, int block_window_, float h) : search_radius(search_window_/2), block_radius(block_window_/2),
|
||||
FastNonLocalMeans(int search_window_, int block_window_, float h) : search_radius(search_window_/2), block_radius(block_window_/2),
|
||||
search_window(search_window_), block_window(block_window_), minus_h2_inv(-1.f/(h * h * VecTraits<T>::cn)) {}
|
||||
|
||||
PtrStep<T> src;
|
||||
@@ -394,7 +394,7 @@ namespace cv { namespace gpu { namespace device
|
||||
}
|
||||
}
|
||||
|
||||
__device__ __forceinline__ void convolve_window(int i, int j, const int* dist_sums, PtrStepi& col_sums, PtrStepi& up_col_sums, T& dst) const
|
||||
__device__ __forceinline__ void convolve_window(int i, int j, const int* dist_sums, T& dst) const
|
||||
{
|
||||
typedef typename TypeVec<float, VecTraits<T>::cn>::vec_type sum_type;
|
||||
|
||||
@@ -471,18 +471,18 @@ namespace cv { namespace gpu { namespace device
|
||||
|
||||
__syncthreads();
|
||||
|
||||
convolve_window(i, j, dist_sums, col_sums, up_col_sums, dst(i, j));
|
||||
convolve_window(i, j, dist_sums, dst(i, j));
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
__global__ void fast_nlm_kernel(const FastNonLocalMenas<T> fnlm, PtrStepSz<T> dst) { fnlm(dst); }
|
||||
__global__ void fast_nlm_kernel(const FastNonLocalMeans<T> fnlm, PtrStepSz<T> dst) { fnlm(dst); }
|
||||
|
||||
void nln_fast_get_buffer_size(const PtrStepSzb& src, int search_window, int block_window, int& buffer_cols, int& buffer_rows)
|
||||
{
|
||||
typedef FastNonLocalMenas<uchar> FNLM;
|
||||
typedef FastNonLocalMeans<uchar> FNLM;
|
||||
dim3 grid(divUp(src.cols, FNLM::TILE_COLS), divUp(src.rows, FNLM::TILE_ROWS));
|
||||
|
||||
buffer_cols = search_window * search_window * grid.y;
|
||||
@@ -493,7 +493,7 @@ namespace cv { namespace gpu { namespace device
|
||||
void nlm_fast_gpu(const PtrStepSzb& src, PtrStepSzb dst, PtrStepi buffer,
|
||||
int search_window, int block_window, float h, cudaStream_t stream)
|
||||
{
|
||||
typedef FastNonLocalMenas<T> FNLM;
|
||||
typedef FastNonLocalMeans<T> FNLM;
|
||||
FNLM fnlm(search_window, block_window, h);
|
||||
|
||||
fnlm.src = (PtrStepSz<T>)src;
|
||||
|
@@ -40,8 +40,6 @@
|
||||
//
|
||||
//M*/
|
||||
|
||||
#define CUDA_DISABLER
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
@@ -244,6 +244,10 @@ void cv::gpu::reprojectImageTo3D(const GpuMat& disp, GpuMat& xyz, const Mat& Q,
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// copyMakeBorder
|
||||
|
||||
// Disable NPP for this file
|
||||
//#define USE_NPP
|
||||
#undef USE_NPP
|
||||
|
||||
namespace cv { namespace gpu { namespace device
|
||||
{
|
||||
namespace imgproc
|
||||
@@ -279,6 +283,7 @@ void cv::gpu::copyMakeBorder(const GpuMat& src, GpuMat& dst, int top, int bottom
|
||||
|
||||
cudaStream_t stream = StreamAccessor::getStream(s);
|
||||
|
||||
#ifdef USE_NPP
|
||||
if (borderType == BORDER_CONSTANT && (src.type() == CV_8UC1 || src.type() == CV_8UC4 || src.type() == CV_32SC1 || src.type() == CV_32FC1))
|
||||
{
|
||||
NppiSize srcsz;
|
||||
@@ -328,6 +333,7 @@ void cv::gpu::copyMakeBorder(const GpuMat& src, GpuMat& dst, int top, int bottom
|
||||
cudaSafeCall( cudaDeviceSynchronize() );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
typedef void (*caller_t)(const PtrStepSzb& src, const PtrStepSzb& dst, int top, int left, int borderType, const Scalar& value, cudaStream_t stream);
|
||||
static const caller_t callers[6][4] =
|
||||
@@ -1485,6 +1491,8 @@ void cv::gpu::convolve(const GpuMat& image, const GpuMat& templ, GpuMat& result,
|
||||
|
||||
void cv::gpu::CannyBuf::create(const Size& image_size, int apperture_size)
|
||||
{
|
||||
CV_Assert(image_size.width < std::numeric_limits<short>::max() && image_size.height < std::numeric_limits<short>::max());
|
||||
|
||||
if (apperture_size > 0)
|
||||
{
|
||||
ensureSizeIsEnough(image_size, CV_32SC1, dx);
|
||||
@@ -1500,8 +1508,8 @@ void cv::gpu::CannyBuf::create(const Size& image_size, int apperture_size)
|
||||
ensureSizeIsEnough(image_size, CV_32FC1, mag);
|
||||
ensureSizeIsEnough(image_size, CV_32SC1, map);
|
||||
|
||||
ensureSizeIsEnough(1, image_size.area(), CV_16UC2, st1);
|
||||
ensureSizeIsEnough(1, image_size.area(), CV_16UC2, st2);
|
||||
ensureSizeIsEnough(1, image_size.area(), CV_16SC2, st1);
|
||||
ensureSizeIsEnough(1, image_size.area(), CV_16SC2, st2);
|
||||
}
|
||||
|
||||
void cv::gpu::CannyBuf::release()
|
||||
@@ -1521,9 +1529,9 @@ namespace canny
|
||||
|
||||
void calcMap(PtrStepSzi dx, PtrStepSzi dy, PtrStepSzf mag, PtrStepSzi map, float low_thresh, float high_thresh);
|
||||
|
||||
void edgesHysteresisLocal(PtrStepSzi map, ushort2* st1);
|
||||
void edgesHysteresisLocal(PtrStepSzi map, short2* st1);
|
||||
|
||||
void edgesHysteresisGlobal(PtrStepSzi map, ushort2* st1, ushort2* st2);
|
||||
void edgesHysteresisGlobal(PtrStepSzi map, short2* st1, short2* st2);
|
||||
|
||||
void getEdges(PtrStepSzi map, PtrStepSzb dst);
|
||||
}
|
||||
@@ -1537,9 +1545,9 @@ namespace
|
||||
buf.map.setTo(Scalar::all(0));
|
||||
calcMap(dx, dy, buf.mag, buf.map, low_thresh, high_thresh);
|
||||
|
||||
edgesHysteresisLocal(buf.map, buf.st1.ptr<ushort2>());
|
||||
edgesHysteresisLocal(buf.map, buf.st1.ptr<short2>());
|
||||
|
||||
edgesHysteresisGlobal(buf.map, buf.st1.ptr<ushort2>(), buf.st2.ptr<ushort2>());
|
||||
edgesHysteresisGlobal(buf.map, buf.st1.ptr<short2>(), buf.st2.ptr<short2>());
|
||||
|
||||
getEdges(buf.map, dst);
|
||||
}
|
||||
|
@@ -98,7 +98,7 @@ bool TestHaarCascadeLoader::process()
|
||||
NCV_SET_SKIP_COND(this->allocatorGPU.get()->isCounting());
|
||||
NCV_SKIP_COND_BEGIN
|
||||
|
||||
const std::string testNvbinName = "test.nvbin";
|
||||
const std::string testNvbinName = cv::tempfile("test.nvbin");
|
||||
ncvStat = ncvHaarLoadFromFile_host(this->cascadeName, haar, h_HaarStages, h_HaarNodes, h_HaarFeatures);
|
||||
ncvAssertReturn(ncvStat == NCV_SUCCESS, false);
|
||||
|
||||
|
@@ -715,7 +715,7 @@ GPU_TEST_P(CvtColor, BGR2YCrCb)
|
||||
cv::Mat dst_gold;
|
||||
cv::cvtColor(src, dst_gold, cv::COLOR_BGR2YCrCb);
|
||||
|
||||
EXPECT_MAT_NEAR(dst_gold, dst, 1.0);
|
||||
EXPECT_MAT_NEAR(dst_gold, dst, depth == CV_32F ? 1e-2 : 1);
|
||||
}
|
||||
|
||||
GPU_TEST_P(CvtColor, RGB2YCrCb)
|
||||
@@ -728,7 +728,7 @@ GPU_TEST_P(CvtColor, RGB2YCrCb)
|
||||
cv::Mat dst_gold;
|
||||
cv::cvtColor(src, dst_gold, cv::COLOR_RGB2YCrCb);
|
||||
|
||||
EXPECT_MAT_NEAR(dst_gold, dst, 1.0);
|
||||
EXPECT_MAT_NEAR(dst_gold, dst, depth == CV_32F ? 1e-2 : 1);
|
||||
}
|
||||
|
||||
GPU_TEST_P(CvtColor, BGR2YCrCb4)
|
||||
@@ -749,7 +749,7 @@ GPU_TEST_P(CvtColor, BGR2YCrCb4)
|
||||
cv::split(h_dst, channels);
|
||||
cv::merge(channels, 3, h_dst);
|
||||
|
||||
EXPECT_MAT_NEAR(dst_gold, h_dst, 1.0);
|
||||
EXPECT_MAT_NEAR(dst_gold, h_dst, depth == CV_32F ? 1e-2 : 1);
|
||||
}
|
||||
|
||||
GPU_TEST_P(CvtColor, RGBA2YCrCb4)
|
||||
@@ -771,7 +771,7 @@ GPU_TEST_P(CvtColor, RGBA2YCrCb4)
|
||||
cv::split(h_dst, channels);
|
||||
cv::merge(channels, 3, h_dst);
|
||||
|
||||
EXPECT_MAT_NEAR(dst_gold, h_dst, 1.0);
|
||||
EXPECT_MAT_NEAR(dst_gold, h_dst, depth == CV_32F ? 1e-2 : 1);
|
||||
}
|
||||
|
||||
GPU_TEST_P(CvtColor, YCrCb2BGR)
|
||||
|
@@ -3582,7 +3582,7 @@ GPU_TEST_P(Normalize, WithOutMask)
|
||||
cv::Mat dst_gold;
|
||||
cv::normalize(src, dst_gold, alpha, beta, norm_type, type);
|
||||
|
||||
EXPECT_MAT_NEAR(dst_gold, dst, 1.0);
|
||||
EXPECT_MAT_NEAR(dst_gold, dst, type < CV_32F ? 1.0 : 1e-4);
|
||||
}
|
||||
|
||||
GPU_TEST_P(Normalize, WithMask)
|
||||
@@ -3598,7 +3598,7 @@ GPU_TEST_P(Normalize, WithMask)
|
||||
dst_gold.setTo(cv::Scalar::all(0));
|
||||
cv::normalize(src, dst_gold, alpha, beta, norm_type, type, mask);
|
||||
|
||||
EXPECT_MAT_NEAR(dst_gold, dst, 1.0);
|
||||
EXPECT_MAT_NEAR(dst_gold, dst, type < CV_32F ? 1.0 : 1e-4);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(GPU_Core, Normalize, testing::Combine(
|
||||
|
@@ -114,6 +114,7 @@ GPU_TEST_P(BruteForceNonLocalMeans, Regression)
|
||||
|
||||
cv::Mat bgr = readImage("denoising/lena_noised_gaussian_sigma=20_multi_0.png", cv::IMREAD_COLOR);
|
||||
ASSERT_FALSE(bgr.empty());
|
||||
cv::resize(bgr, bgr, cv::Size(256, 256));
|
||||
|
||||
cv::Mat gray;
|
||||
cv::cvtColor(bgr, gray, CV_BGR2GRAY);
|
||||
@@ -130,6 +131,8 @@ GPU_TEST_P(BruteForceNonLocalMeans, Regression)
|
||||
cv::Mat bgr_gold = readImage("denoising/nlm_denoised_lena_bgr.png", cv::IMREAD_COLOR);
|
||||
cv::Mat gray_gold = readImage("denoising/nlm_denoised_lena_gray.png", cv::IMREAD_GRAYSCALE);
|
||||
ASSERT_FALSE(bgr_gold.empty() || gray_gold.empty());
|
||||
cv::resize(bgr_gold, bgr_gold, cv::Size(256, 256));
|
||||
cv::resize(gray_gold, gray_gold, cv::Size(256, 256));
|
||||
|
||||
EXPECT_MAT_NEAR(bgr_gold, dbgr, 1e-4);
|
||||
EXPECT_MAT_NEAR(gray_gold, dgray, 1e-4);
|
||||
|
@@ -281,7 +281,7 @@ GPU_TEST_P(ConvertTo, WithOutScaling)
|
||||
cv::Mat dst_gold;
|
||||
src.convertTo(dst_gold, depth2);
|
||||
|
||||
EXPECT_MAT_NEAR(dst_gold, dst, 1.0);
|
||||
EXPECT_MAT_NEAR(dst_gold, dst, depth2 < CV_32F ? 1.0 : 1e-4);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -189,7 +189,7 @@ PARAM_TEST_CASE(GeneralizedHough, cv::gpu::DeviceInfo, UseRoi)
|
||||
{
|
||||
};
|
||||
|
||||
GPU_TEST_P(GeneralizedHough, DISABLED_POSITION)
|
||||
GPU_TEST_P(GeneralizedHough, POSITION)
|
||||
{
|
||||
const cv::gpu::DeviceInfo devInfo = GET_PARAM(0);
|
||||
cv::gpu::setDevice(devInfo.deviceID());
|
||||
|
@@ -563,6 +563,8 @@ INSTANTIATE_TEST_CASE_P(GPU_ImgProc, Blend, testing::Combine(
|
||||
testing::Values(MatType(CV_8UC1), MatType(CV_8UC3), MatType(CV_8UC4), MatType(CV_32FC1), MatType(CV_32FC3), MatType(CV_32FC4)),
|
||||
WHOLE_SUBMAT));
|
||||
|
||||
#ifdef HAVE_CUFFT
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// Convolve
|
||||
|
||||
@@ -1090,6 +1092,8 @@ GPU_TEST_P(Dft, R2CThenC2R)
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(GPU_ImgProc, Dft, ALL_DEVICES);
|
||||
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CornerHarris
|
||||
|
||||
|
@@ -483,13 +483,15 @@ GPU_TEST_P(OpticalFlowBM, Accuracy)
|
||||
|
||||
cv::Mat frame0 = readImage("opticalflow/rubberwhale1.png", cv::IMREAD_GRAYSCALE);
|
||||
ASSERT_FALSE(frame0.empty());
|
||||
cv::resize(frame0, frame0, cv::Size(), 0.5, 0.5);
|
||||
|
||||
cv::Mat frame1 = readImage("opticalflow/rubberwhale2.png", cv::IMREAD_GRAYSCALE);
|
||||
ASSERT_FALSE(frame1.empty());
|
||||
cv::resize(frame1, frame1, cv::Size(), 0.5, 0.5);
|
||||
|
||||
cv::Size block_size(16, 16);
|
||||
cv::Size block_size(8, 8);
|
||||
cv::Size shift_size(1, 1);
|
||||
cv::Size max_range(16, 16);
|
||||
cv::Size max_range(8, 8);
|
||||
|
||||
cv::gpu::GpuMat d_velx, d_vely, buf;
|
||||
cv::gpu::calcOpticalFlowBM(loadMat(frame0), loadMat(frame1),
|
||||
|
@@ -278,8 +278,20 @@
|
||||
{
|
||||
self.captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];
|
||||
|
||||
if ([self.captureVideoPreviewLayer isOrientationSupported]) {
|
||||
[self.captureVideoPreviewLayer setOrientation:self.defaultAVCaptureVideoOrientation];
|
||||
if ([self.captureVideoPreviewLayer respondsToSelector:@selector(connection)])
|
||||
{
|
||||
if ([self.captureVideoPreviewLayer.connection isVideoOrientationSupported])
|
||||
{
|
||||
[self.captureVideoPreviewLayer.connection setVideoOrientation:self.defaultAVCaptureVideoOrientation];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Deprecated in 6.0; here for backward compatibility
|
||||
if ([self.captureVideoPreviewLayer isOrientationSupported])
|
||||
{
|
||||
[self.captureVideoPreviewLayer setOrientation:self.defaultAVCaptureVideoOrientation];
|
||||
}
|
||||
}
|
||||
|
||||
if (parentView != nil) {
|
||||
@@ -290,9 +302,6 @@
|
||||
NSLog(@"[Camera] created AVCaptureVideoPreviewLayer");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (void)setDesiredCameraPosition:(AVCaptureDevicePosition)desiredPosition;
|
||||
{
|
||||
for (AVCaptureDevice *device in [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) {
|
||||
|
@@ -111,18 +111,21 @@ bool TiffDecoder::readHeader()
|
||||
bool result = false;
|
||||
|
||||
close();
|
||||
TIFF* tif = TIFFOpen( m_filename.c_str(), "rb" );
|
||||
// TIFFOpen() mode flags are different to fopen(). A 'b' in mode "rb" has no effect when reading.
|
||||
// http://www.remotesensing.org/libtiff/man/TIFFOpen.3tiff.html
|
||||
TIFF* tif = TIFFOpen( m_filename.c_str(), "r" );
|
||||
|
||||
if( tif )
|
||||
{
|
||||
int wdth = 0, hght = 0, photometric = 0;
|
||||
uint32 wdth = 0, hght = 0;
|
||||
uint16 photometric = 0;
|
||||
m_tif = tif;
|
||||
|
||||
if( TIFFGetField( tif, TIFFTAG_IMAGEWIDTH, &wdth ) &&
|
||||
TIFFGetField( tif, TIFFTAG_IMAGELENGTH, &hght ) &&
|
||||
TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photometric ))
|
||||
{
|
||||
int bpp=8, ncn = photometric > 1 ? 3 : 1;
|
||||
uint16 bpp=8, ncn = photometric > 1 ? 3 : 1;
|
||||
TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE, &bpp );
|
||||
TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &ncn );
|
||||
|
||||
@@ -175,12 +178,12 @@ bool TiffDecoder::readData( Mat& img )
|
||||
if( m_tif && m_width && m_height )
|
||||
{
|
||||
TIFF* tif = (TIFF*)m_tif;
|
||||
int tile_width0 = m_width, tile_height0 = 0;
|
||||
uint32 tile_width0 = m_width, tile_height0 = 0;
|
||||
int x, y, i;
|
||||
int is_tiled = TIFFIsTiled(tif);
|
||||
int photometric;
|
||||
uint16 photometric;
|
||||
TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photometric );
|
||||
int bpp = 8, ncn = photometric > 1 ? 3 : 1;
|
||||
uint16 bpp = 8, ncn = photometric > 1 ? 3 : 1;
|
||||
TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE, &bpp );
|
||||
TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &ncn );
|
||||
const int bitsPerByte = 8;
|
||||
|
@@ -88,7 +88,7 @@ public:
|
||||
stringstream s;
|
||||
s << tag;
|
||||
|
||||
const string filename = "output_"+s.str()+".avi";
|
||||
const string filename = tempfile((s.str()+".avi").c_str());
|
||||
|
||||
try
|
||||
{
|
||||
|
@@ -408,8 +408,8 @@ TEST(Highgui_Tiff, decode_tile16384x16384)
|
||||
|
||||
try
|
||||
{
|
||||
cv::imread(file3);
|
||||
EXPECT_NO_THROW(cv::imread(file4));
|
||||
cv::imread(file3, CV_LOAD_IMAGE_UNCHANGED);
|
||||
EXPECT_NO_THROW(cv::imread(file4, CV_LOAD_IMAGE_UNCHANGED));
|
||||
}
|
||||
catch(const std::bad_alloc&)
|
||||
{
|
||||
@@ -420,6 +420,53 @@ TEST(Highgui_Tiff, decode_tile16384x16384)
|
||||
remove(file4.c_str());
|
||||
}
|
||||
|
||||
class CV_GrfmtReadTifTiledWithNotFullTiles: public cvtest::BaseTest
|
||||
{
|
||||
// see issue #2601 "16-bit Grayscale TIFF Load Failures Due to Buffer Underflow and Endianness"
|
||||
|
||||
// Setup data for two minimal 16-bit grayscale TIFF files in both endian formats
|
||||
uchar tiff_sample_data[2][86] = { {
|
||||
// Little endian
|
||||
0x49, 0x49, 0x2a, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xad, 0xde, 0xef, 0xbe, 0x06, 0x00, 0x00, 0x01,
|
||||
0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00,
|
||||
0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x01,
|
||||
0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x17, 0x01, 0x04, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x04, 0x00, 0x00, 0x00 }, {
|
||||
// Big endian
|
||||
0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x0c, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x06, 0x01, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00,
|
||||
0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10,
|
||||
0x00, 0x00, 0x01, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x11,
|
||||
0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x01, 0x17, 0x00, 0x04, 0x00, 0x00,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x04 }
|
||||
};
|
||||
|
||||
// Test imread() for both a little endian TIFF and big endian TIFF
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
string filename = cv::tempfile(".tiff");
|
||||
|
||||
// Write sample TIFF file
|
||||
FILE* fp = fopen(filename.c_str(), "wb");
|
||||
ASSERT_TRUE(fp != NULL);
|
||||
ASSERT_EQ((size_t)1, fwrite(tiff_sample_data, 86, 1, fp));
|
||||
fclose(fp);
|
||||
|
||||
Mat img = imread(filename, CV_LOAD_IMAGE_UNCHANGED);
|
||||
|
||||
EXPECT_EQ(1, img.rows);
|
||||
EXPECT_EQ(2, img.cols);
|
||||
EXPECT_EQ(CV_16U, img.type());
|
||||
EXPECT_EQ(sizeof(ushort), img.elemSize());
|
||||
EXPECT_EQ(1, img.channels());
|
||||
EXPECT_EQ(0xDEAD, img.at<ushort>(0,0));
|
||||
EXPECT_EQ(0xBEEF, img.at<ushort>(0,1));
|
||||
|
||||
remove(filename.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
class CV_GrfmtReadTifTiledWithNotFullTiles: public cvtest::BaseTest
|
||||
{
|
||||
public:
|
||||
|
@@ -332,9 +332,7 @@ void CV_HighGuiTest::VideoTest(const string& dir, const cvtest::VideoFormat& fmt
|
||||
}
|
||||
}
|
||||
|
||||
printf("Before saved release for %s\n", tmp_name.c_str());
|
||||
cvReleaseCapture( &saved );
|
||||
printf("After release\n");
|
||||
|
||||
ts->printf(ts->LOG, "end test function : ImagesVideo \n");
|
||||
}
|
||||
|
@@ -49,8 +49,8 @@ namespace
|
||||
class CLAHE_CalcLut_Body : public cv::ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
CLAHE_CalcLut_Body(const cv::Mat& src, cv::Mat& lut, cv::Size tileSize, int tilesX, int tilesY, int clipLimit, float lutScale) :
|
||||
src_(src), lut_(lut), tileSize_(tileSize), tilesX_(tilesX), tilesY_(tilesY), clipLimit_(clipLimit), lutScale_(lutScale)
|
||||
CLAHE_CalcLut_Body(const cv::Mat& src, cv::Mat& lut, cv::Size tileSize, int tilesX, int clipLimit, float lutScale) :
|
||||
src_(src), lut_(lut), tileSize_(tileSize), tilesX_(tilesX), clipLimit_(clipLimit), lutScale_(lutScale)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -62,7 +62,6 @@ namespace
|
||||
|
||||
cv::Size tileSize_;
|
||||
int tilesX_;
|
||||
int tilesY_;
|
||||
int clipLimit_;
|
||||
float lutScale_;
|
||||
};
|
||||
@@ -293,7 +292,7 @@ namespace
|
||||
clipLimit = std::max(clipLimit, 1);
|
||||
}
|
||||
|
||||
CLAHE_CalcLut_Body calcLutBody(srcForLut, lut_, tileSize, tilesX_, tilesY_, clipLimit, lutScale);
|
||||
CLAHE_CalcLut_Body calcLutBody(srcForLut, lut_, tileSize, tilesX_, clipLimit, lutScale);
|
||||
cv::parallel_for_(cv::Range(0, tilesX_ * tilesY_), calcLutBody);
|
||||
|
||||
CLAHE_Interpolation_Body interpolationBody(src, dst, lut_, tileSize, tilesX_, tilesY_);
|
||||
|
@@ -3214,7 +3214,7 @@ struct YUV420p2RGB888Invoker : ParallelLoopBody
|
||||
const int rangeBegin = range.start * 2;
|
||||
const int rangeEnd = range.end * 2;
|
||||
|
||||
size_t uvsteps[2] = {width/2, stride - width/2};
|
||||
int uvsteps[2] = {width/2, stride - width/2};
|
||||
int usIdx = ustepIdx, vsIdx = vstepIdx;
|
||||
|
||||
const uchar* y1 = my1 + rangeBegin * stride;
|
||||
@@ -3282,7 +3282,7 @@ struct YUV420p2RGBA8888Invoker : ParallelLoopBody
|
||||
int rangeBegin = range.start * 2;
|
||||
int rangeEnd = range.end * 2;
|
||||
|
||||
size_t uvsteps[2] = {width/2, stride - width/2};
|
||||
int uvsteps[2] = {width/2, stride - width/2};
|
||||
int usIdx = ustepIdx, vsIdx = vstepIdx;
|
||||
|
||||
const uchar* y1 = my1 + rangeBegin * stride;
|
||||
|
@@ -41,7 +41,7 @@
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
#if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
|
||||
#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
|
||||
# pragma GCC diagnostic ignored "-Warray-bounds"
|
||||
#endif
|
||||
|
||||
|
@@ -1217,8 +1217,13 @@ public:
|
||||
alpha(_alpha), _beta(__beta), ssize(_ssize), dsize(_dsize),
|
||||
ksize(_ksize), xmin(_xmin), xmax(_xmax)
|
||||
{
|
||||
CV_Assert(ksize <= MAX_ESIZE);
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Warray-bounds"
|
||||
#endif
|
||||
virtual void operator() (const Range& range) const
|
||||
{
|
||||
int dy, cn = src.channels();
|
||||
@@ -1267,6 +1272,9 @@ public:
|
||||
vresize( (const WT**)rows, (T*)(dst.data + dst.step*dy), beta, dsize.width );
|
||||
}
|
||||
}
|
||||
#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
private:
|
||||
Mat src;
|
||||
@@ -1274,7 +1282,9 @@ private:
|
||||
const int* xofs, *yofs;
|
||||
const AT* alpha, *_beta;
|
||||
Size ssize, dsize;
|
||||
int ksize, xmin, xmax;
|
||||
const int ksize, xmin, xmax;
|
||||
|
||||
resizeGeneric_Invoker& operator = (const resizeGeneric_Invoker&);
|
||||
};
|
||||
|
||||
template<class HResize, class VResize>
|
||||
|
@@ -197,6 +197,10 @@ static void icvContourMoments( CvSeq* contour, CvMoments* moments )
|
||||
\****************************************************************************************/
|
||||
|
||||
template<typename T, typename WT, typename MT>
|
||||
#if defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ >= 5 && __GNUC_MINOR__ < 9
|
||||
// Workaround for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60196
|
||||
__attribute__((optimize("no-tree-vectorize")))
|
||||
#endif
|
||||
static void momentsInTile( const cv::Mat& img, double* moments )
|
||||
{
|
||||
cv::Size size = img.size();
|
||||
|
@@ -718,7 +718,7 @@ void cv::boxFilter( InputArray _src, OutputArray _dst, int ddepth,
|
||||
ddepth = sdepth;
|
||||
_dst.create( src.size(), CV_MAKETYPE(ddepth, cn) );
|
||||
Mat dst = _dst.getMat();
|
||||
if( borderType != BORDER_CONSTANT && normalize )
|
||||
if( borderType != BORDER_CONSTANT && normalize && (borderType & BORDER_ISOLATED) != 0 )
|
||||
{
|
||||
if( src.rows == 1 )
|
||||
ksize.height = 1;
|
||||
|
@@ -1225,7 +1225,7 @@ CV_FitLineTest::CV_FitLineTest()
|
||||
max_noise = 0.05;
|
||||
}
|
||||
|
||||
#if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
|
||||
#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Warray-bounds"
|
||||
#endif
|
||||
@@ -1301,7 +1301,7 @@ void CV_FitLineTest::generate_point_set( void* pointsSet )
|
||||
}
|
||||
}
|
||||
|
||||
#if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
|
||||
#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
@@ -1329,7 +1329,7 @@ void CV_FitLineTest::run_func()
|
||||
cv::fitLine(cv::cvarrToMat(points), (cv::Vec6f&)line[0], dist_type, 0, reps, aeps);
|
||||
}
|
||||
|
||||
#if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
|
||||
#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Warray-bounds"
|
||||
#endif
|
||||
@@ -1412,7 +1412,7 @@ _exit_:
|
||||
return code;
|
||||
}
|
||||
|
||||
#if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
|
||||
#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
|
@@ -1886,3 +1886,35 @@ protected:
|
||||
};
|
||||
|
||||
TEST(Imgproc_Filtering, supportedFormats) { CV_FilterSupportedFormatsTest test; test.safe_run(); }
|
||||
|
||||
TEST(Imgproc_Blur, borderTypes)
|
||||
{
|
||||
Size kernelSize(3, 3);
|
||||
|
||||
/// ksize > src_roi.size()
|
||||
Mat src(3, 3, CV_8UC1, cv::Scalar::all(255)), dst;
|
||||
Mat src_roi = src(Rect(1, 1, 1, 1));
|
||||
src_roi.setTo(cv::Scalar::all(0));
|
||||
|
||||
// should work like !BORDER_ISOLATED
|
||||
blur(src_roi, dst, kernelSize, Point(-1, -1), BORDER_REPLICATE);
|
||||
EXPECT_EQ(227, dst.at<uchar>(0, 0));
|
||||
|
||||
// should work like BORDER_ISOLATED
|
||||
blur(src_roi, dst, kernelSize, Point(-1, -1), BORDER_REPLICATE | BORDER_ISOLATED);
|
||||
EXPECT_EQ(0, dst.at<uchar>(0, 0));
|
||||
|
||||
/// ksize <= src_roi.size()
|
||||
src = Mat(5, 5, CV_8UC1, cv::Scalar(255));
|
||||
src_roi = src(Rect(1, 1, 3, 3));
|
||||
src_roi.setTo(0);
|
||||
src.at<uchar>(2, 2) = 255;
|
||||
|
||||
// should work like !BORDER_ISOLATED
|
||||
blur(src_roi, dst, kernelSize, Point(-1, -1), BORDER_REPLICATE);
|
||||
Mat expected_dst =
|
||||
(Mat_<uchar>(3, 3) << 170, 113, 170, 113, 28, 113, 170, 113, 170);
|
||||
EXPECT_EQ(expected_dst.type(), dst.type());
|
||||
EXPECT_EQ(expected_dst.size(), dst.size());
|
||||
EXPECT_DOUBLE_EQ(0.0, cvtest::norm(expected_dst, dst, NORM_INF));
|
||||
}
|
||||
|
@@ -266,7 +266,7 @@ if(ANDROID)
|
||||
else(ANDROID)
|
||||
set(JAR_NAME opencv-${LIB_NAME_SUFIX}.jar)
|
||||
set(JAR_FILE "${OpenCV_BINARY_DIR}/bin/${JAR_NAME}")
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/build.xml.in" "${OpenCV_BINARY_DIR}/build.xml" IMMEDIATE @ONLY)
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/build.xml.in" "${OpenCV_BINARY_DIR}/build.xml" @ONLY)
|
||||
list(APPEND step3_depends "${OpenCV_BINARY_DIR}/build.xml")
|
||||
|
||||
add_custom_command(OUTPUT "${JAR_FILE}" "${JAR_FILE}.dephelper"
|
||||
|
@@ -329,7 +329,10 @@ JNIEXPORT jstring JNICALL Java_org_opencv_highgui_VideoCapture_n_1getSupportedPr
|
||||
VideoCapture* me = (VideoCapture*) self; //TODO: check for NULL
|
||||
union {double prop; const char* name;} u;
|
||||
u.prop = me->get(CV_CAP_PROP_SUPPORTED_PREVIEW_SIZES_STRING);
|
||||
return env->NewStringUTF(u.name);
|
||||
// VideoCapture::get can return 0.0 or -1.0 if it doesn't support
|
||||
// CV_CAP_PROP_SUPPORTED_PREVIEW_SIZES_STRING
|
||||
if (u.prop != 0.0 && u.prop != -1.0)
|
||||
return env->NewStringUTF(u.name);
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
|
@@ -48,7 +48,17 @@ public class OpenCVLoader
|
||||
*/
|
||||
public static boolean initDebug()
|
||||
{
|
||||
return StaticHelper.initOpenCV();
|
||||
return StaticHelper.initOpenCV(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads and initializes OpenCV library from current application package. Roughly, it's an analog of system.loadLibrary("opencv_java").
|
||||
* @param InitCuda load and initialize CUDA runtime libraries.
|
||||
* @return Returns true is initialization of OpenCV was successful.
|
||||
*/
|
||||
public static boolean initDebug(boolean InitCuda)
|
||||
{
|
||||
return StaticHelper.initOpenCV(InitCuda);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -7,11 +7,21 @@ import android.util.Log;
|
||||
|
||||
class StaticHelper {
|
||||
|
||||
public static boolean initOpenCV()
|
||||
public static boolean initOpenCV(boolean InitCuda)
|
||||
{
|
||||
boolean result;
|
||||
String libs = "";
|
||||
|
||||
if(InitCuda)
|
||||
{
|
||||
loadLibrary("cudart");
|
||||
loadLibrary("nppc");
|
||||
loadLibrary("nppi");
|
||||
loadLibrary("npps");
|
||||
loadLibrary("cufft");
|
||||
loadLibrary("cublas");
|
||||
}
|
||||
|
||||
Log.d(TAG, "Trying to get library list");
|
||||
|
||||
try
|
||||
@@ -52,7 +62,7 @@ class StaticHelper {
|
||||
try
|
||||
{
|
||||
System.loadLibrary(Name);
|
||||
Log.d(TAG, "OpenCV libs init was ok!");
|
||||
Log.d(TAG, "Library " + Name + " loaded");
|
||||
}
|
||||
catch(UnsatisfiedLinkError e)
|
||||
{
|
||||
|
@@ -87,7 +87,6 @@ public class TermCriteria {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (this == null) return "null";
|
||||
return "{ type: " + type + ", maxCount: " + maxCount + ", epsilon: " + epsilon + "}";
|
||||
}
|
||||
}
|
||||
|
@@ -415,7 +415,7 @@ CV_INLINE int _icvRemoveShadowGMM(float* data, int nD,
|
||||
//IEEE Trans. on Pattern Analysis and Machine Intelligence, vol.26, no.5, pages 651-656, 2004
|
||||
//http://www.zoranz.net/Publications/zivkovic2004PAMI.pdf
|
||||
|
||||
#if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
|
||||
#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||
#endif
|
||||
@@ -608,7 +608,7 @@ CV_INLINE int _icvUpdateGMM(float* data, int nD,
|
||||
return bBackground;
|
||||
}
|
||||
|
||||
#if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
|
||||
#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
|
@@ -200,6 +200,7 @@ void RFace::CalculateError(FaceData * lpFaceData)
|
||||
void RFace::CreateFace(void * lpData)
|
||||
{
|
||||
FaceData Data;
|
||||
memset(&Data, 0, sizeof(FaceData));
|
||||
|
||||
double Error = MAX_ERROR;
|
||||
double CurError = MAX_ERROR;
|
||||
|
@@ -163,7 +163,7 @@ icvLMedS( int *points1, int *points2, int numPoints, CvMatrix3 * fundamentalMatr
|
||||
/*===========================================================================*/
|
||||
/*===========================================================================*/
|
||||
|
||||
#if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
|
||||
#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Warray-bounds"
|
||||
#endif
|
||||
@@ -328,7 +328,7 @@ icvCubic( double a2, double a1, double a0, double *squares )
|
||||
return CV_NO_ERR;
|
||||
} /* icvCubic */
|
||||
|
||||
#if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
|
||||
#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
|
@@ -3,10 +3,10 @@ if(BUILD_ANDROID_PACKAGE)
|
||||
endif()
|
||||
|
||||
set(the_description "Functionality with possible limitations on the use")
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef)
|
||||
if (ENABLE_DYNAMIC_CUDA)
|
||||
set(HAVE_CUDA FALSE)
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef -Wshadow)
|
||||
if(ENABLE_DYNAMIC_CUDA)
|
||||
add_definitions(-DDYNAMIC_CUDA_SUPPORT)
|
||||
ocv_define_module(nonfree opencv_imgproc opencv_features2d opencv_calib3d OPTIONAL opencv_ocl)
|
||||
else()
|
||||
ocv_define_module(nonfree opencv_imgproc opencv_features2d opencv_calib3d OPTIONAL opencv_gpu opencv_ocl)
|
||||
endif()
|
||||
endif()
|
||||
|
@@ -43,11 +43,7 @@
|
||||
#ifndef __OPENCV_NONFREE_GPU_HPP__
|
||||
#define __OPENCV_NONFREE_GPU_HPP__
|
||||
|
||||
#include "opencv2/opencv_modules.hpp"
|
||||
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
|
||||
#include "opencv2/gpu/gpu.hpp"
|
||||
#include "opencv2/core/gpumat.hpp"
|
||||
|
||||
namespace cv { namespace gpu {
|
||||
|
||||
@@ -129,6 +125,4 @@ public:
|
||||
|
||||
} // namespace cv
|
||||
|
||||
#endif // defined(HAVE_OPENCV_GPU)
|
||||
|
||||
#endif // __OPENCV_NONFREE_GPU_HPP__
|
||||
|
@@ -42,7 +42,9 @@
|
||||
|
||||
#include "perf_precomp.hpp"
|
||||
|
||||
#if defined(HAVE_OPENCV_GPU) && defined(HAVE_CUDA)
|
||||
#include "cvconfig.h"
|
||||
|
||||
#if defined(HAVE_OPENCV_GPU) && defined(HAVE_CUDA) && !defined(DYNAMIC_CUDA_SUPPORT)
|
||||
|
||||
#include "opencv2/ts/gpu_perf.hpp"
|
||||
|
||||
|
@@ -4,6 +4,9 @@
|
||||
static const char * impls[] = {
|
||||
#ifdef HAVE_CUDA
|
||||
"cuda",
|
||||
#endif
|
||||
#ifdef HAVE_OPENCL
|
||||
"ocl",
|
||||
#endif
|
||||
"plain"
|
||||
};
|
||||
|
@@ -57,55 +57,68 @@ typedef perf::TestBaseWithParam<std::string> OCL_SURF;
|
||||
"cv/detectors_descriptors_evaluation/images_datasets/leuven/img1.png",\
|
||||
"stitching/a3.png"
|
||||
|
||||
PERF_TEST_P(OCL_SURF, DISABLED_with_data_transfer, testing::Values(SURF_IMAGES))
|
||||
#define OCL_TEST_CYCLE() for( ; startTimer(), next(); cv::ocl::finish(), stopTimer())
|
||||
|
||||
PERF_TEST_P(OCL_SURF, with_data_transfer, testing::Values(SURF_IMAGES))
|
||||
{
|
||||
string filename = getDataPath(GetParam());
|
||||
Mat img = imread(filename, IMREAD_GRAYSCALE);
|
||||
ASSERT_FALSE(img.empty());
|
||||
|
||||
SURF_OCL d_surf;
|
||||
oclMat d_keypoints;
|
||||
oclMat d_descriptors;
|
||||
Mat cpu_kp;
|
||||
Mat cpu_dp;
|
||||
Mat src = imread(filename, IMREAD_GRAYSCALE);
|
||||
ASSERT_FALSE(src.empty());
|
||||
|
||||
Mat cpu_kp, cpu_dp;
|
||||
declare.time(60);
|
||||
|
||||
TEST_CYCLE()
|
||||
if (getSelectedImpl() == "ocl")
|
||||
{
|
||||
oclMat d_src(img);
|
||||
SURF_OCL d_surf;
|
||||
oclMat d_keypoints, d_descriptors;
|
||||
|
||||
d_surf(d_src, oclMat(), d_keypoints, d_descriptors);
|
||||
OCL_TEST_CYCLE()
|
||||
{
|
||||
oclMat d_src(src);
|
||||
|
||||
d_keypoints.download(cpu_kp);
|
||||
d_descriptors.download(cpu_dp);
|
||||
d_surf(d_src, oclMat(), d_keypoints, d_descriptors);
|
||||
|
||||
d_keypoints.download(cpu_kp);
|
||||
d_descriptors.download(cpu_dp);
|
||||
}
|
||||
}
|
||||
else if (getSelectedImpl() == "plain")
|
||||
{
|
||||
cv::SURF surf;
|
||||
std::vector<cv::KeyPoint> kp;
|
||||
|
||||
TEST_CYCLE() surf(src, Mat(), kp, cpu_dp);
|
||||
}
|
||||
|
||||
SANITY_CHECK(cpu_kp, 1);
|
||||
SANITY_CHECK(cpu_dp, 1);
|
||||
SANITY_CHECK_NOTHING();
|
||||
}
|
||||
|
||||
PERF_TEST_P(OCL_SURF, DISABLED_without_data_transfer, testing::Values(SURF_IMAGES))
|
||||
PERF_TEST_P(OCL_SURF, without_data_transfer, testing::Values(SURF_IMAGES))
|
||||
{
|
||||
string filename = getDataPath(GetParam());
|
||||
Mat img = imread(filename, IMREAD_GRAYSCALE);
|
||||
ASSERT_FALSE(img.empty());
|
||||
|
||||
SURF_OCL d_surf;
|
||||
oclMat d_keypoints;
|
||||
oclMat d_descriptors;
|
||||
oclMat d_src(img);
|
||||
Mat src = imread(filename, IMREAD_GRAYSCALE);
|
||||
ASSERT_FALSE(src.empty());
|
||||
|
||||
Mat cpu_kp, cpu_dp;
|
||||
declare.time(60);
|
||||
|
||||
TEST_CYCLE() d_surf(d_src, oclMat(), d_keypoints, d_descriptors);
|
||||
if (getSelectedImpl() == "ocl")
|
||||
{
|
||||
SURF_OCL d_surf;
|
||||
oclMat d_keypoints, d_descriptors, d_src(src);
|
||||
|
||||
Mat cpu_kp;
|
||||
Mat cpu_dp;
|
||||
d_keypoints.download(cpu_kp);
|
||||
d_descriptors.download(cpu_dp);
|
||||
SANITY_CHECK(cpu_kp, 1);
|
||||
SANITY_CHECK(cpu_dp, 1);
|
||||
OCL_TEST_CYCLE() d_surf(d_src, oclMat(), d_keypoints, d_descriptors);
|
||||
}
|
||||
else if (getSelectedImpl() == "plain")
|
||||
{
|
||||
cv::SURF surf;
|
||||
std::vector<cv::KeyPoint> kp;
|
||||
|
||||
TEST_CYCLE() surf(src, Mat(), kp, cpu_dp);
|
||||
}
|
||||
|
||||
SANITY_CHECK_NOTHING();
|
||||
}
|
||||
|
||||
#endif // HAVE_OPENCV_OCL
|
@@ -42,7 +42,7 @@
|
||||
|
||||
#include "opencv2/opencv_modules.hpp"
|
||||
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(DYNAMIC_CUDA_SUPPORT)
|
||||
|
||||
#include "opencv2/gpu/device/common.hpp"
|
||||
#include "opencv2/gpu/device/limits.hpp"
|
||||
|
@@ -51,17 +51,14 @@
|
||||
#include "opencv2/imgproc/imgproc.hpp"
|
||||
#include "opencv2/core/internal.hpp"
|
||||
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
#include "opencv2/nonfree/gpu.hpp"
|
||||
#include "opencv2/nonfree/gpu.hpp"
|
||||
|
||||
#if defined(HAVE_CUDA)
|
||||
#include "opencv2/gpu/stream_accessor.hpp"
|
||||
#include "opencv2/gpu/device/common.hpp"
|
||||
|
||||
static inline void throw_nogpu() { CV_Error(CV_StsNotImplemented, "The called functionality is disabled for current build or platform"); }
|
||||
#else
|
||||
static inline void throw_nogpu() { CV_Error(CV_GpuNotSupported, "The library is compiled without GPU support"); }
|
||||
#endif
|
||||
#if defined(HAVE_CUDA) && defined(HAVE_OPENCV_GPU) && !defined(DYNAMIC_CUDA_SUPPORT)
|
||||
#include "opencv2/gpu/stream_accessor.hpp"
|
||||
#include "opencv2/gpu/device/common.hpp"
|
||||
static inline void throw_nogpu() { CV_Error(CV_StsNotImplemented, "The called functionality is disabled for current build or platform"); }
|
||||
#else
|
||||
static inline void throw_nogpu() { CV_Error(CV_GpuNotSupported, "The library is compiled without GPU support"); }
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENCV_OCL
|
||||
|
@@ -42,12 +42,10 @@
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
|
||||
using namespace cv;
|
||||
using namespace cv::gpu;
|
||||
|
||||
#if !defined (HAVE_CUDA)
|
||||
#if !defined (HAVE_CUDA) || !defined(HAVE_OPENCV_GPU) || defined(DYNAMIC_CUDA_SUPPORT)
|
||||
|
||||
cv::gpu::SURF_GPU::SURF_GPU() { throw_nogpu(); }
|
||||
cv::gpu::SURF_GPU::SURF_GPU(double, int, int, bool, float, bool) { throw_nogpu(); }
|
||||
@@ -421,5 +419,3 @@ void cv::gpu::SURF_GPU::releaseMemory()
|
||||
}
|
||||
|
||||
#endif // !defined (HAVE_CUDA)
|
||||
|
||||
#endif // defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
|
@@ -42,7 +42,9 @@
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
#if defined(HAVE_OPENCV_GPU) && defined(HAVE_CUDA)
|
||||
#include "cvconfig.h"
|
||||
|
||||
#if defined(HAVE_OPENCV_GPU) && defined(HAVE_CUDA) && !defined(DYNAMIC_CUDA_SUPPORT)
|
||||
|
||||
using namespace cvtest;
|
||||
|
||||
|
@@ -95,10 +95,11 @@ typedef perf::TestBaseWithParam<OCL_Cascade_Image_MinSize_t> OCL_Cascade_Image_M
|
||||
|
||||
PERF_TEST_P( OCL_Cascade_Image_MinSize, CascadeClassifier,
|
||||
testing::Combine(
|
||||
testing::Values( string("cv/cascadeandhog/cascades/haarcascade_frontalface_alt.xml") ),
|
||||
testing::Values( string("cv/cascadeandhog/cascades/haarcascade_frontalface_alt.xml"),
|
||||
string("cv/cascadeandhog/cascades/haarcascade_frontalface_alt2.xml") ),
|
||||
testing::Values( string("cv/shared/lena.png"),
|
||||
string("cv/cascadeandhog/images/bttf301.png"),
|
||||
string("cv/cascadeandhog/images/class57.png") ),
|
||||
string("cv/cascadeandhog/images/bttf301.png")/*,
|
||||
string("cv/cascadeandhog/images/class57.png")*/ ),
|
||||
testing::Values(30, 64, 90) ) )
|
||||
{
|
||||
const string cascasePath = get<0>(GetParam());
|
||||
|
@@ -106,4 +106,108 @@ PERF_TEST_P(KNNFixture, KNN,
|
||||
}else
|
||||
OCL_PERF_ELSE
|
||||
SANITY_CHECK(best_label);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
typedef TestBaseWithParam<tuple<int> > SVMFixture;
|
||||
|
||||
// code is based on: samples\cpp\tutorial_code\ml\non_linear_svms\non_linear_svms.cpp
|
||||
PERF_TEST_P(SVMFixture, DISABLED_SVM,
|
||||
testing::Values(50, 100))
|
||||
{
|
||||
|
||||
const int NTRAINING_SAMPLES = get<0>(GetParam()); // Number of training samples per class
|
||||
|
||||
#define FRAC_LINEAR_SEP 0.9f // Fraction of samples which compose the linear separable part
|
||||
|
||||
const int WIDTH = 512, HEIGHT = 512;
|
||||
|
||||
Mat trainData(2*NTRAINING_SAMPLES, 2, CV_32FC1);
|
||||
Mat labels (2*NTRAINING_SAMPLES, 1, CV_32FC1);
|
||||
|
||||
RNG rng(100); // Random value generation class
|
||||
|
||||
// Set up the linearly separable part of the training data
|
||||
int nLinearSamples = (int) (FRAC_LINEAR_SEP * NTRAINING_SAMPLES);
|
||||
|
||||
// Generate random points for the class 1
|
||||
Mat trainClass = trainData.rowRange(0, nLinearSamples);
|
||||
// The x coordinate of the points is in [0, 0.4)
|
||||
Mat c = trainClass.colRange(0, 1);
|
||||
rng.fill(c, RNG::UNIFORM, Scalar(1), Scalar(0.4 * WIDTH));
|
||||
// The y coordinate of the points is in [0, 1)
|
||||
c = trainClass.colRange(1,2);
|
||||
rng.fill(c, RNG::UNIFORM, Scalar(1), Scalar(HEIGHT));
|
||||
|
||||
// Generate random points for the class 2
|
||||
trainClass = trainData.rowRange(2*NTRAINING_SAMPLES-nLinearSamples, 2*NTRAINING_SAMPLES);
|
||||
// The x coordinate of the points is in [0.6, 1]
|
||||
c = trainClass.colRange(0 , 1);
|
||||
rng.fill(c, RNG::UNIFORM, Scalar(0.6*WIDTH), Scalar(WIDTH));
|
||||
// The y coordinate of the points is in [0, 1)
|
||||
c = trainClass.colRange(1,2);
|
||||
rng.fill(c, RNG::UNIFORM, Scalar(1), Scalar(HEIGHT));
|
||||
|
||||
//------------------ Set up the non-linearly separable part of the training data ---------------
|
||||
|
||||
// Generate random points for the classes 1 and 2
|
||||
trainClass = trainData.rowRange( nLinearSamples, 2*NTRAINING_SAMPLES-nLinearSamples);
|
||||
// The x coordinate of the points is in [0.4, 0.6)
|
||||
c = trainClass.colRange(0,1);
|
||||
rng.fill(c, RNG::UNIFORM, Scalar(0.4*WIDTH), Scalar(0.6*WIDTH));
|
||||
// The y coordinate of the points is in [0, 1)
|
||||
c = trainClass.colRange(1,2);
|
||||
rng.fill(c, RNG::UNIFORM, Scalar(1), Scalar(HEIGHT));
|
||||
|
||||
//------------------------- Set up the labels for the classes ---------------------------------
|
||||
labels.rowRange( 0, NTRAINING_SAMPLES).setTo(1); // Class 1
|
||||
labels.rowRange(NTRAINING_SAMPLES, 2*NTRAINING_SAMPLES).setTo(2); // Class 2
|
||||
|
||||
//------------------------ Set up the support vector machines parameters --------------------
|
||||
CvSVMParams params;
|
||||
params.svm_type = SVM::C_SVC;
|
||||
params.C = 0.1;
|
||||
params.kernel_type = SVM::LINEAR;
|
||||
params.term_crit = TermCriteria(CV_TERMCRIT_ITER, (int)1e7, 1e-6);
|
||||
|
||||
Mat dst = Mat::zeros(HEIGHT, WIDTH, CV_8UC1);
|
||||
|
||||
Mat samples(WIDTH*HEIGHT, 2, CV_32FC1);
|
||||
int k = 0;
|
||||
for (int i = 0; i < HEIGHT; ++i)
|
||||
{
|
||||
for (int j = 0; j < WIDTH; ++j)
|
||||
{
|
||||
samples.at<float>(k, 0) = (float)i;
|
||||
samples.at<float>(k, 0) = (float)j;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
Mat results(WIDTH*HEIGHT, 1, CV_32FC1);
|
||||
|
||||
CvMat samples_ = samples;
|
||||
CvMat results_ = results;
|
||||
|
||||
if(RUN_PLAIN_IMPL)
|
||||
{
|
||||
CvSVM svm;
|
||||
svm.train(trainData, labels, Mat(), Mat(), params);
|
||||
TEST_CYCLE()
|
||||
{
|
||||
svm.predict(&samples_, &results_);
|
||||
}
|
||||
}
|
||||
else if(RUN_OCL_IMPL)
|
||||
{
|
||||
CvSVM_OCL svm;
|
||||
svm.train(trainData, labels, Mat(), Mat(), params);
|
||||
OCL_TEST_CYCLE()
|
||||
{
|
||||
svm.predict(&samples_, &results_);
|
||||
}
|
||||
}
|
||||
else
|
||||
OCL_PERF_ELSE
|
||||
|
||||
SANITY_CHECK_NOTHING();
|
||||
}
|
||||
|
@@ -66,7 +66,7 @@ __kernel void arithm_pow(__global VT * src, int src_step, int src_offset,
|
||||
int dst_index = mad24(y, dst_step, x + dst_offset);
|
||||
|
||||
VT src_data = src[src_index];
|
||||
VT tmp = src_data > 0 ? exp(p * log(src_data)) : (src_data == 0 ? 0 : exp(p * log(fabs(src_data))));
|
||||
VT tmp = src_data > (VT)0 ? (VT)exp(p * log(src_data)) : (src_data == (VT)0 ? (VT)0 : (VT)exp(p * log(fabs(src_data))));
|
||||
|
||||
dst[dst_index] = tmp;
|
||||
}
|
||||
|
@@ -83,10 +83,10 @@ __kernel void resizeLN_C1_D0(__global uchar * dst, __global uchar const * restri
|
||||
int y = floor(sy);
|
||||
float v = sy - y;
|
||||
|
||||
u = x < 0 ? 0 : u;
|
||||
u = (x >= src_cols) ? 0 : u;
|
||||
x = x < 0 ? 0 : x;
|
||||
x = (x >= src_cols) ? src_cols-1 : x;
|
||||
u = x < (int4)0 ? (float4)0 : u;
|
||||
u = (x >= (int4)src_cols) ? (float4)0 : u;
|
||||
x = x < (int4)0 ? (int4)0 : x;
|
||||
x = (x >= (int4)src_cols) ? (int4)(src_cols-1) : x;
|
||||
|
||||
y<0 ? y=0,v=0 : y;
|
||||
y>=src_rows ? y=src_rows-1,v=0 : y;
|
||||
|
@@ -1,6 +1,7 @@
|
||||
set(the_description "Images stitching")
|
||||
if (ENABLE_DYNAMIC_CUDA)
|
||||
if(ENABLE_DYNAMIC_CUDA)
|
||||
add_definitions(-DDYNAMIC_CUDA_SUPPORT)
|
||||
ocv_define_module(stitching opencv_imgproc opencv_features2d opencv_calib3d opencv_objdetect OPTIONAL opencv_nonfree)
|
||||
else()
|
||||
ocv_define_module(stitching opencv_imgproc opencv_features2d opencv_calib3d opencv_objdetect OPTIONAL opencv_gpu opencv_nonfree)
|
||||
endif()
|
||||
endif()
|
||||
|
@@ -44,11 +44,12 @@
|
||||
#define __OPENCV_STITCHING_MATCHERS_HPP__
|
||||
|
||||
#include "opencv2/core/core.hpp"
|
||||
#include "opencv2/core/gpumat.hpp"
|
||||
#include "opencv2/features2d/features2d.hpp"
|
||||
|
||||
#include "opencv2/opencv_modules.hpp"
|
||||
|
||||
#if defined(HAVE_OPENCV_NONFREE) && defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
#if defined(HAVE_OPENCV_NONFREE)
|
||||
#include "opencv2/nonfree/gpu.hpp"
|
||||
#endif
|
||||
|
||||
@@ -104,7 +105,7 @@ private:
|
||||
};
|
||||
|
||||
|
||||
#if defined(HAVE_OPENCV_NONFREE) && defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
#if defined(HAVE_OPENCV_NONFREE)
|
||||
class CV_EXPORTS SurfFeaturesFinderGpu : public FeaturesFinder
|
||||
{
|
||||
public:
|
||||
|
@@ -45,7 +45,7 @@
|
||||
|
||||
#include <set>
|
||||
#include "opencv2/core/core.hpp"
|
||||
#include "opencv2/opencv_modules.hpp"
|
||||
#include "opencv2/core/gpumat.hpp"
|
||||
|
||||
namespace cv {
|
||||
namespace detail {
|
||||
@@ -227,7 +227,6 @@ private:
|
||||
};
|
||||
|
||||
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
class CV_EXPORTS GraphCutSeamFinderGpu : public GraphCutSeamFinderBase, public PairwiseSeamFinder
|
||||
{
|
||||
public:
|
||||
@@ -251,7 +250,6 @@ private:
|
||||
float terminal_cost_;
|
||||
float bad_region_penalty_;
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
} // namespace cv
|
||||
|
@@ -44,11 +44,8 @@
|
||||
#define __OPENCV_STITCHING_WARPERS_HPP__
|
||||
|
||||
#include "opencv2/core/core.hpp"
|
||||
#include "opencv2/core/gpumat.hpp"
|
||||
#include "opencv2/imgproc/imgproc.hpp"
|
||||
#include "opencv2/opencv_modules.hpp"
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
# include "opencv2/gpu/gpu.hpp"
|
||||
#endif
|
||||
|
||||
namespace cv {
|
||||
namespace detail {
|
||||
@@ -331,7 +328,6 @@ public:
|
||||
};
|
||||
|
||||
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
class CV_EXPORTS PlaneWarperGpu : public PlaneWarper
|
||||
{
|
||||
public:
|
||||
@@ -448,7 +444,6 @@ public:
|
||||
private:
|
||||
gpu::GpuMat d_xmap_, d_ymap_, d_src_, d_dst_;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
struct SphericalPortraitProjector : ProjectorBase
|
||||
|
@@ -145,7 +145,6 @@ public:
|
||||
|
||||
|
||||
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
class PlaneWarperGpu: public WarperCreator
|
||||
{
|
||||
public:
|
||||
@@ -165,7 +164,6 @@ class SphericalWarperGpu: public WarperCreator
|
||||
public:
|
||||
Ptr<detail::RotationWarper> create(float scale) const { return new detail::SphericalWarperGpu(scale); }
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace cv
|
||||
|
||||
|
@@ -189,7 +189,7 @@ Rect FeatherBlender::createWeightMaps(const vector<Mat> &masks, const vector<Poi
|
||||
MultiBandBlender::MultiBandBlender(int try_gpu, int num_bands, int weight_type)
|
||||
{
|
||||
setNumBands(num_bands);
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(DYNAMIC_CUDA_SUPPORT)
|
||||
can_use_gpu_ = try_gpu && gpu::getCudaEnabledDeviceCount();
|
||||
#else
|
||||
(void)try_gpu;
|
||||
@@ -491,7 +491,7 @@ void createLaplacePyr(const Mat &img, int num_levels, vector<Mat> &pyr)
|
||||
|
||||
void createLaplacePyrGpu(const Mat &img, int num_levels, vector<Mat> &pyr)
|
||||
{
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(DYNAMIC_CUDA_SUPPORT)
|
||||
pyr.resize(num_levels + 1);
|
||||
|
||||
vector<gpu::GpuMat> gpu_pyr(num_levels + 1);
|
||||
@@ -512,6 +512,7 @@ void createLaplacePyrGpu(const Mat &img, int num_levels, vector<Mat> &pyr)
|
||||
(void)img;
|
||||
(void)num_levels;
|
||||
(void)pyr;
|
||||
CV_Error(CV_StsNotImplemented, "CUDA optimization is unavailable");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -531,7 +532,7 @@ void restoreImageFromLaplacePyr(vector<Mat> &pyr)
|
||||
|
||||
void restoreImageFromLaplacePyrGpu(vector<Mat> &pyr)
|
||||
{
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(DYNAMIC_CUDA_SUPPORT)
|
||||
if (pyr.empty())
|
||||
return;
|
||||
|
||||
@@ -549,6 +550,7 @@ void restoreImageFromLaplacePyrGpu(vector<Mat> &pyr)
|
||||
gpu_pyr[0].download(pyr[0]);
|
||||
#else
|
||||
(void)pyr;
|
||||
CV_Error(CV_StsNotImplemented, "CUDA optimization is unavailable");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -45,10 +45,7 @@
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
using namespace cv::detail;
|
||||
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
using namespace cv::gpu;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENCV_NONFREE
|
||||
#include "opencv2/nonfree/nonfree.hpp"
|
||||
@@ -129,7 +126,7 @@ private:
|
||||
float match_conf_;
|
||||
};
|
||||
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(DYNAMIC_CUDA_SUPPORT)
|
||||
class GpuMatcher : public FeaturesMatcher
|
||||
{
|
||||
public:
|
||||
@@ -204,7 +201,7 @@ void CpuMatcher::match(const ImageFeatures &features1, const ImageFeatures &feat
|
||||
LOG("1->2 & 2->1 matches: " << matches_info.matches.size() << endl);
|
||||
}
|
||||
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(DYNAMIC_CUDA_SUPPORT)
|
||||
void GpuMatcher::match(const ImageFeatures &features1, const ImageFeatures &features2, MatchesInfo& matches_info)
|
||||
{
|
||||
matches_info.matches.clear();
|
||||
@@ -432,7 +429,7 @@ void OrbFeaturesFinder::find(const Mat &image, ImageFeatures &features)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(HAVE_OPENCV_NONFREE) && defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
#if defined(HAVE_OPENCV_NONFREE) && defined(HAVE_OPENCV_GPU) && !defined(DYNAMIC_CUDA_SUPPORT)
|
||||
SurfFeaturesFinderGpu::SurfFeaturesFinderGpu(double hess_thresh, int num_octaves, int num_layers,
|
||||
int num_octaves_descr, int num_layers_descr)
|
||||
{
|
||||
@@ -478,6 +475,29 @@ void SurfFeaturesFinderGpu::collectGarbage()
|
||||
keypoints_.release();
|
||||
descriptors_.release();
|
||||
}
|
||||
#elif defined(HAVE_OPENCV_NONFREE)
|
||||
SurfFeaturesFinderGpu::SurfFeaturesFinderGpu(double hess_thresh, int num_octaves, int num_layers,
|
||||
int num_octaves_descr, int num_layers_descr)
|
||||
{
|
||||
(void)hess_thresh;
|
||||
(void)num_octaves;
|
||||
(void)num_layers;
|
||||
(void)num_octaves_descr;
|
||||
(void)num_layers_descr;
|
||||
CV_Error(CV_StsNotImplemented, "CUDA optimization is unavailable");
|
||||
}
|
||||
|
||||
|
||||
void SurfFeaturesFinderGpu::find(const Mat &image, ImageFeatures &features)
|
||||
{
|
||||
(void)image;
|
||||
(void)features;
|
||||
CV_Error(CV_StsNotImplemented, "CUDA optimization is unavailable");
|
||||
}
|
||||
|
||||
void SurfFeaturesFinderGpu::collectGarbage()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -533,7 +553,7 @@ void FeaturesMatcher::operator ()(const vector<ImageFeatures> &features, vector<
|
||||
|
||||
BestOf2NearestMatcher::BestOf2NearestMatcher(bool try_use_gpu, float match_conf, int num_matches_thresh1, int num_matches_thresh2)
|
||||
{
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(DYNAMIC_CUDA_SUPPORT)
|
||||
if (try_use_gpu && getCudaEnabledDeviceCount() > 0)
|
||||
impl_ = new GpuMatcher(match_conf);
|
||||
else
|
||||
|
@@ -68,7 +68,7 @@
|
||||
#include "opencv2/imgproc/imgproc.hpp"
|
||||
#include "opencv2/features2d/features2d.hpp"
|
||||
#include "opencv2/calib3d/calib3d.hpp"
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(DYNAMIC_CUDA_SUPPORT)
|
||||
#include "opencv2/gpu/gpu.hpp"
|
||||
|
||||
#ifdef HAVE_OPENCV_NONFREE
|
||||
|
@@ -1318,7 +1318,7 @@ void GraphCutSeamFinder::find(const vector<Mat> &src, const vector<Point> &corne
|
||||
}
|
||||
|
||||
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(DYNAMIC_CUDA_SUPPORT)
|
||||
void GraphCutSeamFinderGpu::find(const vector<Mat> &src, const vector<Point> &corners,
|
||||
vector<Mat> &masks)
|
||||
{
|
||||
@@ -1642,6 +1642,62 @@ void GraphCutSeamFinderGpu::setGraphWeightsColorGrad(
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
void GraphCutSeamFinderGpu::find(const vector<Mat> &src, const vector<Point> &corners,
|
||||
vector<Mat> &masks)
|
||||
{
|
||||
(void)src;
|
||||
(void)corners;
|
||||
(void)masks;
|
||||
CV_Error(CV_StsNotImplemented, "CUDA optimization is unavailable");
|
||||
}
|
||||
|
||||
|
||||
void GraphCutSeamFinderGpu::findInPair(size_t first, size_t second, Rect roi)
|
||||
{
|
||||
(void)first;
|
||||
(void)second;
|
||||
(void)roi;
|
||||
CV_Error(CV_StsNotImplemented, "CUDA optimization is unavailable");
|
||||
}
|
||||
|
||||
|
||||
void GraphCutSeamFinderGpu::setGraphWeightsColor(const Mat &img1, const Mat &img2, const Mat &mask1, const Mat &mask2,
|
||||
Mat &terminals, Mat &leftT, Mat &rightT, Mat &top, Mat &bottom)
|
||||
{
|
||||
(void)img1;
|
||||
(void)img2;
|
||||
(void)mask1;
|
||||
(void)mask2;
|
||||
(void)terminals;
|
||||
(void)leftT;
|
||||
(void)rightT;
|
||||
(void)top;
|
||||
(void)bottom;
|
||||
CV_Error(CV_StsNotImplemented, "CUDA optimization is unavailable");
|
||||
}
|
||||
|
||||
|
||||
void GraphCutSeamFinderGpu::setGraphWeightsColorGrad(
|
||||
const Mat &img1, const Mat &img2, const Mat &dx1, const Mat &dx2,
|
||||
const Mat &dy1, const Mat &dy2, const Mat &mask1, const Mat &mask2,
|
||||
Mat &terminals, Mat &leftT, Mat &rightT, Mat &top, Mat &bottom)
|
||||
{
|
||||
(void)img1;
|
||||
(void)img2;
|
||||
(void)dx1;
|
||||
(void)dx2;
|
||||
(void)dy1;
|
||||
(void)dy2;
|
||||
(void)mask1;
|
||||
(void)mask2;
|
||||
(void)terminals;
|
||||
(void)leftT;
|
||||
(void)rightT;
|
||||
(void)top;
|
||||
(void)bottom;
|
||||
CV_Error(CV_StsNotImplemented, "CUDA optimization is unavailable");
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
@@ -58,7 +58,7 @@ Stitcher Stitcher::createDefault(bool try_use_gpu)
|
||||
stitcher.setFeaturesMatcher(new detail::BestOf2NearestMatcher(try_use_gpu));
|
||||
stitcher.setBundleAdjuster(new detail::BundleAdjusterRay());
|
||||
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(DYNAMIC_CUDA_SUPPORT)
|
||||
if (try_use_gpu && gpu::getCudaEnabledDeviceCount() > 0)
|
||||
{
|
||||
#if defined(HAVE_OPENCV_NONFREE)
|
||||
|
@@ -212,7 +212,7 @@ void SphericalWarper::detectResultRoi(Size src_size, Point &dst_tl, Point &dst_b
|
||||
}
|
||||
|
||||
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(DYNAMIC_CUDA_SUPPORT)
|
||||
Rect PlaneWarperGpu::buildMaps(Size src_size, const Mat &K, const Mat &R, gpu::GpuMat &xmap, gpu::GpuMat &ymap)
|
||||
{
|
||||
return buildMaps(src_size, K, R, Mat::zeros(3, 1, CV_32F), xmap, ymap);
|
||||
@@ -294,6 +294,96 @@ Point CylindricalWarperGpu::warp(const gpu::GpuMat &src, const Mat &K, const Mat
|
||||
gpu::remap(src, dst, d_xmap_, d_ymap_, interp_mode, border_mode);
|
||||
return dst_roi.tl();
|
||||
}
|
||||
#else
|
||||
Rect PlaneWarperGpu::buildMaps(Size src_size, const Mat &K, const Mat &R, gpu::GpuMat &xmap, gpu::GpuMat &ymap)
|
||||
{
|
||||
return buildMaps(src_size, K, R, Mat::zeros(3, 1, CV_32F), xmap, ymap);
|
||||
}
|
||||
|
||||
Rect PlaneWarperGpu::buildMaps(Size src_size, const Mat &K, const Mat &R, const Mat &T, gpu::GpuMat &xmap, gpu::GpuMat &ymap)
|
||||
{
|
||||
(void)src_size;
|
||||
(void)K;
|
||||
(void)R;
|
||||
(void)T;
|
||||
(void)xmap;
|
||||
(void)ymap;
|
||||
CV_Error(CV_StsNotImplemented, "CUDA optimization is unavailable");
|
||||
return Rect();
|
||||
}
|
||||
|
||||
Point PlaneWarperGpu::warp(const gpu::GpuMat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
|
||||
gpu::GpuMat &dst)
|
||||
{
|
||||
return warp(src, K, R, Mat::zeros(3, 1, CV_32F), interp_mode, border_mode, dst);
|
||||
}
|
||||
|
||||
|
||||
Point PlaneWarperGpu::warp(const gpu::GpuMat &src, const Mat &K, const Mat &R, const Mat &T, int interp_mode, int border_mode,
|
||||
gpu::GpuMat &dst)
|
||||
{
|
||||
(void)src;
|
||||
(void)K;
|
||||
(void)R;
|
||||
(void)T;
|
||||
(void)interp_mode;
|
||||
(void)border_mode;
|
||||
(void)dst;
|
||||
CV_Error(CV_StsNotImplemented, "CUDA optimization is unavailable");
|
||||
return Point();
|
||||
}
|
||||
|
||||
|
||||
Rect SphericalWarperGpu::buildMaps(Size src_size, const Mat &K, const Mat &R, gpu::GpuMat &xmap, gpu::GpuMat &ymap)
|
||||
{
|
||||
(void)src_size;
|
||||
(void)K;
|
||||
(void)R;
|
||||
(void)xmap;
|
||||
(void)ymap;
|
||||
CV_Error(CV_StsNotImplemented, "CUDA optimization is unavailable");
|
||||
return Rect();
|
||||
}
|
||||
|
||||
|
||||
Point SphericalWarperGpu::warp(const gpu::GpuMat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
|
||||
gpu::GpuMat &dst)
|
||||
{
|
||||
(void)src;
|
||||
(void)K;
|
||||
(void)R;
|
||||
(void)interp_mode;
|
||||
(void)border_mode;
|
||||
(void)dst;
|
||||
CV_Error(CV_StsNotImplemented, "CUDA optimization is unavailable");
|
||||
return Point();
|
||||
}
|
||||
|
||||
|
||||
Rect CylindricalWarperGpu::buildMaps(Size src_size, const Mat &K, const Mat &R, gpu::GpuMat &xmap, gpu::GpuMat &ymap)
|
||||
{
|
||||
(void)src_size;
|
||||
(void)K;
|
||||
(void)R;
|
||||
(void)xmap;
|
||||
(void)ymap;
|
||||
CV_Error(CV_StsNotImplemented, "CUDA optimization is unavailable");
|
||||
return Rect();
|
||||
}
|
||||
|
||||
|
||||
Point CylindricalWarperGpu::warp(const gpu::GpuMat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
|
||||
gpu::GpuMat &dst)
|
||||
{
|
||||
(void)src;
|
||||
(void)K;
|
||||
(void)R;
|
||||
(void)interp_mode;
|
||||
(void)border_mode;
|
||||
(void)dst;
|
||||
CV_Error(CV_StsNotImplemented, "CUDA optimization is unavailable");
|
||||
return Point();
|
||||
}
|
||||
#endif
|
||||
|
||||
void SphericalPortraitWarper::detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br)
|
||||
|
@@ -3,5 +3,5 @@ if(ANDROID OR IOS)
|
||||
endif()
|
||||
|
||||
set(the_description "Super Resolution")
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4127 -Wundef)
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4127 -Wundef -Wshadow)
|
||||
ocv_define_module(superres opencv_imgproc opencv_video OPTIONAL opencv_gpu opencv_highgui opencv_ocl ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
|
||||
|
@@ -97,6 +97,9 @@ re_data_type = re.compile(r'^ (?: 8 | 16 | 32 | 64 ) [USF] C [1234] $', re.VERBO
|
||||
|
||||
time_style = xlwt.easyxf(num_format_str='#0.00')
|
||||
no_time_style = xlwt.easyxf('pattern: pattern solid, fore_color gray25')
|
||||
failed_style = xlwt.easyxf('pattern: pattern solid, fore_color red')
|
||||
noimpl_style = xlwt.easyxf('pattern: pattern solid, fore_color orange')
|
||||
style_dict = {"failed": failed_style, "noimpl":noimpl_style}
|
||||
|
||||
speedup_style = time_style
|
||||
good_speedup_style = xlwt.easyxf('font: color green', num_format_str='#0.00')
|
||||
@@ -328,7 +331,7 @@ def main():
|
||||
|
||||
for c in config_names:
|
||||
if c in configs:
|
||||
sheet.write(row, col, configs[c], time_style)
|
||||
sheet.write(row, col, configs[c], style_dict.get(configs[c], time_style))
|
||||
else:
|
||||
sheet.write(row, col, None, no_time_style)
|
||||
col += 1
|
||||
|
@@ -122,7 +122,7 @@ void ArrayTest::get_test_array_types_and_sizes( int /*test_case_idx*/, vector<ve
|
||||
}
|
||||
|
||||
|
||||
static const int icvTsTypeToDepth[] =
|
||||
static const unsigned int icvTsTypeToDepth[] =
|
||||
{
|
||||
IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U, IPL_DEPTH_16S,
|
||||
IPL_DEPTH_32S, IPL_DEPTH_32F, IPL_DEPTH_64F
|
||||
|
11
modules/viz/CMakeLists.txt
Normal file
11
modules/viz/CMakeLists.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
if(NOT WITH_VTK OR NOT DEFINED HAVE_VTK OR NOT HAVE_VTK)
|
||||
ocv_module_disable(viz)
|
||||
endif()
|
||||
|
||||
include(${VTK_USE_FILE})
|
||||
set(the_description "Viz")
|
||||
ocv_define_module(viz opencv_core ${VTK_LIBRARIES})
|
||||
|
||||
if(APPLE AND BUILD_opencv_viz)
|
||||
target_link_libraries(opencv_viz "-framework Cocoa")
|
||||
endif()
|
BIN
modules/viz/doc/images/cpw1.png
Normal file
BIN
modules/viz/doc/images/cpw1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
BIN
modules/viz/doc/images/cpw2.png
Normal file
BIN
modules/viz/doc/images/cpw2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
BIN
modules/viz/doc/images/cpw3.png
Normal file
BIN
modules/viz/doc/images/cpw3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
BIN
modules/viz/doc/images/cube_widget.png
Normal file
BIN
modules/viz/doc/images/cube_widget.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.4 KiB |
9
modules/viz/doc/viz.rst
Normal file
9
modules/viz/doc/viz.rst
Normal file
@@ -0,0 +1,9 @@
|
||||
***********************
|
||||
viz. 3D Visualizer
|
||||
***********************
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
viz3d.rst
|
||||
widget.rst
|
637
modules/viz/doc/viz3d.rst
Normal file
637
modules/viz/doc/viz3d.rst
Normal file
@@ -0,0 +1,637 @@
|
||||
Viz
|
||||
===
|
||||
|
||||
.. highlight:: cpp
|
||||
|
||||
This section describes 3D visualization window as well as classes and methods
|
||||
that are used to interact with it.
|
||||
|
||||
3D visualization window (see :ocv:class:`Viz3d`) is used to display widgets (see :ocv:class:`Widget`), and it provides
|
||||
several methods to interact with scene and widgets.
|
||||
|
||||
viz::makeTransformToGlobal
|
||||
--------------------------
|
||||
Takes coordinate frame data and builds transform to global coordinate frame.
|
||||
|
||||
.. ocv:function:: Affine3d viz::makeTransformToGlobal(const Vec3f& axis_x, const Vec3f& axis_y, const Vec3f& axis_z, const Vec3f& origin = Vec3f::all(0))
|
||||
|
||||
:param axis_x: X axis vector in global coordinate frame.
|
||||
:param axis_y: Y axis vector in global coordinate frame.
|
||||
:param axis_z: Z axis vector in global coordinate frame.
|
||||
:param origin: Origin of the coordinate frame in global coordinate frame.
|
||||
|
||||
This function returns affine transform that describes transformation between global coordinate frame and a given coordinate frame.
|
||||
|
||||
viz::makeCameraPose
|
||||
-------------------
|
||||
Constructs camera pose from position, focal_point and up_vector (see gluLookAt() for more infromation).
|
||||
|
||||
.. ocv:function:: Affine3d makeCameraPose(const Vec3f& position, const Vec3f& focal_point, const Vec3f& y_dir)
|
||||
|
||||
:param position: Position of the camera in global coordinate frame.
|
||||
:param focal_point: Focal point of the camera in global coordinate frame.
|
||||
:param y_dir: Up vector of the camera in global coordinate frame.
|
||||
|
||||
This function returns pose of the camera in global coordinate frame.
|
||||
|
||||
viz::getWindowByName
|
||||
--------------------
|
||||
Retrieves a window by its name.
|
||||
|
||||
.. ocv:function:: Viz3d getWindowByName(const String &window_name)
|
||||
|
||||
:param window_name: Name of the window that is to be retrieved.
|
||||
|
||||
This function returns a :ocv:class:`Viz3d` object with the given name.
|
||||
|
||||
.. note:: If the window with that name already exists, that window is returned. Otherwise, new window is created with the given name, and it is returned.
|
||||
|
||||
.. note:: Window names are automatically prefixed by "Viz - " if it is not done by the user.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
/// window and window_2 are the same windows.
|
||||
viz::Viz3d window = viz::getWindowByName("myWindow");
|
||||
viz::Viz3d window_2 = viz::getWindowByName("Viz - myWindow");
|
||||
|
||||
viz::isNan
|
||||
----------
|
||||
Checks **float/double** value for nan.
|
||||
|
||||
.. ocv:function:: bool isNan(float x)
|
||||
|
||||
.. ocv:function:: bool isNan(double x)
|
||||
|
||||
:param x: return true if nan.
|
||||
|
||||
Checks **vector** for nan.
|
||||
|
||||
.. ocv:function:: bool isNan(const Vec<_Tp, cn>& v)
|
||||
|
||||
:param v: return true if **any** of the elements of the vector is *nan*.
|
||||
|
||||
Checks **point** for nan
|
||||
|
||||
.. ocv:function:: bool isNan(const Point3_<_Tp>& p)
|
||||
|
||||
:param p: return true if **any** of the elements of the point is *nan*.
|
||||
|
||||
viz::Viz3d
|
||||
----------
|
||||
.. ocv:class:: Viz3d
|
||||
|
||||
The Viz3d class represents a 3D visualizer window. This class is implicitly shared. ::
|
||||
|
||||
class CV_EXPORTS Viz3d
|
||||
{
|
||||
public:
|
||||
typedef cv::Ptr<Viz3d> Ptr;
|
||||
typedef void (*KeyboardCallback)(const KeyboardEvent&, void*);
|
||||
typedef void (*MouseCallback)(const MouseEvent&, void*);
|
||||
|
||||
Viz3d(const String& window_name = String());
|
||||
Viz3d(const Viz3d&);
|
||||
Viz3d& operator=(const Viz3d&);
|
||||
~Viz3d();
|
||||
|
||||
void showWidget(const String &id, const Widget &widget, const Affine3d &pose = Affine3d::Identity());
|
||||
void removeWidget(const String &id);
|
||||
Widget getWidget(const String &id) const;
|
||||
void removeAllWidgets();
|
||||
|
||||
void setWidgetPose(const String &id, const Affine3d &pose);
|
||||
void updateWidgetPose(const String &id, const Affine3d &pose);
|
||||
Affine3d getWidgetPose(const String &id) const;
|
||||
|
||||
void showImage(InputArray image, const Size& window_size = Size(-1, -1));
|
||||
|
||||
void setCamera(const Camera &camera);
|
||||
Camera getCamera() const;
|
||||
Affine3d getViewerPose();
|
||||
void setViewerPose(const Affine3d &pose);
|
||||
|
||||
void resetCameraViewpoint (const String &id);
|
||||
void resetCamera();
|
||||
|
||||
void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord);
|
||||
void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction);
|
||||
|
||||
Size getWindowSize() const;
|
||||
void setWindowSize(const Size &window_size);
|
||||
String getWindowName() const;
|
||||
void saveScreenshot (const String &file);
|
||||
void setWindowPosition (int x, int y);
|
||||
void setFullScreen (bool mode);
|
||||
void setBackgroundColor(const Color& color = Color::black());
|
||||
|
||||
void spin();
|
||||
void spinOnce(int time = 1, bool force_redraw = false);
|
||||
bool wasStopped() const;
|
||||
|
||||
void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0);
|
||||
void registerMouseCallback(MouseCallback callback, void* cookie = 0);
|
||||
|
||||
void setRenderingProperty(const String &id, int property, double value);
|
||||
double getRenderingProperty(const String &id, int property);
|
||||
|
||||
|
||||
void setRepresentation(int representation);
|
||||
private:
|
||||
/* hidden */
|
||||
};
|
||||
|
||||
viz::Viz3d::Viz3d
|
||||
-----------------
|
||||
The constructors.
|
||||
|
||||
.. ocv:function:: Viz3d::Viz3d(const String& window_name = String())
|
||||
|
||||
:param window_name: Name of the window.
|
||||
|
||||
viz::Viz3d::showWidget
|
||||
----------------------
|
||||
Shows a widget in the window.
|
||||
|
||||
.. ocv:function:: void Viz3d::showWidget(const String &id, const Widget &widget, const Affine3d &pose = Affine3d::Identity())
|
||||
|
||||
:param id: A unique id for the widget.
|
||||
:param widget: The widget to be displayed in the window.
|
||||
:param pose: Pose of the widget.
|
||||
|
||||
viz::Viz3d::removeWidget
|
||||
------------------------
|
||||
Removes a widget from the window.
|
||||
|
||||
.. ocv:function:: void removeWidget(const String &id)
|
||||
|
||||
:param id: The id of the widget that will be removed.
|
||||
|
||||
viz::Viz3d::getWidget
|
||||
---------------------
|
||||
Retrieves a widget from the window. A widget is implicitly shared;
|
||||
that is, if the returned widget is modified, the changes will be
|
||||
immediately visible in the window.
|
||||
|
||||
.. ocv:function:: Widget getWidget(const String &id) const
|
||||
|
||||
:param id: The id of the widget that will be returned.
|
||||
|
||||
viz::Viz3d::removeAllWidgets
|
||||
----------------------------
|
||||
Removes all widgets from the window.
|
||||
|
||||
.. ocv:function:: void removeAllWidgets()
|
||||
|
||||
viz::Viz3d::showImage
|
||||
---------------------
|
||||
Removed all widgets and displays image scaled to whole window area.
|
||||
|
||||
.. ocv:function:: void showImage(InputArray image, const Size& window_size = Size(-1, -1))
|
||||
|
||||
:param image: Image to be displayed.
|
||||
:param size: Size of Viz3d window. Default value means no change.
|
||||
|
||||
viz::Viz3d::setWidgetPose
|
||||
-------------------------
|
||||
Sets pose of a widget in the window.
|
||||
|
||||
.. ocv:function:: void setWidgetPose(const String &id, const Affine3d &pose)
|
||||
|
||||
:param id: The id of the widget whose pose will be set.
|
||||
:param pose: The new pose of the widget.
|
||||
|
||||
viz::Viz3d::updateWidgetPose
|
||||
----------------------------
|
||||
Updates pose of a widget in the window by pre-multiplying its current pose.
|
||||
|
||||
.. ocv:function:: void updateWidgetPose(const String &id, const Affine3d &pose)
|
||||
|
||||
:param id: The id of the widget whose pose will be updated.
|
||||
:param pose: The pose that the current pose of the widget will be pre-multiplied by.
|
||||
|
||||
viz::Viz3d::getWidgetPose
|
||||
-------------------------
|
||||
Returns the current pose of a widget in the window.
|
||||
|
||||
.. ocv:function:: Affine3d getWidgetPose(const String &id) const
|
||||
|
||||
:param id: The id of the widget whose pose will be returned.
|
||||
|
||||
viz::Viz3d::setCamera
|
||||
---------------------
|
||||
Sets the intrinsic parameters of the viewer using Camera.
|
||||
|
||||
.. ocv:function:: void setCamera(const Camera &camera)
|
||||
|
||||
:param camera: Camera object wrapping intrinsinc parameters.
|
||||
|
||||
viz::Viz3d::getCamera
|
||||
---------------------
|
||||
Returns a camera object that contains intrinsic parameters of the current viewer.
|
||||
|
||||
.. ocv:function:: Camera getCamera() const
|
||||
|
||||
viz::Viz3d::getViewerPose
|
||||
-------------------------
|
||||
Returns the current pose of the viewer.
|
||||
|
||||
..ocv:function:: Affine3d getViewerPose()
|
||||
|
||||
viz::Viz3d::setViewerPose
|
||||
-------------------------
|
||||
Sets pose of the viewer.
|
||||
|
||||
.. ocv:function:: void setViewerPose(const Affine3d &pose)
|
||||
|
||||
:param pose: The new pose of the viewer.
|
||||
|
||||
viz::Viz3d::resetCameraViewpoint
|
||||
--------------------------------
|
||||
Resets camera viewpoint to a 3D widget in the scene.
|
||||
|
||||
.. ocv:function:: void resetCameraViewpoint (const String &id)
|
||||
|
||||
:param pose: Id of a 3D widget.
|
||||
|
||||
viz::Viz3d::resetCamera
|
||||
-----------------------
|
||||
Resets camera.
|
||||
|
||||
.. ocv:function:: void resetCamera()
|
||||
|
||||
viz::Viz3d::convertToWindowCoordinates
|
||||
--------------------------------------
|
||||
Transforms a point in world coordinate system to window coordinate system.
|
||||
|
||||
.. ocv:function:: void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord)
|
||||
|
||||
:param pt: Point in world coordinate system.
|
||||
:param window_coord: Output point in window coordinate system.
|
||||
|
||||
viz::Viz3d::converTo3DRay
|
||||
-------------------------
|
||||
Transforms a point in window coordinate system to a 3D ray in world coordinate system.
|
||||
|
||||
.. ocv:function:: void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction)
|
||||
|
||||
:param window_coord: Point in window coordinate system.
|
||||
:param origin: Output origin of the ray.
|
||||
:param direction: Output direction of the ray.
|
||||
|
||||
viz::Viz3d::getWindowSize
|
||||
-------------------------
|
||||
Returns the current size of the window.
|
||||
|
||||
.. ocv:function:: Size getWindowSize() const
|
||||
|
||||
viz::Viz3d::setWindowSize
|
||||
-------------------------
|
||||
Sets the size of the window.
|
||||
|
||||
.. ocv:function:: void setWindowSize(const Size &window_size)
|
||||
|
||||
:param window_size: New size of the window.
|
||||
|
||||
viz::Viz3d::getWindowName
|
||||
-------------------------
|
||||
Returns the name of the window which has been set in the constructor.
|
||||
|
||||
.. ocv:function:: String getWindowName() const
|
||||
|
||||
viz::Viz3d::saveScreenshot
|
||||
--------------------------
|
||||
Saves screenshot of the current scene.
|
||||
|
||||
.. ocv:function:: void saveScreenshot(const String &file)
|
||||
|
||||
:param file: Name of the file.
|
||||
|
||||
viz::Viz3d::setWindowPosition
|
||||
-----------------------------
|
||||
Sets the position of the window in the screen.
|
||||
|
||||
.. ocv:function:: void setWindowPosition(int x, int y)
|
||||
|
||||
:param x: x coordinate of the window
|
||||
:param y: y coordinate of the window
|
||||
|
||||
viz::Viz3d::setFullScreen
|
||||
-------------------------
|
||||
Sets or unsets full-screen rendering mode.
|
||||
|
||||
.. ocv:function:: void setFullScreen(bool mode)
|
||||
|
||||
:param mode: If true, window will use full-screen mode.
|
||||
|
||||
viz::Viz3d::setBackgroundColor
|
||||
------------------------------
|
||||
Sets background color.
|
||||
|
||||
.. ocv:function:: void setBackgroundColor(const Color& color = Color::black())
|
||||
|
||||
viz::Viz3d::spin
|
||||
----------------
|
||||
The window renders and starts the event loop.
|
||||
|
||||
.. ocv:function:: void spin()
|
||||
|
||||
viz::Viz3d::spinOnce
|
||||
--------------------
|
||||
Starts the event loop for a given time.
|
||||
|
||||
.. ocv:function:: void spinOnce(int time = 1, bool force_redraw = false)
|
||||
|
||||
:param time: Amount of time in milliseconds for the event loop to keep running.
|
||||
:param force_draw: If true, window renders.
|
||||
|
||||
viz::Viz3d::wasStopped
|
||||
----------------------
|
||||
Returns whether the event loop has been stopped.
|
||||
|
||||
.. ocv:function:: bool wasStopped()
|
||||
|
||||
viz::Viz3d::registerKeyboardCallback
|
||||
------------------------------------
|
||||
Sets keyboard handler.
|
||||
|
||||
.. ocv:function:: void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0)
|
||||
|
||||
:param callback: Keyboard callback ``(void (*KeyboardCallbackFunction(const KeyboardEvent&, void*))``.
|
||||
:param cookie: The optional parameter passed to the callback.
|
||||
|
||||
viz::Viz3d::registerMouseCallback
|
||||
---------------------------------
|
||||
Sets mouse handler.
|
||||
|
||||
.. ocv:function:: void registerMouseCallback(MouseCallback callback, void* cookie = 0)
|
||||
|
||||
:param callback: Mouse callback ``(void (*MouseCallback)(const MouseEvent&, void*))``.
|
||||
:param cookie: The optional parameter passed to the callback.
|
||||
|
||||
viz::Viz3d::setRenderingProperty
|
||||
--------------------------------
|
||||
Sets rendering property of a widget.
|
||||
|
||||
.. ocv:function:: void setRenderingProperty(const String &id, int property, double value)
|
||||
|
||||
:param id: Id of the widget.
|
||||
:param property: Property that will be modified.
|
||||
:param value: The new value of the property.
|
||||
|
||||
**Rendering property** can be one of the following:
|
||||
|
||||
* **POINT_SIZE**
|
||||
* **OPACITY**
|
||||
* **LINE_WIDTH**
|
||||
* **FONT_SIZE**
|
||||
* **REPRESENTATION**: Expected values are
|
||||
* **REPRESENTATION_POINTS**
|
||||
* **REPRESENTATION_WIREFRAME**
|
||||
* **REPRESENTATION_SURFACE**
|
||||
* **IMMEDIATE_RENDERING**:
|
||||
* Turn on immediate rendering by setting the value to ``1``.
|
||||
* Turn off immediate rendering by setting the value to ``0``.
|
||||
* **SHADING**: Expected values are
|
||||
* **SHADING_FLAT**
|
||||
* **SHADING_GOURAUD**
|
||||
* **SHADING_PHONG**
|
||||
|
||||
viz::Viz3d::getRenderingProperty
|
||||
--------------------------------
|
||||
Returns rendering property of a widget.
|
||||
|
||||
.. ocv:function:: double getRenderingProperty(const String &id, int property)
|
||||
|
||||
:param id: Id of the widget.
|
||||
:param property: Property.
|
||||
|
||||
**Rendering property** can be one of the following:
|
||||
|
||||
* **POINT_SIZE**
|
||||
* **OPACITY**
|
||||
* **LINE_WIDTH**
|
||||
* **FONT_SIZE**
|
||||
* **REPRESENTATION**: Expected values are
|
||||
* **REPRESENTATION_POINTS**
|
||||
* **REPRESENTATION_WIREFRAME**
|
||||
* **REPRESENTATION_SURFACE**
|
||||
* **IMMEDIATE_RENDERING**:
|
||||
* Turn on immediate rendering by setting the value to ``1``.
|
||||
* Turn off immediate rendering by setting the value to ``0``.
|
||||
* **SHADING**: Expected values are
|
||||
* **SHADING_FLAT**
|
||||
* **SHADING_GOURAUD**
|
||||
* **SHADING_PHONG**
|
||||
|
||||
viz::Viz3d::setRepresentation
|
||||
-----------------------------
|
||||
Sets geometry representation of the widgets to surface, wireframe or points.
|
||||
|
||||
.. ocv:function:: void setRepresentation(int representation)
|
||||
|
||||
:param representation: Geometry representation which can be one of the following:
|
||||
|
||||
* **REPRESENTATION_POINTS**
|
||||
* **REPRESENTATION_WIREFRAME**
|
||||
* **REPRESENTATION_SURFACE**
|
||||
|
||||
viz::Color
|
||||
----------
|
||||
.. ocv:class:: Color
|
||||
|
||||
This class a represents BGR color. ::
|
||||
|
||||
class CV_EXPORTS Color : public Scalar
|
||||
{
|
||||
public:
|
||||
Color();
|
||||
Color(double gray);
|
||||
Color(double blue, double green, double red);
|
||||
|
||||
Color(const Scalar& color);
|
||||
|
||||
static Color black();
|
||||
static Color blue();
|
||||
static Color green();
|
||||
static Color cyan();
|
||||
|
||||
static Color red();
|
||||
static Color magenta();
|
||||
static Color yellow();
|
||||
static Color white();
|
||||
|
||||
static Color gray();
|
||||
};
|
||||
|
||||
viz::Mesh
|
||||
-----------
|
||||
.. ocv:class:: Mesh
|
||||
|
||||
This class wraps mesh attributes, and it can load a mesh from a ``ply`` file. ::
|
||||
|
||||
class CV_EXPORTS Mesh
|
||||
{
|
||||
public:
|
||||
|
||||
Mat cloud, colors, normals;
|
||||
|
||||
//! Raw integer list of the form: (n,id1,id2,...,idn, n,id1,id2,...,idn, ...)
|
||||
//! where n is the number of points in the poligon, and id is a zero-offset index into an associated cloud.
|
||||
Mat polygons;
|
||||
|
||||
//! Loads mesh from a given ply file
|
||||
static Mesh load(const String& file);
|
||||
};
|
||||
|
||||
viz::Mesh::load
|
||||
---------------------
|
||||
Loads a mesh from a ``ply`` file.
|
||||
|
||||
.. ocv:function:: static Mesh load(const String& file)
|
||||
|
||||
:param file: File name (for no only PLY is supported)
|
||||
|
||||
|
||||
viz::KeyboardEvent
|
||||
------------------
|
||||
.. ocv:class:: KeyboardEvent
|
||||
|
||||
This class represents a keyboard event. ::
|
||||
|
||||
class CV_EXPORTS KeyboardEvent
|
||||
{
|
||||
public:
|
||||
enum { ALT = 1, CTRL = 2, SHIFT = 4 };
|
||||
enum Action { KEY_UP = 0, KEY_DOWN = 1 };
|
||||
|
||||
KeyboardEvent(Action action, const String& symbol, unsigned char code, int modifiers);
|
||||
|
||||
Action action;
|
||||
String symbol;
|
||||
unsigned char code;
|
||||
int modifiers;
|
||||
};
|
||||
|
||||
viz::KeyboardEvent::KeyboardEvent
|
||||
---------------------------------
|
||||
Constructs a KeyboardEvent.
|
||||
|
||||
.. ocv:function:: KeyboardEvent (Action action, const String& symbol, unsigned char code, Modifiers modifiers)
|
||||
|
||||
:param action: Signals if key is pressed or released.
|
||||
:param symbol: Name of the key.
|
||||
:param code: Code of the key.
|
||||
:param modifiers: Signals if ``alt``, ``ctrl`` or ``shift`` are pressed or their combination.
|
||||
|
||||
|
||||
viz::MouseEvent
|
||||
---------------
|
||||
.. ocv:class:: MouseEvent
|
||||
|
||||
This class represents a mouse event. ::
|
||||
|
||||
class CV_EXPORTS MouseEvent
|
||||
{
|
||||
public:
|
||||
enum Type { MouseMove = 1, MouseButtonPress, MouseButtonRelease, MouseScrollDown, MouseScrollUp, MouseDblClick } ;
|
||||
enum MouseButton { NoButton = 0, LeftButton, MiddleButton, RightButton, VScroll } ;
|
||||
|
||||
MouseEvent(const Type& type, const MouseButton& button, const Point& pointer, int modifiers);
|
||||
|
||||
Type type;
|
||||
MouseButton button;
|
||||
Point pointer;
|
||||
int modifiers;
|
||||
};
|
||||
|
||||
viz::MouseEvent::MouseEvent
|
||||
---------------------------
|
||||
Constructs a MouseEvent.
|
||||
|
||||
.. ocv:function:: MouseEvent (const Type& type, const MouseButton& button, const Point& p, Modifiers modifiers)
|
||||
|
||||
:param type: Type of the event. This can be **MouseMove**, **MouseButtonPress**, **MouseButtonRelease**, **MouseScrollDown**, **MouseScrollUp**, **MouseDblClick**.
|
||||
:param button: Mouse button. This can be **NoButton**, **LeftButton**, **MiddleButton**, **RightButton**, **VScroll**.
|
||||
:param p: Position of the event.
|
||||
:param modifiers: Signals if ``alt``, ``ctrl`` or ``shift`` are pressed or their combination.
|
||||
|
||||
viz::Camera
|
||||
-----------
|
||||
.. ocv:class:: Camera
|
||||
|
||||
This class wraps intrinsic parameters of a camera. It provides several constructors
|
||||
that can extract the intrinsic parameters from ``field of view``, ``intrinsic matrix`` and
|
||||
``projection matrix``. ::
|
||||
|
||||
class CV_EXPORTS Camera
|
||||
{
|
||||
public:
|
||||
Camera(double f_x, double f_y, double c_x, double c_y, const Size &window_size);
|
||||
Camera(const Vec2d &fov, const Size &window_size);
|
||||
Camera(const Matx33d &K, const Size &window_size);
|
||||
Camera(const Matx44d &proj, const Size &window_size);
|
||||
|
||||
inline const Vec2d & getClip() const;
|
||||
inline void setClip(const Vec2d &clip);
|
||||
|
||||
inline const Size & getWindowSize() const;
|
||||
void setWindowSize(const Size &window_size);
|
||||
|
||||
inline const Vec2d & getFov() const;
|
||||
inline void setFov(const Vec2d & fov);
|
||||
|
||||
inline const Vec2d & getPrincipalPoint() const;
|
||||
inline const Vec2d & getFocalLength() const;
|
||||
|
||||
void computeProjectionMatrix(Matx44d &proj) const;
|
||||
|
||||
static Camera KinectCamera(const Size &window_size);
|
||||
|
||||
private:
|
||||
/* hidden */
|
||||
};
|
||||
|
||||
viz::Camera::Camera
|
||||
-------------------
|
||||
Constructs a Camera.
|
||||
|
||||
.. ocv:function:: Camera(double f_x, double f_y, double c_x, double c_y, const Size &window_size)
|
||||
|
||||
:param f_x: Horizontal focal length.
|
||||
:param f_y: Vertical focal length.
|
||||
:param c_x: x coordinate of the principal point.
|
||||
:param c_y: y coordinate of the principal point.
|
||||
:param window_size: Size of the window. This together with focal length and principal point determines the field of view.
|
||||
|
||||
.. ocv:function:: Camera(const Vec2d &fov, const Size &window_size)
|
||||
|
||||
:param fov: Field of view (horizontal, vertical)
|
||||
:param window_size: Size of the window.
|
||||
|
||||
Principal point is at the center of the window by default.
|
||||
|
||||
.. ocv:function:: Camera(const Matx33d &K, const Size &window_size)
|
||||
|
||||
:param K: Intrinsic matrix of the camera.
|
||||
:param window_size: Size of the window. This together with intrinsic matrix determines the field of view.
|
||||
|
||||
.. ocv:function:: Camera(const Matx44d &proj, const Size &window_size)
|
||||
|
||||
:param proj: Projection matrix of the camera.
|
||||
:param window_size: Size of the window. This together with projection matrix determines the field of view.
|
||||
|
||||
viz::Camera::computeProjectionMatrix
|
||||
------------------------------------
|
||||
Computes projection matrix using intrinsic parameters of the camera.
|
||||
|
||||
.. ocv:function:: void computeProjectionMatrix(Matx44d &proj) const
|
||||
|
||||
:param proj: Output projection matrix.
|
||||
|
||||
viz::Camera::KinectCamera
|
||||
-------------------------
|
||||
Creates a Kinect Camera.
|
||||
|
||||
.. ocv:function:: static Camera KinectCamera(const Size &window_size)
|
||||
|
||||
:param window_size: Size of the window. This together with intrinsic matrix of a Kinect Camera determines the field of view.
|
1019
modules/viz/doc/widget.rst
Normal file
1019
modules/viz/doc/widget.rst
Normal file
File diff suppressed because it is too large
Load Diff
236
modules/viz/include/opencv2/viz/types.hpp
Normal file
236
modules/viz/include/opencv2/viz/types.hpp
Normal file
@@ -0,0 +1,236 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's 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.
|
||||
//
|
||||
// * The name of the copyright holders may not 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 Intel Corporation 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.
|
||||
//
|
||||
// Authors:
|
||||
// * Ozan Tonkal, ozantonkal@gmail.com
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __OPENCV_VIZ_TYPES_HPP__
|
||||
#define __OPENCV_VIZ_TYPES_HPP__
|
||||
|
||||
#include <string>
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/core/affine.hpp>
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace viz
|
||||
{
|
||||
class Color : public Scalar
|
||||
{
|
||||
public:
|
||||
Color();
|
||||
Color(double gray);
|
||||
Color(double blue, double green, double red);
|
||||
|
||||
Color(const Scalar& color);
|
||||
|
||||
static Color black();
|
||||
static Color blue();
|
||||
static Color green();
|
||||
static Color cyan();
|
||||
|
||||
static Color red();
|
||||
static Color magenta();
|
||||
static Color yellow();
|
||||
static Color white();
|
||||
|
||||
static Color gray();
|
||||
|
||||
static Color mlab();
|
||||
|
||||
static Color navy();
|
||||
static Color olive();
|
||||
static Color maroon();
|
||||
static Color teal();
|
||||
static Color rose();
|
||||
static Color azure();
|
||||
static Color lime();
|
||||
static Color gold();
|
||||
static Color brown();
|
||||
static Color orange();
|
||||
static Color chartreuse();
|
||||
static Color orange_red();
|
||||
static Color purple();
|
||||
static Color indigo();
|
||||
|
||||
static Color pink();
|
||||
static Color cherry();
|
||||
static Color bluberry();
|
||||
static Color raspberry();
|
||||
static Color silver();
|
||||
static Color violet();
|
||||
static Color apricot();
|
||||
static Color turquoise();
|
||||
static Color celestial_blue();
|
||||
static Color amethyst();
|
||||
|
||||
static Color not_set();
|
||||
};
|
||||
|
||||
class CV_EXPORTS Mesh
|
||||
{
|
||||
public:
|
||||
Mat cloud, colors, normals;
|
||||
|
||||
//! Raw integer list of the form: (n,id1,id2,...,idn, n,id1,id2,...,idn, ...)
|
||||
//! where n is the number of points in the poligon, and id is a zero-offset index into an associated cloud.
|
||||
Mat polygons;
|
||||
|
||||
Mat texture, tcoords;
|
||||
|
||||
//! Loads mesh from a given ply file (no texture load support for now)
|
||||
static Mesh load(const String& file);
|
||||
};
|
||||
|
||||
class CV_EXPORTS Camera
|
||||
{
|
||||
public:
|
||||
Camera(double fx, double fy, double cx, double cy, const Size &window_size);
|
||||
explicit Camera(const Vec2d &fov, const Size &window_size);
|
||||
explicit Camera(const Matx33d &K, const Size &window_size);
|
||||
explicit Camera(const Matx44d &proj, const Size &window_size);
|
||||
|
||||
const Vec2d & getClip() const { return clip_; }
|
||||
void setClip(const Vec2d &clip) { clip_ = clip; }
|
||||
|
||||
const Size & getWindowSize() const { return window_size_; }
|
||||
void setWindowSize(const Size &window_size);
|
||||
|
||||
const Vec2d& getFov() const { return fov_; }
|
||||
void setFov(const Vec2d& fov) { fov_ = fov; }
|
||||
|
||||
const Vec2d& getPrincipalPoint() const { return principal_point_; }
|
||||
const Vec2d& getFocalLength() const { return focal_; }
|
||||
|
||||
void computeProjectionMatrix(Matx44d &proj) const;
|
||||
|
||||
static Camera KinectCamera(const Size &window_size);
|
||||
|
||||
private:
|
||||
void init(double fx, double fy, double cx, double cy, const Size &window_size);
|
||||
|
||||
Vec2d clip_;
|
||||
Vec2d fov_;
|
||||
Size window_size_;
|
||||
Vec2d principal_point_;
|
||||
Vec2d focal_;
|
||||
};
|
||||
|
||||
class CV_EXPORTS KeyboardEvent
|
||||
{
|
||||
public:
|
||||
enum { NONE = 0, ALT = 1, CTRL = 2, SHIFT = 4 };
|
||||
enum Action { KEY_UP = 0, KEY_DOWN = 1 };
|
||||
|
||||
KeyboardEvent(Action action, const String& symbol, unsigned char code, int modifiers);
|
||||
|
||||
Action action;
|
||||
String symbol;
|
||||
unsigned char code;
|
||||
int modifiers;
|
||||
};
|
||||
|
||||
class CV_EXPORTS MouseEvent
|
||||
{
|
||||
public:
|
||||
enum Type { MouseMove = 1, MouseButtonPress, MouseButtonRelease, MouseScrollDown, MouseScrollUp, MouseDblClick } ;
|
||||
enum MouseButton { NoButton = 0, LeftButton, MiddleButton, RightButton, VScroll } ;
|
||||
|
||||
MouseEvent(const Type& type, const MouseButton& button, const Point& pointer, int modifiers);
|
||||
|
||||
Type type;
|
||||
MouseButton button;
|
||||
Point pointer;
|
||||
int modifiers;
|
||||
};
|
||||
} /* namespace viz */
|
||||
} /* namespace cv */
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// cv::viz::Color
|
||||
|
||||
inline cv::viz::Color::Color() : Scalar(0, 0, 0) {}
|
||||
inline cv::viz::Color::Color(double _gray) : Scalar(_gray, _gray, _gray) {}
|
||||
inline cv::viz::Color::Color(double _blue, double _green, double _red) : Scalar(_blue, _green, _red) {}
|
||||
inline cv::viz::Color::Color(const Scalar& color) : Scalar(color) {}
|
||||
|
||||
inline cv::viz::Color cv::viz::Color::black() { return Color( 0, 0, 0); }
|
||||
inline cv::viz::Color cv::viz::Color::green() { return Color( 0, 255, 0); }
|
||||
inline cv::viz::Color cv::viz::Color::blue() { return Color(255, 0, 0); }
|
||||
inline cv::viz::Color cv::viz::Color::cyan() { return Color(255, 255, 0); }
|
||||
inline cv::viz::Color cv::viz::Color::red() { return Color( 0, 0, 255); }
|
||||
inline cv::viz::Color cv::viz::Color::yellow() { return Color( 0, 255, 255); }
|
||||
inline cv::viz::Color cv::viz::Color::magenta() { return Color(255, 0, 255); }
|
||||
inline cv::viz::Color cv::viz::Color::white() { return Color(255, 255, 255); }
|
||||
inline cv::viz::Color cv::viz::Color::gray() { return Color(128, 128, 128); }
|
||||
|
||||
inline cv::viz::Color cv::viz::Color::mlab() { return Color(255, 128, 128); }
|
||||
|
||||
inline cv::viz::Color cv::viz::Color::navy() { return Color(0, 0, 128); }
|
||||
inline cv::viz::Color cv::viz::Color::olive() { return Color(0, 128, 128); }
|
||||
inline cv::viz::Color cv::viz::Color::maroon() { return Color(0, 0, 128); }
|
||||
inline cv::viz::Color cv::viz::Color::teal() { return Color(128, 128, 0); }
|
||||
inline cv::viz::Color cv::viz::Color::rose() { return Color(128, 0, 255); }
|
||||
inline cv::viz::Color cv::viz::Color::azure() { return Color(255, 128, 0); }
|
||||
inline cv::viz::Color cv::viz::Color::lime() { return Color(0, 255, 191); }
|
||||
inline cv::viz::Color cv::viz::Color::gold() { return Color(0, 215, 255); }
|
||||
inline cv::viz::Color cv::viz::Color::brown() { return Color(0, 75, 150); }
|
||||
inline cv::viz::Color cv::viz::Color::orange() { return Color(0, 165, 255); }
|
||||
inline cv::viz::Color cv::viz::Color::chartreuse() { return Color(0, 255, 128); }
|
||||
inline cv::viz::Color cv::viz::Color::orange_red() { return Color(0, 69, 255); }
|
||||
inline cv::viz::Color cv::viz::Color::purple() { return Color(128, 0, 128); }
|
||||
inline cv::viz::Color cv::viz::Color::indigo() { return Color(130, 0, 75); }
|
||||
|
||||
inline cv::viz::Color cv::viz::Color::pink() { return Color(203, 192, 255); }
|
||||
inline cv::viz::Color cv::viz::Color::cherry() { return Color( 99, 29, 222); }
|
||||
inline cv::viz::Color cv::viz::Color::bluberry() { return Color(247, 134, 79); }
|
||||
inline cv::viz::Color cv::viz::Color::raspberry() { return Color( 92, 11, 227); }
|
||||
inline cv::viz::Color cv::viz::Color::silver() { return Color(192, 192, 192); }
|
||||
inline cv::viz::Color cv::viz::Color::violet() { return Color(226, 43, 138); }
|
||||
inline cv::viz::Color cv::viz::Color::apricot() { return Color(177, 206, 251); }
|
||||
inline cv::viz::Color cv::viz::Color::turquoise() { return Color(208, 224, 64); }
|
||||
inline cv::viz::Color cv::viz::Color::celestial_blue() { return Color(208, 151, 73); }
|
||||
inline cv::viz::Color cv::viz::Color::amethyst() { return Color(204, 102, 153); }
|
||||
|
||||
inline cv::viz::Color cv::viz::Color::not_set() { return Color(-1, -1, -1); }
|
||||
|
||||
#endif
|
131
modules/viz/include/opencv2/viz/viz3d.hpp
Normal file
131
modules/viz/include/opencv2/viz/viz3d.hpp
Normal file
@@ -0,0 +1,131 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's 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.
|
||||
//
|
||||
// * The name of the copyright holders may not 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 Intel Corporation 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.
|
||||
//
|
||||
// Authors:
|
||||
// * Ozan Tonkal, ozantonkal@gmail.com
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __OPENCV_VIZ_VIZ3D_HPP__
|
||||
#define __OPENCV_VIZ_VIZ3D_HPP__
|
||||
|
||||
#if !defined YES_I_AGREE_THAT_VIZ_API_IS_NOT_STABLE_NOW_AND_BINARY_COMPARTIBILITY_WONT_BE_SUPPORTED && !defined CVAPI_EXPORTS
|
||||
//#error "Viz is in beta state now. Please define macro above to use it"
|
||||
#endif
|
||||
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/viz/types.hpp>
|
||||
#include <opencv2/viz/widgets.hpp>
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace viz
|
||||
{
|
||||
class CV_EXPORTS Viz3d
|
||||
{
|
||||
public:
|
||||
typedef cv::viz::Color Color;
|
||||
typedef void (*KeyboardCallback)(const KeyboardEvent&, void*);
|
||||
typedef void (*MouseCallback)(const MouseEvent&, void*);
|
||||
|
||||
Viz3d(const String& window_name = String());
|
||||
Viz3d(const Viz3d&);
|
||||
Viz3d& operator=(const Viz3d&);
|
||||
~Viz3d();
|
||||
|
||||
void showWidget(const String &id, const Widget &widget, const Affine3d &pose = Affine3d::Identity());
|
||||
void removeWidget(const String &id);
|
||||
Widget getWidget(const String &id) const;
|
||||
void removeAllWidgets();
|
||||
|
||||
void showImage(InputArray image, const Size& window_size = Size(-1, -1));
|
||||
|
||||
void setWidgetPose(const String &id, const Affine3d &pose);
|
||||
void updateWidgetPose(const String &id, const Affine3d &pose);
|
||||
Affine3d getWidgetPose(const String &id) const;
|
||||
|
||||
void setCamera(const Camera &camera);
|
||||
Camera getCamera() const;
|
||||
Affine3d getViewerPose();
|
||||
void setViewerPose(const Affine3d &pose);
|
||||
|
||||
void resetCameraViewpoint(const String &id);
|
||||
void resetCamera();
|
||||
|
||||
void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord);
|
||||
void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction);
|
||||
|
||||
Size getWindowSize() const;
|
||||
void setWindowSize(const Size &window_size);
|
||||
String getWindowName() const;
|
||||
void saveScreenshot(const String &file);
|
||||
void setWindowPosition(const Point& window_position);
|
||||
void setFullScreen(bool mode = true);
|
||||
void setBackgroundColor(const Color& color = Color::black(), const Color& color2 = Color::not_set());
|
||||
void setBackgroundTexture(InputArray image = noArray());
|
||||
void setBackgroundMeshLab();
|
||||
|
||||
void spin();
|
||||
void spinOnce(int time = 1, bool force_redraw = false);
|
||||
bool wasStopped() const;
|
||||
void close();
|
||||
|
||||
void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0);
|
||||
void registerMouseCallback(MouseCallback callback, void* cookie = 0);
|
||||
|
||||
void setRenderingProperty(const String &id, int property, double value);
|
||||
double getRenderingProperty(const String &id, int property);
|
||||
|
||||
void setRepresentation(int representation);
|
||||
private:
|
||||
|
||||
struct VizImpl;
|
||||
VizImpl* impl_;
|
||||
|
||||
void create(const String &window_name);
|
||||
void release();
|
||||
|
||||
friend class VizStorage;
|
||||
};
|
||||
|
||||
} /* namespace viz */
|
||||
} /* namespace cv */
|
||||
|
||||
#endif
|
127
modules/viz/include/opencv2/viz/vizcore.hpp
Normal file
127
modules/viz/include/opencv2/viz/vizcore.hpp
Normal file
@@ -0,0 +1,127 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's 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.
|
||||
//
|
||||
// * The name of the copyright holders may not 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 Intel Corporation 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.
|
||||
//
|
||||
// Authors:
|
||||
// * Ozan Tonkal, ozantonkal@gmail.com
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __OPENCV_VIZCORE_HPP__
|
||||
#define __OPENCV_VIZCORE_HPP__
|
||||
|
||||
#include <opencv2/viz/types.hpp>
|
||||
#include <opencv2/viz/widgets.hpp>
|
||||
#include <opencv2/viz/viz3d.hpp>
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace viz
|
||||
{
|
||||
//! takes coordiante frame data and builds transfrom to global coordinate frame
|
||||
CV_EXPORTS Affine3d makeTransformToGlobal(const Vec3d& axis_x, const Vec3d& axis_y, const Vec3d& axis_z, const Vec3d& origin = Vec3d::all(0));
|
||||
|
||||
//! constructs camera pose from position, focal_point and up_vector (see gluLookAt() for more infromation)
|
||||
CV_EXPORTS Affine3d makeCameraPose(const Vec3d& position, const Vec3d& focal_point, const Vec3d& y_dir);
|
||||
|
||||
//! retrieves a window by its name. If no window with such name, then it creates new.
|
||||
CV_EXPORTS Viz3d getWindowByName(const String &window_name);
|
||||
|
||||
//! Unregisters all Viz windows from internal database. After it 'getWindowByName()' will create new windows instead getting existing from the database.
|
||||
CV_EXPORTS void unregisterAllWindows();
|
||||
|
||||
//! Displays image in specified window
|
||||
CV_EXPORTS Viz3d imshow(const String& window_name, InputArray image, const Size& window_size = Size(-1, -1));
|
||||
|
||||
//! checks float value for Nan
|
||||
inline bool isNan(float x)
|
||||
{
|
||||
unsigned int *u = reinterpret_cast<unsigned int *>(&x);
|
||||
return ((u[0] & 0x7f800000) == 0x7f800000) && (u[0] & 0x007fffff);
|
||||
}
|
||||
|
||||
//! checks double value for Nan
|
||||
inline bool isNan(double x)
|
||||
{
|
||||
unsigned int *u = reinterpret_cast<unsigned int *>(&x);
|
||||
return (u[1] & 0x7ff00000) == 0x7ff00000 && (u[0] != 0 || (u[1] & 0x000fffff) != 0);
|
||||
}
|
||||
|
||||
//! checks vectors for Nans
|
||||
template<typename _Tp, int cn> inline bool isNan(const Vec<_Tp, cn>& v)
|
||||
{ return isNan(v.val[0]) || isNan(v.val[1]) || isNan(v.val[2]); }
|
||||
|
||||
//! checks point for Nans
|
||||
template<typename _Tp> inline bool isNan(const Point3_<_Tp>& p)
|
||||
{ return isNan(p.x) || isNan(p.y) || isNan(p.z); }
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Read/write clouds. Supported formats: ply, xyz, obj and stl (readonly)
|
||||
|
||||
CV_EXPORTS void writeCloud(const String& file, InputArray cloud, InputArray colors = noArray(), InputArray normals = noArray(), bool binary = false);
|
||||
CV_EXPORTS Mat readCloud (const String& file, OutputArray colors = noArray(), OutputArray normals = noArray());
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Reads mesh. Only ply format is supported now and no texture load support
|
||||
|
||||
CV_EXPORTS Mesh readMesh(const String& file);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Read/write poses and trajectories
|
||||
|
||||
CV_EXPORTS bool readPose(const String& file, Affine3d& pose, const String& tag = "pose");
|
||||
CV_EXPORTS void writePose(const String& file, const Affine3d& pose, const String& tag = "pose");
|
||||
|
||||
//! takes vector<Affine3<T>> with T = float/dobule and writes to a sequence of files with given filename format
|
||||
CV_EXPORTS void writeTrajectory(InputArray traj, const String& files_format = "pose%05d.xml", int start = 0, const String& tag = "pose");
|
||||
|
||||
//! takes vector<Affine3<T>> with T = float/dobule and loads poses from sequence of files
|
||||
CV_EXPORTS void readTrajectory(OutputArray traj, const String& files_format = "pose%05d.xml", int start = 0, int end = INT_MAX, const String& tag = "pose");
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Computing normals for mesh
|
||||
|
||||
CV_EXPORTS void computeNormals(const Mesh& mesh, OutputArray normals);
|
||||
|
||||
} /* namespace viz */
|
||||
} /* namespace cv */
|
||||
|
||||
#endif /* __OPENCV_VIZCORE_HPP__ */
|
69
modules/viz/include/opencv2/viz/widget_accessor.hpp
Normal file
69
modules/viz/include/opencv2/viz/widget_accessor.hpp
Normal file
@@ -0,0 +1,69 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's 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.
|
||||
//
|
||||
// * The name of the copyright holders may not 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 Intel Corporation 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.
|
||||
//
|
||||
// Authors:
|
||||
// * Ozan Tonkal, ozantonkal@gmail.com
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __OPENCV_VIZ_WIDGET_ACCESSOR_HPP__
|
||||
#define __OPENCV_VIZ_WIDGET_ACCESSOR_HPP__
|
||||
|
||||
#include <opencv2/core/types_c.h>
|
||||
#include <vtkSmartPointer.h>
|
||||
#include <vtkProp.h>
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace viz
|
||||
{
|
||||
class Widget;
|
||||
|
||||
//The class is only that depends on VTK in its interface.
|
||||
//It is indended for those users who want to develop own widgets system using VTK library API.
|
||||
struct CV_EXPORTS WidgetAccessor
|
||||
{
|
||||
static vtkSmartPointer<vtkProp> getProp(const Widget &widget);
|
||||
static void setProp(Widget &widget, vtkSmartPointer<vtkProp> prop);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
396
modules/viz/include/opencv2/viz/widgets.hpp
Normal file
396
modules/viz/include/opencv2/viz/widgets.hpp
Normal file
@@ -0,0 +1,396 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's 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.
|
||||
//
|
||||
// * The name of the copyright holders may not 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 Intel Corporation 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.
|
||||
//
|
||||
// Authors:
|
||||
// * Ozan Tonkal, ozantonkal@gmail.com
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __OPENCV_VIZ_WIDGETS_HPP__
|
||||
#define __OPENCV_VIZ_WIDGETS_HPP__
|
||||
|
||||
#include <opencv2/viz/types.hpp>
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace viz
|
||||
{
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/// Widget rendering properties
|
||||
enum RenderingProperties
|
||||
{
|
||||
POINT_SIZE,
|
||||
OPACITY,
|
||||
LINE_WIDTH,
|
||||
FONT_SIZE,
|
||||
REPRESENTATION,
|
||||
IMMEDIATE_RENDERING,
|
||||
SHADING
|
||||
};
|
||||
|
||||
enum RepresentationValues
|
||||
{
|
||||
REPRESENTATION_POINTS,
|
||||
REPRESENTATION_WIREFRAME,
|
||||
REPRESENTATION_SURFACE
|
||||
};
|
||||
|
||||
enum ShadingValues
|
||||
{
|
||||
SHADING_FLAT,
|
||||
SHADING_GOURAUD,
|
||||
SHADING_PHONG
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/// The base class for all widgets
|
||||
class CV_EXPORTS Widget
|
||||
{
|
||||
public:
|
||||
Widget();
|
||||
Widget(const Widget& other);
|
||||
Widget& operator=(const Widget& other);
|
||||
~Widget();
|
||||
|
||||
//! Create a widget directly from ply file
|
||||
static Widget fromPlyFile(const String &file_name);
|
||||
|
||||
//! Rendering properties of this particular widget
|
||||
void setRenderingProperty(int property, double value);
|
||||
double getRenderingProperty(int property) const;
|
||||
|
||||
//! Casting between widgets
|
||||
template<typename _W> _W cast();
|
||||
private:
|
||||
class Impl;
|
||||
Impl *impl_;
|
||||
friend struct WidgetAccessor;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/// The base class for all 3D widgets
|
||||
class CV_EXPORTS Widget3D : public Widget
|
||||
{
|
||||
public:
|
||||
Widget3D() {}
|
||||
|
||||
//! widget position manipulation, i.e. place where it is rendered
|
||||
void setPose(const Affine3d &pose);
|
||||
void updatePose(const Affine3d &pose);
|
||||
Affine3d getPose() const;
|
||||
|
||||
//! update internal widget data, i.e. points, normals, etc.
|
||||
void applyTransform(const Affine3d &transform);
|
||||
|
||||
void setColor(const Color &color);
|
||||
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/// The base class for all 2D widgets
|
||||
class CV_EXPORTS Widget2D : public Widget
|
||||
{
|
||||
public:
|
||||
Widget2D() {}
|
||||
|
||||
void setColor(const Color &color);
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/// Simple widgets
|
||||
|
||||
class CV_EXPORTS WLine : public Widget3D
|
||||
{
|
||||
public:
|
||||
WLine(const Point3d &pt1, const Point3d &pt2, const Color &color = Color::white());
|
||||
};
|
||||
|
||||
class CV_EXPORTS WPlane : public Widget3D
|
||||
{
|
||||
public:
|
||||
//! created default plane with center point at origin and normal oriented along z-axis
|
||||
WPlane(const Size2d& size = Size2d(1.0, 1.0), const Color &color = Color::white());
|
||||
|
||||
//! repositioned plane
|
||||
WPlane(const Point3d& center, const Vec3d& normal, const Vec3d& new_yaxis,
|
||||
const Size2d& size = Size2d(1.0, 1.0), const Color &color = Color::white());
|
||||
};
|
||||
|
||||
class CV_EXPORTS WSphere : public Widget3D
|
||||
{
|
||||
public:
|
||||
WSphere(const cv::Point3d ¢er, double radius, int sphere_resolution = 10, const Color &color = Color::white());
|
||||
};
|
||||
|
||||
class CV_EXPORTS WArrow : public Widget3D
|
||||
{
|
||||
public:
|
||||
WArrow(const Point3d& pt1, const Point3d& pt2, double thickness = 0.03, const Color &color = Color::white());
|
||||
};
|
||||
|
||||
class CV_EXPORTS WCircle : public Widget3D
|
||||
{
|
||||
public:
|
||||
//! creates default planar circle centred at origin with plane normal along z-axis
|
||||
WCircle(double radius, double thickness = 0.01, const Color &color = Color::white());
|
||||
|
||||
//! creates repositioned circle
|
||||
WCircle(double radius, const Point3d& center, const Vec3d& normal, double thickness = 0.01, const Color &color = Color::white());
|
||||
};
|
||||
|
||||
class CV_EXPORTS WCone : public Widget3D
|
||||
{
|
||||
public:
|
||||
//! create default cone, oriented along x-axis with center of its base located at origin
|
||||
WCone(double length, double radius, int resolution = 6.0, const Color &color = Color::white());
|
||||
|
||||
//! creates repositioned cone
|
||||
WCone(double radius, const Point3d& center, const Point3d& tip, int resolution = 6.0, const Color &color = Color::white());
|
||||
};
|
||||
|
||||
class CV_EXPORTS WCylinder : public Widget3D
|
||||
{
|
||||
public:
|
||||
WCylinder(const Point3d& axis_point1, const Point3d& axis_point2, double radius, int numsides = 30, const Color &color = Color::white());
|
||||
};
|
||||
|
||||
class CV_EXPORTS WCube : public Widget3D
|
||||
{
|
||||
public:
|
||||
WCube(const Point3d& min_point = Vec3d::all(-0.5), const Point3d& max_point = Vec3d::all(0.5),
|
||||
bool wire_frame = true, const Color &color = Color::white());
|
||||
};
|
||||
|
||||
class CV_EXPORTS WPolyLine : public Widget3D
|
||||
{
|
||||
public:
|
||||
WPolyLine(InputArray points, const Color &color = Color::white());
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/// Text and image widgets
|
||||
|
||||
class CV_EXPORTS WText : public Widget2D
|
||||
{
|
||||
public:
|
||||
WText(const String &text, const Point &pos, int font_size = 20, const Color &color = Color::white());
|
||||
|
||||
void setText(const String &text);
|
||||
String getText() const;
|
||||
};
|
||||
|
||||
class CV_EXPORTS WText3D : public Widget3D
|
||||
{
|
||||
public:
|
||||
//! creates text label in 3D. If face_camera = false, text plane normal is oriented along z-axis. Use widget pose to orient it properly
|
||||
WText3D(const String &text, const Point3d &position, double text_scale = 1., bool face_camera = true, const Color &color = Color::white());
|
||||
|
||||
void setText(const String &text);
|
||||
String getText() const;
|
||||
};
|
||||
|
||||
class CV_EXPORTS WImageOverlay : public Widget2D
|
||||
{
|
||||
public:
|
||||
WImageOverlay(InputArray image, const Rect &rect);
|
||||
void setImage(InputArray image);
|
||||
};
|
||||
|
||||
class CV_EXPORTS WImage3D : public Widget3D
|
||||
{
|
||||
public:
|
||||
//! Creates 3D image in a plane centered at the origin with normal orientaion along z-axis,
|
||||
//! image x- and y-axes are oriented along x- and y-axes of 3d world
|
||||
WImage3D(InputArray image, const Size2d &size);
|
||||
|
||||
//! Creates 3D image at a given position, pointing in the direction of the normal, and having the up_vector orientation
|
||||
WImage3D(InputArray image, const Size2d &size, const Vec3d ¢er, const Vec3d &normal, const Vec3d &up_vector);
|
||||
|
||||
void setImage(InputArray image);
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/// Compond widgets
|
||||
|
||||
class CV_EXPORTS WCoordinateSystem : public Widget3D
|
||||
{
|
||||
public:
|
||||
WCoordinateSystem(double scale = 1.0);
|
||||
};
|
||||
|
||||
class CV_EXPORTS WGrid : public Widget3D
|
||||
{
|
||||
public:
|
||||
//! Creates grid at the origin and normal oriented along z-axis
|
||||
WGrid(const Vec2i &cells = Vec2i::all(10), const Vec2d &cells_spacing = Vec2d::all(1.0), const Color &color = Color::white());
|
||||
|
||||
//! Creates repositioned grid
|
||||
WGrid(const Point3d& center, const Vec3d& normal, const Vec3d& new_yaxis,
|
||||
const Vec2i &cells = Vec2i::all(10), const Vec2d &cells_spacing = Vec2d::all(1.0), const Color &color = Color::white());
|
||||
};
|
||||
|
||||
class CV_EXPORTS WCameraPosition : public Widget3D
|
||||
{
|
||||
public:
|
||||
//! Creates camera coordinate frame (axes) at the origin
|
||||
WCameraPosition(double scale = 1.0);
|
||||
//! Creates frustum based on the intrinsic marix K at the origin
|
||||
WCameraPosition(const Matx33d &K, double scale = 1.0, const Color &color = Color::white());
|
||||
//! Creates frustum based on the field of view at the origin
|
||||
WCameraPosition(const Vec2d &fov, double scale = 1.0, const Color &color = Color::white());
|
||||
//! Creates frustum and display given image at the far plane
|
||||
WCameraPosition(const Matx33d &K, InputArray image, double scale = 1.0, const Color &color = Color::white());
|
||||
//! Creates frustum and display given image at the far plane
|
||||
WCameraPosition(const Vec2d &fov, InputArray image, double scale = 1.0, const Color &color = Color::white());
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/// Trajectories
|
||||
|
||||
class CV_EXPORTS WTrajectory : public Widget3D
|
||||
{
|
||||
public:
|
||||
enum {FRAMES = 1, PATH = 2, BOTH = FRAMES + PATH };
|
||||
|
||||
//! Takes vector<Affine3<T>> and displays trajectory of the given path either by coordinate frames or polyline
|
||||
WTrajectory(InputArray path, int display_mode = WTrajectory::PATH, double scale = 1.0, const Color &color = Color::white());
|
||||
};
|
||||
|
||||
class CV_EXPORTS WTrajectoryFrustums : public Widget3D
|
||||
{
|
||||
public:
|
||||
//! Takes vector<Affine3<T>> and displays trajectory of the given path by frustums
|
||||
WTrajectoryFrustums(InputArray path, const Matx33d &K, double scale = 1., const Color &color = Color::white());
|
||||
|
||||
//! Takes vector<Affine3<T>> and displays trajectory of the given path by frustums
|
||||
WTrajectoryFrustums(InputArray path, const Vec2d &fov, double scale = 1., const Color &color = Color::white());
|
||||
};
|
||||
|
||||
class CV_EXPORTS WTrajectorySpheres: public Widget3D
|
||||
{
|
||||
public:
|
||||
//! Takes vector<Affine3<T>> and displays trajectory of the given path
|
||||
WTrajectorySpheres(InputArray path, double line_length = 0.05, double radius = 0.007,
|
||||
const Color &from = Color::red(), const Color &to = Color::white());
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/// Clouds
|
||||
|
||||
class CV_EXPORTS WCloud: public Widget3D
|
||||
{
|
||||
public:
|
||||
//! Each point in cloud is mapped to a color in colors
|
||||
WCloud(InputArray cloud, InputArray colors);
|
||||
//! All points in cloud have the same color
|
||||
WCloud(InputArray cloud, const Color &color = Color::white());
|
||||
};
|
||||
|
||||
class CV_EXPORTS WPaintedCloud: public Widget3D
|
||||
{
|
||||
public:
|
||||
//! Paint cloud with default gradient between cloud bounds points
|
||||
WPaintedCloud(InputArray cloud);
|
||||
|
||||
//! Paint cloud with default gradient between given points
|
||||
WPaintedCloud(InputArray cloud, const Point3d& p1, const Point3d& p2);
|
||||
|
||||
//! Paint cloud with gradient specified by given colors between given points
|
||||
WPaintedCloud(InputArray cloud, const Point3d& p1, const Point3d& p2, const Color& c1, const Color c2);
|
||||
};
|
||||
|
||||
class CV_EXPORTS WCloudCollection : public Widget3D
|
||||
{
|
||||
public:
|
||||
WCloudCollection();
|
||||
|
||||
//! Each point in cloud is mapped to a color in colors
|
||||
void addCloud(InputArray cloud, InputArray colors, const Affine3d &pose = Affine3d::Identity());
|
||||
//! All points in cloud have the same color
|
||||
void addCloud(InputArray cloud, const Color &color = Color::white(), const Affine3d &pose = Affine3d::Identity());
|
||||
};
|
||||
|
||||
class CV_EXPORTS WCloudNormals : public Widget3D
|
||||
{
|
||||
public:
|
||||
WCloudNormals(InputArray cloud, InputArray normals, int level = 64, double scale = 0.1, const Color &color = Color::white());
|
||||
};
|
||||
|
||||
class CV_EXPORTS WMesh : public Widget3D
|
||||
{
|
||||
public:
|
||||
WMesh(const Mesh &mesh);
|
||||
WMesh(InputArray cloud, InputArray polygons, InputArray colors = noArray(), InputArray normals = noArray());
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/// Utility exports
|
||||
|
||||
template<> CV_EXPORTS Widget2D Widget::cast<Widget2D>();
|
||||
template<> CV_EXPORTS Widget3D Widget::cast<Widget3D>();
|
||||
template<> CV_EXPORTS WLine Widget::cast<WLine>();
|
||||
template<> CV_EXPORTS WPlane Widget::cast<WPlane>();
|
||||
template<> CV_EXPORTS WSphere Widget::cast<WSphere>();
|
||||
template<> CV_EXPORTS WCylinder Widget::cast<WCylinder>();
|
||||
template<> CV_EXPORTS WArrow Widget::cast<WArrow>();
|
||||
template<> CV_EXPORTS WCircle Widget::cast<WCircle>();
|
||||
template<> CV_EXPORTS WCone Widget::cast<WCone>();
|
||||
template<> CV_EXPORTS WCube Widget::cast<WCube>();
|
||||
template<> CV_EXPORTS WCoordinateSystem Widget::cast<WCoordinateSystem>();
|
||||
template<> CV_EXPORTS WPolyLine Widget::cast<WPolyLine>();
|
||||
template<> CV_EXPORTS WGrid Widget::cast<WGrid>();
|
||||
template<> CV_EXPORTS WText3D Widget::cast<WText3D>();
|
||||
template<> CV_EXPORTS WText Widget::cast<WText>();
|
||||
template<> CV_EXPORTS WImageOverlay Widget::cast<WImageOverlay>();
|
||||
template<> CV_EXPORTS WImage3D Widget::cast<WImage3D>();
|
||||
template<> CV_EXPORTS WCameraPosition Widget::cast<WCameraPosition>();
|
||||
template<> CV_EXPORTS WTrajectory Widget::cast<WTrajectory>();
|
||||
template<> CV_EXPORTS WTrajectoryFrustums Widget::cast<WTrajectoryFrustums>();
|
||||
template<> CV_EXPORTS WTrajectorySpheres Widget::cast<WTrajectorySpheres>();
|
||||
template<> CV_EXPORTS WCloud Widget::cast<WCloud>();
|
||||
template<> CV_EXPORTS WPaintedCloud Widget::cast<WPaintedCloud>();
|
||||
template<> CV_EXPORTS WCloudCollection Widget::cast<WCloudCollection>();
|
||||
template<> CV_EXPORTS WCloudNormals Widget::cast<WCloudNormals>();
|
||||
template<> CV_EXPORTS WMesh Widget::cast<WMesh>();
|
||||
|
||||
} /* namespace viz */
|
||||
} /* namespace cv */
|
||||
|
||||
#endif
|
441
modules/viz/src/clouds.cpp
Normal file
441
modules/viz/src/clouds.cpp
Normal file
@@ -0,0 +1,441 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's 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.
|
||||
//
|
||||
// * The name of the copyright holders may not 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 Intel Corporation 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.
|
||||
//
|
||||
// Authors:
|
||||
// * Ozan Tonkal, ozantonkal@gmail.com
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Point Cloud Widget implementation
|
||||
|
||||
cv::viz::WCloud::WCloud(InputArray cloud, InputArray colors)
|
||||
{
|
||||
CV_Assert(!cloud.empty() && !colors.empty());
|
||||
|
||||
vtkSmartPointer<vtkCloudMatSource> cloud_source = vtkSmartPointer<vtkCloudMatSource>::New();
|
||||
cloud_source->SetColorCloud(cloud, colors);
|
||||
cloud_source->Update();
|
||||
|
||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||
VtkUtils::SetInputData(mapper, cloud_source->GetOutput());
|
||||
mapper->SetScalarModeToUsePointData();
|
||||
mapper->ImmediateModeRenderingOff();
|
||||
mapper->SetScalarRange(0, 255);
|
||||
mapper->ScalarVisibilityOn();
|
||||
|
||||
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
||||
actor->GetProperty()->SetInterpolationToFlat();
|
||||
actor->GetProperty()->BackfaceCullingOn();
|
||||
actor->SetMapper(mapper);
|
||||
|
||||
WidgetAccessor::setProp(*this, actor);
|
||||
}
|
||||
|
||||
cv::viz::WCloud::WCloud(InputArray cloud, const Color &color)
|
||||
{
|
||||
WCloud cloud_widget(cloud, Mat(cloud.size(), CV_8UC3, color));
|
||||
*this = cloud_widget;
|
||||
}
|
||||
|
||||
|
||||
template<> cv::viz::WCloud cv::viz::Widget::cast<cv::viz::WCloud>()
|
||||
{
|
||||
Widget3D widget = this->cast<Widget3D>();
|
||||
return static_cast<WCloud&>(widget);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Painted Cloud Widget implementation
|
||||
|
||||
cv::viz::WPaintedCloud::WPaintedCloud(InputArray cloud)
|
||||
{
|
||||
vtkSmartPointer<vtkCloudMatSource> cloud_source = vtkSmartPointer<vtkCloudMatSource>::New();
|
||||
cloud_source->SetCloud(cloud);
|
||||
cloud_source->Update();
|
||||
|
||||
Vec6d bounds(cloud_source->GetOutput()->GetPoints()->GetBounds());
|
||||
|
||||
vtkSmartPointer<vtkElevationFilter> elevation = vtkSmartPointer<vtkElevationFilter>::New();
|
||||
elevation->SetInputConnection(cloud_source->GetOutputPort());
|
||||
elevation->SetLowPoint(bounds[0], bounds[2], bounds[4]);
|
||||
elevation->SetHighPoint(bounds[1], bounds[3], bounds[5]);
|
||||
elevation->SetScalarRange(0.0, 1.0);
|
||||
elevation->Update();
|
||||
|
||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||
VtkUtils::SetInputData(mapper, vtkPolyData::SafeDownCast(elevation->GetOutput()));
|
||||
mapper->ImmediateModeRenderingOff();
|
||||
mapper->ScalarVisibilityOn();
|
||||
mapper->SetColorModeToMapScalars();
|
||||
|
||||
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
||||
actor->GetProperty()->SetInterpolationToFlat();
|
||||
actor->GetProperty()->BackfaceCullingOn();
|
||||
actor->SetMapper(mapper);
|
||||
|
||||
WidgetAccessor::setProp(*this, actor);
|
||||
}
|
||||
|
||||
cv::viz::WPaintedCloud::WPaintedCloud(InputArray cloud, const Point3d& p1, const Point3d& p2)
|
||||
{
|
||||
vtkSmartPointer<vtkCloudMatSource> cloud_source = vtkSmartPointer<vtkCloudMatSource>::New();
|
||||
cloud_source->SetCloud(cloud);
|
||||
|
||||
vtkSmartPointer<vtkElevationFilter> elevation = vtkSmartPointer<vtkElevationFilter>::New();
|
||||
elevation->SetInputConnection(cloud_source->GetOutputPort());
|
||||
elevation->SetLowPoint(p1.x, p1.y, p1.z);
|
||||
elevation->SetHighPoint(p2.x, p2.y, p2.z);
|
||||
elevation->SetScalarRange(0.0, 1.0);
|
||||
elevation->Update();
|
||||
|
||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||
VtkUtils::SetInputData(mapper, vtkPolyData::SafeDownCast(elevation->GetOutput()));
|
||||
mapper->ImmediateModeRenderingOff();
|
||||
mapper->ScalarVisibilityOn();
|
||||
mapper->SetColorModeToMapScalars();
|
||||
|
||||
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
||||
actor->GetProperty()->SetInterpolationToFlat();
|
||||
actor->GetProperty()->BackfaceCullingOn();
|
||||
actor->SetMapper(mapper);
|
||||
|
||||
WidgetAccessor::setProp(*this, actor);
|
||||
}
|
||||
|
||||
cv::viz::WPaintedCloud::WPaintedCloud(InputArray cloud, const Point3d& p1, const Point3d& p2, const Color& c1, const Color c2)
|
||||
{
|
||||
vtkSmartPointer<vtkCloudMatSource> cloud_source = vtkSmartPointer<vtkCloudMatSource>::New();
|
||||
cloud_source->SetCloud(cloud);
|
||||
|
||||
vtkSmartPointer<vtkElevationFilter> elevation = vtkSmartPointer<vtkElevationFilter>::New();
|
||||
elevation->SetInputConnection(cloud_source->GetOutputPort());
|
||||
elevation->SetLowPoint(p1.x, p1.y, p1.z);
|
||||
elevation->SetHighPoint(p2.x, p2.y, p2.z);
|
||||
elevation->SetScalarRange(0.0, 1.0);
|
||||
elevation->Update();
|
||||
|
||||
Color vc1 = vtkcolor(c1), vc2 = vtkcolor(c2);
|
||||
vtkSmartPointer<vtkColorTransferFunction> color_transfer = vtkSmartPointer<vtkColorTransferFunction>::New();
|
||||
color_transfer->SetColorSpaceToRGB();
|
||||
color_transfer->AddRGBPoint(0.0, vc1[0], vc1[1], vc1[2]);
|
||||
color_transfer->AddRGBPoint(1.0, vc2[0], vc2[1], vc2[2]);
|
||||
color_transfer->SetScaleToLinear();
|
||||
color_transfer->Build();
|
||||
|
||||
//if in future some need to replace color table with real scalars, then this can be done usine next calls:
|
||||
//vtkDataArray *float_scalars = vtkPolyData::SafeDownCast(elevation->GetOutput())->GetPointData()->GetArray("Elevation");
|
||||
//vtkSmartPointer<vtkPolyData> polydata = cloud_source->GetOutput();
|
||||
//polydata->GetPointData()->SetScalars(color_transfer->MapScalars(float_scalars, VTK_COLOR_MODE_DEFAULT, 0));
|
||||
|
||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||
VtkUtils::SetInputData(mapper, vtkPolyData::SafeDownCast(elevation->GetOutput()));
|
||||
mapper->ImmediateModeRenderingOff();
|
||||
mapper->ScalarVisibilityOn();
|
||||
mapper->SetColorModeToMapScalars();
|
||||
mapper->SetLookupTable(color_transfer);
|
||||
|
||||
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
||||
actor->GetProperty()->SetInterpolationToFlat();
|
||||
actor->GetProperty()->BackfaceCullingOn();
|
||||
actor->SetMapper(mapper);
|
||||
|
||||
WidgetAccessor::setProp(*this, actor);
|
||||
}
|
||||
|
||||
template<> cv::viz::WPaintedCloud cv::viz::Widget::cast<cv::viz::WPaintedCloud>()
|
||||
{
|
||||
Widget3D widget = this->cast<Widget3D>();
|
||||
return static_cast<WPaintedCloud&>(widget);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Cloud Collection Widget implementation
|
||||
|
||||
cv::viz::WCloudCollection::WCloudCollection()
|
||||
{
|
||||
// Just create the actor
|
||||
vtkSmartPointer<vtkLODActor> actor = vtkSmartPointer<vtkLODActor>::New();
|
||||
WidgetAccessor::setProp(*this, actor);
|
||||
}
|
||||
|
||||
void cv::viz::WCloudCollection::addCloud(InputArray cloud, InputArray colors, const Affine3d &pose)
|
||||
{
|
||||
vtkSmartPointer<vtkCloudMatSource> source = vtkSmartPointer<vtkCloudMatSource>::New();
|
||||
source->SetColorCloud(cloud, colors);
|
||||
|
||||
vtkSmartPointer<vtkPolyData> polydata = VtkUtils::TransformPolydata(source->GetOutputPort(), pose);
|
||||
|
||||
vtkSmartPointer<vtkLODActor> actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this));
|
||||
CV_Assert("Incompatible widget type." && actor);
|
||||
|
||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper());
|
||||
if (!mapper)
|
||||
{
|
||||
// This is the first cloud
|
||||
mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||
mapper->SetScalarRange(0, 255);
|
||||
mapper->SetScalarModeToUsePointData();
|
||||
mapper->ScalarVisibilityOn();
|
||||
mapper->ImmediateModeRenderingOff();
|
||||
VtkUtils::SetInputData(mapper, polydata);
|
||||
|
||||
actor->SetNumberOfCloudPoints(std::max<vtkIdType>(1, polydata->GetNumberOfPoints()/10));
|
||||
actor->GetProperty()->SetInterpolationToFlat();
|
||||
actor->GetProperty()->BackfaceCullingOn();
|
||||
actor->SetMapper(mapper);
|
||||
return;
|
||||
}
|
||||
|
||||
vtkPolyData *currdata = vtkPolyData::SafeDownCast(mapper->GetInput());
|
||||
CV_Assert("Cloud Widget without data" && currdata);
|
||||
|
||||
vtkSmartPointer<vtkAppendPolyData> append_filter = vtkSmartPointer<vtkAppendPolyData>::New();
|
||||
VtkUtils::AddInputData(append_filter, currdata);
|
||||
VtkUtils::AddInputData(append_filter, polydata);
|
||||
append_filter->Update();
|
||||
|
||||
VtkUtils::SetInputData(mapper, append_filter->GetOutput());
|
||||
|
||||
actor->SetNumberOfCloudPoints(std::max<vtkIdType>(1, actor->GetNumberOfCloudPoints() + polydata->GetNumberOfPoints()/10));
|
||||
}
|
||||
|
||||
void cv::viz::WCloudCollection::addCloud(InputArray cloud, const Color &color, const Affine3d &pose)
|
||||
{
|
||||
addCloud(cloud, Mat(cloud.size(), CV_8UC3, color), pose);
|
||||
}
|
||||
|
||||
template<> cv::viz::WCloudCollection cv::viz::Widget::cast<cv::viz::WCloudCollection>()
|
||||
{
|
||||
Widget3D widget = this->cast<Widget3D>();
|
||||
return static_cast<WCloudCollection&>(widget);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Cloud Normals Widget implementation
|
||||
|
||||
cv::viz::WCloudNormals::WCloudNormals(InputArray _cloud, InputArray _normals, int level, double scale, const Color &color)
|
||||
{
|
||||
Mat cloud = _cloud.getMat();
|
||||
Mat normals = _normals.getMat();
|
||||
|
||||
CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4);
|
||||
CV_Assert(cloud.size() == normals.size() && cloud.type() == normals.type());
|
||||
|
||||
int sqlevel = (int)std::sqrt((double)level);
|
||||
int ystep = (cloud.cols > 1 && cloud.rows > 1) ? sqlevel : 1;
|
||||
int xstep = (cloud.cols > 1 && cloud.rows > 1) ? sqlevel : level;
|
||||
|
||||
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
|
||||
points->SetDataType(cloud.depth() == CV_32F ? VTK_FLOAT : VTK_DOUBLE);
|
||||
|
||||
vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
|
||||
|
||||
int s_chs = cloud.channels();
|
||||
int n_chs = normals.channels();
|
||||
int total = 0;
|
||||
|
||||
for(int y = 0; y < cloud.rows; y += ystep)
|
||||
{
|
||||
if (cloud.depth() == CV_32F)
|
||||
{
|
||||
const float *srow = cloud.ptr<float>(y);
|
||||
const float *send = srow + cloud.cols * s_chs;
|
||||
const float *nrow = normals.ptr<float>(y);
|
||||
|
||||
for (; srow < send; srow += xstep * s_chs, nrow += xstep * n_chs)
|
||||
if (!isNan(srow) && !isNan(nrow))
|
||||
{
|
||||
Vec3f endp = Vec3f(srow) + Vec3f(nrow) * (float)scale;
|
||||
|
||||
points->InsertNextPoint(srow);
|
||||
points->InsertNextPoint(endp.val);
|
||||
|
||||
lines->InsertNextCell(2);
|
||||
lines->InsertCellPoint(total++);
|
||||
lines->InsertCellPoint(total++);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const double *srow = cloud.ptr<double>(y);
|
||||
const double *send = srow + cloud.cols * s_chs;
|
||||
const double *nrow = normals.ptr<double>(y);
|
||||
|
||||
for (; srow < send; srow += xstep * s_chs, nrow += xstep * n_chs)
|
||||
if (!isNan(srow) && !isNan(nrow))
|
||||
{
|
||||
Vec3d endp = Vec3d(srow) + Vec3d(nrow) * (double)scale;
|
||||
|
||||
points->InsertNextPoint(srow);
|
||||
points->InsertNextPoint(endp.val);
|
||||
|
||||
lines->InsertNextCell(2);
|
||||
lines->InsertCellPoint(total++);
|
||||
lines->InsertCellPoint(total++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
|
||||
polyData->SetPoints(points);
|
||||
polyData->SetLines(lines);
|
||||
|
||||
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
|
||||
mapper->SetColorModeToMapScalars();
|
||||
mapper->SetScalarModeToUsePointData();
|
||||
VtkUtils::SetInputData(mapper, polyData);
|
||||
|
||||
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
||||
actor->SetMapper(mapper);
|
||||
|
||||
WidgetAccessor::setProp(*this, actor);
|
||||
setColor(color);
|
||||
}
|
||||
|
||||
template<> cv::viz::WCloudNormals cv::viz::Widget::cast<cv::viz::WCloudNormals>()
|
||||
{
|
||||
Widget3D widget = this->cast<Widget3D>();
|
||||
return static_cast<WCloudNormals&>(widget);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Mesh Widget implementation
|
||||
|
||||
cv::viz::WMesh::WMesh(const Mesh &mesh)
|
||||
{
|
||||
CV_Assert(mesh.cloud.rows == 1 && mesh.polygons.type() == CV_32SC1);
|
||||
|
||||
vtkSmartPointer<vtkCloudMatSource> source = vtkSmartPointer<vtkCloudMatSource>::New();
|
||||
source->SetColorCloudNormalsTCoords(mesh.cloud, mesh.colors, mesh.normals, mesh.tcoords);
|
||||
source->Update();
|
||||
|
||||
Mat lookup_buffer(1, mesh.cloud.total(), CV_32SC1);
|
||||
int *lookup = lookup_buffer.ptr<int>();
|
||||
for(int y = 0, index = 0; y < mesh.cloud.rows; ++y)
|
||||
{
|
||||
int s_chs = mesh.cloud.channels();
|
||||
|
||||
if (mesh.cloud.depth() == CV_32F)
|
||||
{
|
||||
const float* srow = mesh.cloud.ptr<float>(y);
|
||||
const float* send = srow + mesh.cloud.cols * s_chs;
|
||||
|
||||
for (; srow != send; srow += s_chs, ++lookup)
|
||||
if (!isNan(srow[0]) && !isNan(srow[1]) && !isNan(srow[2]))
|
||||
*lookup = index++;
|
||||
}
|
||||
|
||||
if (mesh.cloud.depth() == CV_64F)
|
||||
{
|
||||
const double* srow = mesh.cloud.ptr<double>(y);
|
||||
const double* send = srow + mesh.cloud.cols * s_chs;
|
||||
|
||||
for (; srow != send; srow += s_chs, ++lookup)
|
||||
if (!isNan(srow[0]) && !isNan(srow[1]) && !isNan(srow[2]))
|
||||
*lookup = index++;
|
||||
}
|
||||
}
|
||||
lookup = lookup_buffer.ptr<int>();
|
||||
|
||||
vtkSmartPointer<vtkPolyData> polydata = source->GetOutput();
|
||||
polydata->SetVerts(0);
|
||||
|
||||
const int * polygons = mesh.polygons.ptr<int>();
|
||||
vtkSmartPointer<vtkCellArray> cell_array = vtkSmartPointer<vtkCellArray>::New();
|
||||
|
||||
int idx = 0;
|
||||
size_t polygons_size = mesh.polygons.total();
|
||||
for (size_t i = 0; i < polygons_size; ++idx)
|
||||
{
|
||||
int n_points = polygons[i++];
|
||||
|
||||
cell_array->InsertNextCell(n_points);
|
||||
for (int j = 0; j < n_points; ++j, ++idx)
|
||||
cell_array->InsertCellPoint(lookup[polygons[i++]]);
|
||||
}
|
||||
cell_array->GetData()->SetNumberOfValues(idx);
|
||||
cell_array->Squeeze();
|
||||
polydata->SetStrips(cell_array);
|
||||
|
||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||
mapper->SetScalarModeToUsePointData();
|
||||
mapper->ImmediateModeRenderingOff();
|
||||
VtkUtils::SetInputData(mapper, polydata);
|
||||
|
||||
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
||||
//actor->SetNumberOfCloudPoints(std::max(1, polydata->GetNumberOfPoints() / 10));
|
||||
actor->GetProperty()->SetRepresentationToSurface();
|
||||
actor->GetProperty()->BackfaceCullingOff(); // Backface culling is off for higher efficiency
|
||||
actor->GetProperty()->SetInterpolationToFlat();
|
||||
actor->GetProperty()->EdgeVisibilityOff();
|
||||
actor->GetProperty()->ShadingOff();
|
||||
actor->SetMapper(mapper);
|
||||
|
||||
if (!mesh.texture.empty())
|
||||
{
|
||||
vtkSmartPointer<vtkImageMatSource> image_source = vtkSmartPointer<vtkImageMatSource>::New();
|
||||
image_source->SetImage(mesh.texture);
|
||||
|
||||
vtkSmartPointer<vtkTexture> texture = vtkSmartPointer<vtkTexture>::New();
|
||||
texture->SetInputConnection(image_source->GetOutputPort());
|
||||
actor->SetTexture(texture);
|
||||
}
|
||||
|
||||
WidgetAccessor::setProp(*this, actor);
|
||||
}
|
||||
|
||||
cv::viz::WMesh::WMesh(InputArray cloud, InputArray polygons, InputArray colors, InputArray normals)
|
||||
{
|
||||
Mesh mesh;
|
||||
mesh.cloud = cloud.getMat();
|
||||
mesh.colors = colors.getMat();
|
||||
mesh.normals = normals.getMat();
|
||||
mesh.polygons = polygons.getMat();
|
||||
*this = WMesh(mesh);
|
||||
}
|
||||
|
||||
template<> CV_EXPORTS cv::viz::WMesh cv::viz::Widget::cast<cv::viz::WMesh>()
|
||||
{
|
||||
Widget3D widget = this->cast<Widget3D>();
|
||||
return static_cast<WMesh&>(widget);
|
||||
}
|
639
modules/viz/src/interactor_style.cpp
Normal file
639
modules/viz/src/interactor_style.cpp
Normal file
@@ -0,0 +1,639 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's 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.
|
||||
//
|
||||
// * The name of the copyright holders may not 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 Intel Corporation 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.
|
||||
//
|
||||
// Authors:
|
||||
// * Ozan Tonkal, ozantonkal@gmail.com
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
// OpenCV Viz module is complete rewrite of
|
||||
// PCL visualization module (www.pointclouds.org)
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
|
||||
namespace cv { namespace viz
|
||||
{
|
||||
vtkStandardNewMacro(InteractorStyle)
|
||||
}}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::InteractorStyle::Initialize()
|
||||
{
|
||||
// Set windows size (width, height) to unknown (-1)
|
||||
win_size_ = Vec2i(-1, -1);
|
||||
win_pos_ = Vec2i(0, 0);
|
||||
max_win_size_ = Vec2i(-1, -1);
|
||||
|
||||
init_ = true;
|
||||
stereo_anaglyph_mask_default_ = true;
|
||||
|
||||
// Initialize the keyboard event callback as none
|
||||
keyboardCallback_ = 0;
|
||||
keyboard_callback_cookie_ = 0;
|
||||
|
||||
// Initialize the mouse event callback as none
|
||||
mouseCallback_ = 0;
|
||||
mouse_callback_cookie_ = 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::InteractorStyle::saveScreenshot(const String &file)
|
||||
{
|
||||
FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]);
|
||||
|
||||
vtkSmartPointer<vtkWindowToImageFilter> wif = vtkSmartPointer<vtkWindowToImageFilter>::New();
|
||||
wif->SetInput(Interactor->GetRenderWindow());
|
||||
|
||||
vtkSmartPointer<vtkPNGWriter> snapshot_writer = vtkSmartPointer<vtkPNGWriter>::New();
|
||||
snapshot_writer->SetInputConnection(wif->GetOutputPort());
|
||||
snapshot_writer->SetFileName(file.c_str());
|
||||
snapshot_writer->Write();
|
||||
|
||||
cout << "Screenshot successfully captured (" << file.c_str() << ")" << endl;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::InteractorStyle::exportScene(const String &file)
|
||||
{
|
||||
vtkSmartPointer<vtkExporter> exporter;
|
||||
if (file.size() > 5 && file.substr(file.size() - 5) == ".vrml")
|
||||
{
|
||||
exporter = vtkSmartPointer<vtkVRMLExporter>::New();
|
||||
vtkVRMLExporter::SafeDownCast(exporter)->SetFileName(file.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
exporter = vtkSmartPointer<vtkOBJExporter>::New();
|
||||
vtkOBJExporter::SafeDownCast(exporter)->SetFilePrefix(file.c_str());
|
||||
}
|
||||
|
||||
exporter->SetInput(Interactor->GetRenderWindow());
|
||||
exporter->Write();
|
||||
|
||||
cout << "Scene successfully exported (" << file.c_str() << ")" << endl;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::InteractorStyle::zoomIn()
|
||||
{
|
||||
FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]);
|
||||
// Zoom in
|
||||
StartDolly();
|
||||
double factor = 10.0 * 0.2 * .5;
|
||||
Dolly(std::pow(1.1, factor));
|
||||
EndDolly();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::InteractorStyle::zoomOut()
|
||||
{
|
||||
FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]);
|
||||
// Zoom out
|
||||
StartDolly();
|
||||
double factor = 10.0 * -0.2 * .5;
|
||||
Dolly(std::pow(1.1, factor));
|
||||
EndDolly();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::InteractorStyle::OnChar()
|
||||
{
|
||||
// Make sure we ignore the same events we handle in OnKeyDown to avoid calling things twice
|
||||
FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]);
|
||||
if (Interactor->GetKeyCode() >= '0' && Interactor->GetKeyCode() <= '9')
|
||||
return;
|
||||
|
||||
String key(Interactor->GetKeySym());
|
||||
if (key.find("XF86ZoomIn") != String::npos)
|
||||
zoomIn();
|
||||
else if (key.find("XF86ZoomOut") != String::npos)
|
||||
zoomOut();
|
||||
|
||||
int keymod = Interactor->GetAltKey();
|
||||
|
||||
switch (Interactor->GetKeyCode())
|
||||
{
|
||||
// All of the options below simply exit
|
||||
case 'h': case 'H':
|
||||
case 'l': case 'L':
|
||||
case 'p': case 'P':
|
||||
case 'j': case 'J':
|
||||
case 'c': case 'C':
|
||||
case 43: // KEY_PLUS
|
||||
case 45: // KEY_MINUS
|
||||
case 'f': case 'F':
|
||||
case 'g': case 'G':
|
||||
case 'o': case 'O':
|
||||
case 'u': case 'U':
|
||||
case 'q': case 'Q':
|
||||
{
|
||||
break;
|
||||
}
|
||||
// S and R have a special !ALT case
|
||||
case 'r': case 'R':
|
||||
case 's': case 'S':
|
||||
{
|
||||
if (!keymod)
|
||||
Superclass::OnChar();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
Superclass::OnChar();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::InteractorStyle::registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie)
|
||||
{
|
||||
// Register the callback function and store the user data
|
||||
mouseCallback_ = callback;
|
||||
mouse_callback_cookie_ = cookie;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::InteractorStyle::registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void *cookie)
|
||||
{
|
||||
// Register the callback function and store the user data
|
||||
keyboardCallback_ = callback;
|
||||
keyboard_callback_cookie_ = cookie;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
int cv::viz::InteractorStyle::getModifiers()
|
||||
{
|
||||
int modifiers = KeyboardEvent::NONE;
|
||||
|
||||
if (Interactor->GetAltKey())
|
||||
modifiers |= KeyboardEvent::ALT;
|
||||
|
||||
if (Interactor->GetControlKey())
|
||||
modifiers |= KeyboardEvent::CTRL;
|
||||
|
||||
if (Interactor->GetShiftKey())
|
||||
modifiers |= KeyboardEvent::SHIFT;
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::InteractorStyle::OnKeyDown()
|
||||
{
|
||||
CV_Assert("Interactor style not initialized. Please call Initialize() before continuing" && init_);
|
||||
FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]);
|
||||
|
||||
// Save the initial windows width/height
|
||||
if (win_size_[0] == -1 || win_size_[1] == -1)
|
||||
win_size_ = Vec2i(Interactor->GetRenderWindow()->GetSize());
|
||||
|
||||
bool alt = Interactor->GetAltKey() != 0;
|
||||
|
||||
std::string key(Interactor->GetKeySym());
|
||||
if (key.find("XF86ZoomIn") != std::string::npos)
|
||||
zoomIn();
|
||||
else if (key.find("XF86ZoomOut") != std::string::npos)
|
||||
zoomOut();
|
||||
|
||||
switch (Interactor->GetKeyCode())
|
||||
{
|
||||
case 'h': case 'H':
|
||||
{
|
||||
std::cout << "| Help:\n"
|
||||
"-------\n"
|
||||
" p, P : switch to a point-based representation\n"
|
||||
" w, W : switch to a wireframe-based representation (where available)\n"
|
||||
" s, S : switch to a surface-based representation (where available)\n"
|
||||
"\n"
|
||||
" j, J : take a .PNG snapshot of the current window view\n"
|
||||
" k, K : export scene to Wavefront .obj format\n"
|
||||
" ALT + k, K : export scene to VRML format\n"
|
||||
" c, C : display current camera/window parameters\n"
|
||||
" f, F : fly to point mode, hold the key and move mouse where to fly\n"
|
||||
"\n"
|
||||
" e, E : exit the interactor\n"
|
||||
" q, Q : stop and call VTK's TerminateApp\n"
|
||||
"\n"
|
||||
" +/- : increment/decrement overall point size\n"
|
||||
" +/- [+ ALT] : zoom in/out \n"
|
||||
"\n"
|
||||
" r, R [+ ALT] : reset camera [to viewpoint = {0, 0, 0} -> center_{x, y, z}]\n"
|
||||
"\n"
|
||||
" ALT + s, S : turn stereo mode on/off\n"
|
||||
" ALT + f, F : switch between maximized window mode and original size\n"
|
||||
"\n"
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
// Switch representation to points
|
||||
case 'p': case 'P':
|
||||
{
|
||||
vtkSmartPointer<vtkActorCollection> ac = CurrentRenderer->GetActors();
|
||||
vtkCollectionSimpleIterator ait;
|
||||
for (ac->InitTraversal(ait); vtkActor* actor = ac->GetNextActor(ait); )
|
||||
for (actor->InitPathTraversal(); vtkAssemblyPath* path = actor->GetNextPath(); )
|
||||
{
|
||||
vtkActor* apart = vtkActor::SafeDownCast(path->GetLastNode()->GetViewProp());
|
||||
apart->GetProperty()->SetRepresentationToPoints();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Save a PNG snapshot
|
||||
case 'j': case 'J':
|
||||
saveScreenshot(cv::format("screenshot-%d.png", (unsigned int)time(0))); break;
|
||||
|
||||
// Export scene as in obj or vrml format
|
||||
case 'k': case 'K':
|
||||
{
|
||||
String format = alt ? "scene-%d.vrml" : "scene-%d";
|
||||
exportScene(cv::format(format.c_str(), (unsigned int)time(0)));
|
||||
break;
|
||||
}
|
||||
|
||||
// display current camera settings/parameters
|
||||
case 'c': case 'C':
|
||||
{
|
||||
vtkSmartPointer<vtkCamera> cam = Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->GetActiveCamera();
|
||||
|
||||
Vec2d clip(cam->GetClippingRange());
|
||||
Vec3d focal(cam->GetFocalPoint()), pos(cam->GetPosition()), view(cam->GetViewUp());
|
||||
Vec2i win_pos(Interactor->GetRenderWindow()->GetPosition());
|
||||
Vec2i win_size(Interactor->GetRenderWindow()->GetSize());
|
||||
double angle = cam->GetViewAngle () / 180.0 * CV_PI;
|
||||
|
||||
String data = cv::format("clip(%f,%f) focal(%f,%f,%f) pos(%f,%f,%f) view(%f,%f,%f) angle(%f) winsz(%d,%d) winpos(%d,%d)",
|
||||
clip[0], clip[1], focal[0], focal[1], focal[2], pos[0], pos[1], pos[2], view[0], view[1], view[2],
|
||||
angle, win_size[0], win_size[1], win_pos[0], win_pos[1]);
|
||||
|
||||
std::cout << data.c_str() << std::endl;
|
||||
|
||||
break;
|
||||
}
|
||||
case '=':
|
||||
{
|
||||
zoomIn();
|
||||
break;
|
||||
}
|
||||
case 43: // KEY_PLUS
|
||||
{
|
||||
if (alt)
|
||||
zoomIn();
|
||||
else
|
||||
{
|
||||
vtkSmartPointer<vtkActorCollection> ac = CurrentRenderer->GetActors();
|
||||
vtkCollectionSimpleIterator ait;
|
||||
for (ac->InitTraversal(ait); vtkActor* actor = ac->GetNextActor(ait); )
|
||||
for (actor->InitPathTraversal(); vtkAssemblyPath* path = actor->GetNextPath(); )
|
||||
{
|
||||
vtkActor* apart = vtkActor::SafeDownCast(path->GetLastNode()->GetViewProp());
|
||||
float psize = apart->GetProperty()->GetPointSize();
|
||||
if (psize < 63.0f)
|
||||
apart->GetProperty()->SetPointSize(psize + 1.0f);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 45: // KEY_MINUS
|
||||
{
|
||||
if (alt)
|
||||
zoomOut();
|
||||
else
|
||||
{
|
||||
vtkSmartPointer<vtkActorCollection> ac = CurrentRenderer->GetActors();
|
||||
vtkCollectionSimpleIterator ait;
|
||||
for (ac->InitTraversal(ait); vtkActor* actor = ac->GetNextActor(ait); )
|
||||
for (actor->InitPathTraversal(); vtkAssemblyPath* path = actor->GetNextPath(); )
|
||||
{
|
||||
vtkActor* apart = vtkActor::SafeDownCast(path->GetLastNode()->GetViewProp());
|
||||
float psize = apart->GetProperty()->GetPointSize();
|
||||
if (psize > 1.0f)
|
||||
apart->GetProperty()->SetPointSize(psize - 1.0f);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Switch between maximize and original window size
|
||||
case 'f': case 'F':
|
||||
{
|
||||
if (alt)
|
||||
{
|
||||
Vec2i screen_size(Interactor->GetRenderWindow()->GetScreenSize());
|
||||
Vec2i win_size(Interactor->GetRenderWindow()->GetSize());
|
||||
|
||||
// Is window size = max?
|
||||
if (win_size == max_win_size_)
|
||||
{
|
||||
Interactor->GetRenderWindow()->SetSize(win_size_.val);
|
||||
Interactor->GetRenderWindow()->SetPosition(win_pos_.val);
|
||||
Interactor->GetRenderWindow()->Render();
|
||||
Interactor->Render();
|
||||
}
|
||||
// Set to max
|
||||
else
|
||||
{
|
||||
win_pos_ = Vec2i(Interactor->GetRenderWindow()->GetPosition());
|
||||
win_size_ = win_size;
|
||||
|
||||
Interactor->GetRenderWindow()->SetSize(screen_size.val);
|
||||
Interactor->GetRenderWindow()->Render();
|
||||
Interactor->Render();
|
||||
max_win_size_ = Vec2i(Interactor->GetRenderWindow()->GetSize());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AnimState = VTKIS_ANIM_ON;
|
||||
Interactor->GetPicker()->Pick(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1], 0.0, CurrentRenderer);
|
||||
vtkSmartPointer<vtkAbstractPropPicker> picker = vtkAbstractPropPicker::SafeDownCast(Interactor->GetPicker());
|
||||
if (picker)
|
||||
if (picker->GetPath())
|
||||
Interactor->FlyTo(CurrentRenderer, picker->GetPickPosition());
|
||||
AnimState = VTKIS_ANIM_OFF;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// 's'/'S' w/out ALT
|
||||
case 's': case 'S':
|
||||
{
|
||||
if (alt)
|
||||
{
|
||||
vtkSmartPointer<vtkRenderWindow> window = Interactor->GetRenderWindow();
|
||||
if (!window->GetStereoRender())
|
||||
{
|
||||
static Vec2i red_blue(4, 3), magenta_green(2, 5);
|
||||
window->SetAnaglyphColorMask (stereo_anaglyph_mask_default_ ? red_blue.val : magenta_green.val);
|
||||
stereo_anaglyph_mask_default_ = !stereo_anaglyph_mask_default_;
|
||||
}
|
||||
window->SetStereoRender(!window->GetStereoRender());
|
||||
Interactor->Render();
|
||||
}
|
||||
else
|
||||
Superclass::OnKeyDown();
|
||||
break;
|
||||
}
|
||||
|
||||
case 'o': case 'O':
|
||||
{
|
||||
vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera();
|
||||
cam->SetParallelProjection(!cam->GetParallelProjection());
|
||||
CurrentRenderer->Render();
|
||||
break;
|
||||
}
|
||||
|
||||
// Overwrite the camera reset
|
||||
case 'r': case 'R':
|
||||
{
|
||||
if (!alt)
|
||||
{
|
||||
Superclass::OnKeyDown();
|
||||
break;
|
||||
}
|
||||
|
||||
WidgetActorMap::iterator it = widget_actor_map_->begin();
|
||||
// it might be that some actors don't have a valid transformation set -> we skip them to avoid a seg fault.
|
||||
for (; it != widget_actor_map_->end(); ++it)
|
||||
{
|
||||
vtkProp3D * actor = vtkProp3D::SafeDownCast(it->second);
|
||||
if (actor && actor->GetUserMatrix())
|
||||
break;
|
||||
}
|
||||
|
||||
vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera();
|
||||
|
||||
// if a valid transformation was found, use it otherwise fall back to default view point.
|
||||
if (it != widget_actor_map_->end())
|
||||
{
|
||||
vtkMatrix4x4* m = vtkProp3D::SafeDownCast(it->second)->GetUserMatrix();
|
||||
|
||||
cam->SetFocalPoint(m->GetElement(0, 3) - m->GetElement(0, 2),
|
||||
m->GetElement(1, 3) - m->GetElement(1, 2),
|
||||
m->GetElement(2, 3) - m->GetElement(2, 2));
|
||||
|
||||
cam->SetViewUp (m->GetElement(0, 1), m->GetElement(1, 1), m->GetElement(2, 1));
|
||||
cam->SetPosition(m->GetElement(0, 3), m->GetElement(1, 3), m->GetElement(2, 3));
|
||||
}
|
||||
else
|
||||
{
|
||||
cam->SetPosition(0, 0, 0);
|
||||
cam->SetFocalPoint(0, 0, 1);
|
||||
cam->SetViewUp(0, -1, 0);
|
||||
}
|
||||
|
||||
// go to the next actor for the next key-press event.
|
||||
if (it != widget_actor_map_->end())
|
||||
++it;
|
||||
else
|
||||
it = widget_actor_map_->begin();
|
||||
|
||||
CurrentRenderer->SetActiveCamera(cam);
|
||||
CurrentRenderer->ResetCameraClippingRange();
|
||||
CurrentRenderer->Render();
|
||||
break;
|
||||
}
|
||||
|
||||
case 'q': case 'Q':
|
||||
{
|
||||
Interactor->ExitCallback();
|
||||
return;
|
||||
}
|
||||
default:
|
||||
{
|
||||
Superclass::OnKeyDown();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
KeyboardEvent event(KeyboardEvent::KEY_DOWN, Interactor->GetKeySym(), Interactor->GetKeyCode(), getModifiers());
|
||||
if (keyboardCallback_)
|
||||
keyboardCallback_(event, keyboard_callback_cookie_);
|
||||
Interactor->Render();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::InteractorStyle::OnKeyUp()
|
||||
{
|
||||
KeyboardEvent event(KeyboardEvent::KEY_UP, Interactor->GetKeySym(), Interactor->GetKeyCode(), getModifiers());
|
||||
if (keyboardCallback_)
|
||||
keyboardCallback_(event, keyboard_callback_cookie_);
|
||||
Superclass::OnKeyUp();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::InteractorStyle::OnMouseMove()
|
||||
{
|
||||
Vec2i p(Interactor->GetEventPosition());
|
||||
MouseEvent event(MouseEvent::MouseMove, MouseEvent::NoButton, p, getModifiers());
|
||||
if (mouseCallback_)
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
Superclass::OnMouseMove();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::InteractorStyle::OnLeftButtonDown()
|
||||
{
|
||||
Vec2i p(Interactor->GetEventPosition());
|
||||
MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick;
|
||||
MouseEvent event(type, MouseEvent::LeftButton, p, getModifiers());
|
||||
if (mouseCallback_)
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
Superclass::OnLeftButtonDown();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::InteractorStyle::OnLeftButtonUp()
|
||||
{
|
||||
Vec2i p(Interactor->GetEventPosition());
|
||||
MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::LeftButton, p, getModifiers());
|
||||
if (mouseCallback_)
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
Superclass::OnLeftButtonUp();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::InteractorStyle::OnMiddleButtonDown()
|
||||
{
|
||||
Vec2i p(Interactor->GetEventPosition());
|
||||
MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick;
|
||||
MouseEvent event(type, MouseEvent::MiddleButton, p, getModifiers());
|
||||
if (mouseCallback_)
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
Superclass::OnMiddleButtonDown();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::InteractorStyle::OnMiddleButtonUp()
|
||||
{
|
||||
Vec2i p(Interactor->GetEventPosition());
|
||||
MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::MiddleButton, p, getModifiers());
|
||||
if (mouseCallback_)
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
Superclass::OnMiddleButtonUp();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::InteractorStyle::OnRightButtonDown()
|
||||
{
|
||||
Vec2i p(Interactor->GetEventPosition());
|
||||
MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick;
|
||||
MouseEvent event(type, MouseEvent::RightButton, p, getModifiers());
|
||||
if (mouseCallback_)
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
Superclass::OnRightButtonDown();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::InteractorStyle::OnRightButtonUp()
|
||||
{
|
||||
Vec2i p(Interactor->GetEventPosition());
|
||||
MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::RightButton, p, getModifiers());
|
||||
if (mouseCallback_)
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
Superclass::OnRightButtonUp();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::InteractorStyle::OnMouseWheelForward()
|
||||
{
|
||||
Vec2i p(Interactor->GetEventPosition());
|
||||
MouseEvent event(MouseEvent::MouseScrollUp, MouseEvent::VScroll, p, getModifiers());
|
||||
if (mouseCallback_)
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
if (Interactor->GetRepeatCount() && mouseCallback_)
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
|
||||
if (Interactor->GetAltKey())
|
||||
{
|
||||
// zoom
|
||||
vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera();
|
||||
double opening_angle = cam->GetViewAngle();
|
||||
if (opening_angle > 15.0)
|
||||
opening_angle -= 1.0;
|
||||
|
||||
cam->SetViewAngle(opening_angle);
|
||||
cam->Modified();
|
||||
CurrentRenderer->ResetCameraClippingRange();
|
||||
CurrentRenderer->Modified();
|
||||
CurrentRenderer->Render();
|
||||
Interactor->Render();
|
||||
}
|
||||
else
|
||||
Superclass::OnMouseWheelForward();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::InteractorStyle::OnMouseWheelBackward()
|
||||
{
|
||||
Vec2i p(Interactor->GetEventPosition());
|
||||
MouseEvent event(MouseEvent::MouseScrollDown, MouseEvent::VScroll, p, getModifiers());
|
||||
if (mouseCallback_)
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
|
||||
if (Interactor->GetRepeatCount() && mouseCallback_)
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
|
||||
if (Interactor->GetAltKey())
|
||||
{
|
||||
// zoom
|
||||
vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera();
|
||||
double opening_angle = cam->GetViewAngle();
|
||||
if (opening_angle < 170.0)
|
||||
opening_angle += 1.0;
|
||||
|
||||
cam->SetViewAngle(opening_angle);
|
||||
cam->Modified();
|
||||
CurrentRenderer->ResetCameraClippingRange();
|
||||
CurrentRenderer->Modified();
|
||||
CurrentRenderer->Render();
|
||||
Interactor->Render();
|
||||
}
|
||||
else
|
||||
Superclass::OnMouseWheelBackward();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::InteractorStyle::OnTimer()
|
||||
{
|
||||
CV_Assert("Interactor style not initialized." && init_);
|
||||
Interactor->Render();
|
||||
}
|
119
modules/viz/src/interactor_style.hpp
Normal file
119
modules/viz/src/interactor_style.hpp
Normal file
@@ -0,0 +1,119 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's 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.
|
||||
//
|
||||
// * The name of the copyright holders may not 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 Intel Corporation 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.
|
||||
//
|
||||
// Authors:
|
||||
// * Ozan Tonkal, ozantonkal@gmail.com
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __OPENCV_VIZ_INTERACTOR_STYLE_H__
|
||||
#define __OPENCV_VIZ_INTERACTOR_STYLE_H__
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace viz
|
||||
{
|
||||
class InteractorStyle : public vtkInteractorStyleTrackballCamera
|
||||
{
|
||||
public:
|
||||
static InteractorStyle *New();
|
||||
virtual ~InteractorStyle() {}
|
||||
|
||||
// this macro defines Superclass, the isA functionality and the safe downcast method
|
||||
vtkTypeMacro(InteractorStyle, vtkInteractorStyleTrackballCamera)
|
||||
|
||||
/** \brief Initialization routine. Must be called before anything else. */
|
||||
virtual void Initialize();
|
||||
|
||||
void setWidgetActorMap(const Ptr<WidgetActorMap>& actors) { widget_actor_map_ = actors; }
|
||||
void registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie = 0);
|
||||
void registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void * cookie = 0);
|
||||
void saveScreenshot(const String &file);
|
||||
void exportScene(const String &file);
|
||||
|
||||
private:
|
||||
/** \brief Set to true after initialization is complete. */
|
||||
bool init_;
|
||||
|
||||
Ptr<WidgetActorMap> widget_actor_map_;
|
||||
|
||||
Vec2i win_size_;
|
||||
Vec2i win_pos_;
|
||||
Vec2i max_win_size_;
|
||||
|
||||
/** \brief Interactor style internal method. Gets called whenever a key is pressed. */
|
||||
virtual void OnChar();
|
||||
|
||||
// Keyboard events
|
||||
virtual void OnKeyDown();
|
||||
virtual void OnKeyUp();
|
||||
|
||||
// mouse button events
|
||||
virtual void OnMouseMove();
|
||||
virtual void OnLeftButtonDown();
|
||||
virtual void OnLeftButtonUp();
|
||||
virtual void OnMiddleButtonDown();
|
||||
virtual void OnMiddleButtonUp();
|
||||
virtual void OnRightButtonDown();
|
||||
virtual void OnRightButtonUp();
|
||||
virtual void OnMouseWheelForward();
|
||||
virtual void OnMouseWheelBackward();
|
||||
|
||||
/** \brief Interactor style internal method. Gets called periodically if a timer is set. */
|
||||
virtual void OnTimer();
|
||||
|
||||
void zoomIn();
|
||||
void zoomOut();
|
||||
|
||||
/** \brief True if we're using red-blue colors for anaglyphic stereo, false if magenta-green. */
|
||||
bool stereo_anaglyph_mask_default_;
|
||||
|
||||
void (*keyboardCallback_)(const KeyboardEvent&, void*);
|
||||
void *keyboard_callback_cookie_;
|
||||
|
||||
void (*mouseCallback_)(const MouseEvent&, void*);
|
||||
void *mouse_callback_cookie_;
|
||||
|
||||
int getModifiers();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
324
modules/viz/src/precomp.hpp
Normal file
324
modules/viz/src/precomp.hpp
Normal file
@@ -0,0 +1,324 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's 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.
|
||||
//
|
||||
// * The name of the copyright holders may not 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 Intel Corporation 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.
|
||||
//
|
||||
// Authors:
|
||||
// * Ozan Tonkal, ozantonkal@gmail.com
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __OPENCV_VIZ_PRECOMP_HPP__
|
||||
#define __OPENCV_VIZ_PRECOMP_HPP__
|
||||
|
||||
#include <map>
|
||||
#include <ctime>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <iomanip>
|
||||
#include <limits>
|
||||
|
||||
#include <vtkAppendPolyData.h>
|
||||
#include <vtkAssemblyPath.h>
|
||||
#include <vtkCellData.h>
|
||||
#include <vtkLineSource.h>
|
||||
#include <vtkPropPicker.h>
|
||||
#include <vtkSmartPointer.h>
|
||||
#include <vtkDataSet.h>
|
||||
#include <vtkPolygon.h>
|
||||
#include <vtkUnstructuredGrid.h>
|
||||
#include <vtkDiskSource.h>
|
||||
#include <vtkPlaneSource.h>
|
||||
#include <vtkSphereSource.h>
|
||||
#include <vtkArrowSource.h>
|
||||
#include <vtkOutlineSource.h>
|
||||
#include <vtkTransform.h>
|
||||
#include <vtkTransformPolyDataFilter.h>
|
||||
#include <vtkTubeFilter.h>
|
||||
#include <vtkCubeSource.h>
|
||||
#include <vtkAxes.h>
|
||||
#include <vtkFloatArray.h>
|
||||
#include <vtkDoubleArray.h>
|
||||
#include <vtkPointData.h>
|
||||
#include <vtkPolyData.h>
|
||||
#include <vtkPolyDataReader.h>
|
||||
#include <vtkPolyDataMapper.h>
|
||||
#include <vtkDataSetMapper.h>
|
||||
#include <vtkCellArray.h>
|
||||
#include <vtkCommand.h>
|
||||
#include <vtkPLYReader.h>
|
||||
#include <vtkPolyLine.h>
|
||||
#include <vtkVectorText.h>
|
||||
#include <vtkFollower.h>
|
||||
#include <vtkInteractorStyle.h>
|
||||
#include <vtkUnsignedCharArray.h>
|
||||
#include <vtkRendererCollection.h>
|
||||
#include <vtkPNGWriter.h>
|
||||
#include <vtkWindowToImageFilter.h>
|
||||
#include <vtkInteractorStyleTrackballCamera.h>
|
||||
#include <vtkProperty.h>
|
||||
#include <vtkCamera.h>
|
||||
#include <vtkPlanes.h>
|
||||
#include <vtkImageFlip.h>
|
||||
#include <vtkRenderWindow.h>
|
||||
#include <vtkTextProperty.h>
|
||||
#include <vtkProperty2D.h>
|
||||
#include <vtkLODActor.h>
|
||||
#include <vtkActor.h>
|
||||
#include <vtkTextActor.h>
|
||||
#include <vtkRenderWindowInteractor.h>
|
||||
#include <vtkMath.h>
|
||||
#include <vtkExtractEdges.h>
|
||||
#include <vtkFrustumSource.h>
|
||||
#include <vtkTextureMapToPlane.h>
|
||||
#include <vtkPolyDataNormals.h>
|
||||
#include <vtkAlgorithmOutput.h>
|
||||
#include <vtkImageMapper.h>
|
||||
#include <vtkPoints.h>
|
||||
#include <vtkInformation.h>
|
||||
#include <vtkInformationVector.h>
|
||||
#include <vtkObjectFactory.h>
|
||||
#include <vtkPolyDataAlgorithm.h>
|
||||
#include <vtkMergeFilter.h>
|
||||
#include <vtkDataSetWriter.h>
|
||||
#include <vtkErrorCode.h>
|
||||
#include <vtkPLYWriter.h>
|
||||
#include <vtkSTLWriter.h>
|
||||
#include <vtkSimplePointsReader.h>
|
||||
#include <vtkPLYReader.h>
|
||||
#include <vtkOBJReader.h>
|
||||
#include <vtkSTLReader.h>
|
||||
#include <vtkPNGReader.h>
|
||||
#include <vtkOBJExporter.h>
|
||||
#include <vtkVRMLExporter.h>
|
||||
#include <vtkTensorGlyph.h>
|
||||
#include <vtkImageAlgorithm.h>
|
||||
#include <vtkTransformFilter.h>
|
||||
#include <vtkConeSource.h>
|
||||
#include <vtkElevationFilter.h>
|
||||
#include <vtkColorTransferFunction.h>
|
||||
#include <vtkStreamingDemandDrivenPipeline.h>
|
||||
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
# include <unistd.h> /* unlink */
|
||||
#else
|
||||
# include <io.h> /* unlink */
|
||||
#endif
|
||||
|
||||
#include <vtk/vtkOBJWriter.h>
|
||||
#include <vtk/vtkXYZWriter.h>
|
||||
#include <vtk/vtkCloudMatSink.h>
|
||||
#include <vtk/vtkCloudMatSource.h>
|
||||
#include <vtk/vtkTrajectorySource.h>
|
||||
#include <vtk/vtkImageMatSource.h>
|
||||
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/viz/vizcore.hpp>
|
||||
#include <opencv2/viz/widget_accessor.hpp>
|
||||
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace viz
|
||||
{
|
||||
typedef std::map<String, vtkSmartPointer<vtkProp> > WidgetActorMap;
|
||||
typedef std::map<String, Viz3d> VizMap;
|
||||
|
||||
class VizStorage
|
||||
{
|
||||
public:
|
||||
static void unregisterAll();
|
||||
|
||||
//! window names automatically have Viz - prefix even though not provided by the users
|
||||
static String generateWindowName(const String &window_name);
|
||||
|
||||
private:
|
||||
VizStorage(); // Static
|
||||
~VizStorage();
|
||||
|
||||
static void add(const Viz3d& window);
|
||||
static Viz3d& get(const String &window_name);
|
||||
static void remove(const String &window_name);
|
||||
static bool windowExists(const String &window_name);
|
||||
static void removeUnreferenced();
|
||||
|
||||
static VizMap storage;
|
||||
friend class Viz3d;
|
||||
};
|
||||
|
||||
template<typename _Tp> inline _Tp normalized(const _Tp& v) { return v * 1/norm(v); }
|
||||
|
||||
template<typename _Tp> inline bool isNan(const _Tp* data)
|
||||
{
|
||||
return isNan(data[0]) || isNan(data[1]) || isNan(data[2]);
|
||||
}
|
||||
|
||||
inline vtkSmartPointer<vtkActor> getActor(const Widget3D& widget)
|
||||
{
|
||||
return vtkActor::SafeDownCast(WidgetAccessor::getProp(widget));
|
||||
}
|
||||
|
||||
inline vtkSmartPointer<vtkPolyData> getPolyData(const Widget3D& widget)
|
||||
{
|
||||
vtkSmartPointer<vtkMapper> mapper = getActor(widget)->GetMapper();
|
||||
return vtkPolyData::SafeDownCast(mapper->GetInput());
|
||||
}
|
||||
|
||||
inline vtkSmartPointer<vtkMatrix4x4> vtkmatrix(const cv::Matx44d &matrix)
|
||||
{
|
||||
vtkSmartPointer<vtkMatrix4x4> vtk_matrix = vtkSmartPointer<vtkMatrix4x4>::New();
|
||||
vtk_matrix->DeepCopy(matrix.val);
|
||||
return vtk_matrix;
|
||||
}
|
||||
|
||||
inline Color vtkcolor(const Color& color)
|
||||
{
|
||||
Color scaled_color = color * (1.0/255.0);
|
||||
std::swap(scaled_color[0], scaled_color[2]);
|
||||
return scaled_color;
|
||||
}
|
||||
|
||||
inline Vec3d get_random_vec(double from = -10.0, double to = 10.0)
|
||||
{
|
||||
RNG& rng = theRNG();
|
||||
return Vec3d(rng.uniform(from, to), rng.uniform(from, to), rng.uniform(from, to));
|
||||
}
|
||||
|
||||
struct VtkUtils
|
||||
{
|
||||
template<class Filter>
|
||||
static void SetInputData(vtkSmartPointer<Filter> filter, vtkPolyData* polydata)
|
||||
{
|
||||
#if VTK_MAJOR_VERSION <= 5
|
||||
filter->SetInput(polydata);
|
||||
#else
|
||||
filter->SetInputData(polydata);
|
||||
#endif
|
||||
}
|
||||
template<class Filter>
|
||||
static void SetSourceData(vtkSmartPointer<Filter> filter, vtkPolyData* polydata)
|
||||
{
|
||||
#if VTK_MAJOR_VERSION <= 5
|
||||
filter->SetSource(polydata);
|
||||
#else
|
||||
filter->SetSourceData(polydata);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<class Filter>
|
||||
static void SetInputData(vtkSmartPointer<Filter> filter, vtkImageData* polydata)
|
||||
{
|
||||
#if VTK_MAJOR_VERSION <= 5
|
||||
filter->SetInput(polydata);
|
||||
#else
|
||||
filter->SetInputData(polydata);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<class Filter>
|
||||
static void AddInputData(vtkSmartPointer<Filter> filter, vtkPolyData *polydata)
|
||||
{
|
||||
#if VTK_MAJOR_VERSION <= 5
|
||||
filter->AddInput(polydata);
|
||||
#else
|
||||
filter->AddInputData(polydata);
|
||||
#endif
|
||||
}
|
||||
|
||||
static vtkSmartPointer<vtkUnsignedCharArray> FillScalars(size_t size, const Color& color)
|
||||
{
|
||||
Vec3b rgb = Vec3d(color[2], color[1], color[0]);
|
||||
Vec3b* color_data = new Vec3b[size];
|
||||
std::fill(color_data, color_data + size, rgb);
|
||||
|
||||
vtkSmartPointer<vtkUnsignedCharArray> scalars = vtkSmartPointer<vtkUnsignedCharArray>::New();
|
||||
scalars->SetName("Colors");
|
||||
scalars->SetNumberOfComponents(3);
|
||||
scalars->SetNumberOfTuples(size);
|
||||
scalars->SetArray(color_data->val, size * 3, 0);
|
||||
return scalars;
|
||||
}
|
||||
|
||||
static vtkSmartPointer<vtkPolyData> ComputeNormals(vtkSmartPointer<vtkPolyData> polydata)
|
||||
{
|
||||
vtkSmartPointer<vtkPolyDataNormals> normals_generator = vtkSmartPointer<vtkPolyDataNormals>::New();
|
||||
normals_generator->ComputePointNormalsOn();
|
||||
normals_generator->ComputeCellNormalsOff();
|
||||
normals_generator->SetFeatureAngle(0.1);
|
||||
normals_generator->SetSplitting(0);
|
||||
normals_generator->SetConsistency(1);
|
||||
normals_generator->SetAutoOrientNormals(0);
|
||||
normals_generator->SetFlipNormals(0);
|
||||
normals_generator->SetNonManifoldTraversal(1);
|
||||
VtkUtils::SetInputData(normals_generator, polydata);
|
||||
normals_generator->Update();
|
||||
return normals_generator->GetOutput();
|
||||
}
|
||||
|
||||
static vtkSmartPointer<vtkPolyData> TransformPolydata(vtkSmartPointer<vtkAlgorithmOutput> algorithm_output_port, const Affine3d& pose)
|
||||
{
|
||||
vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
|
||||
transform->SetMatrix(vtkmatrix(pose.matrix));
|
||||
|
||||
vtkSmartPointer<vtkTransformPolyDataFilter> transform_filter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
|
||||
transform_filter->SetTransform(transform);
|
||||
transform_filter->SetInputConnection(algorithm_output_port);
|
||||
transform_filter->Update();
|
||||
return transform_filter->GetOutput();
|
||||
}
|
||||
|
||||
static vtkSmartPointer<vtkPolyData> TransformPolydata(vtkSmartPointer<vtkPolyData> polydata, const Affine3d& pose)
|
||||
{
|
||||
vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
|
||||
transform->SetMatrix(vtkmatrix(pose.matrix));
|
||||
|
||||
vtkSmartPointer<vtkTransformPolyDataFilter> transform_filter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
|
||||
VtkUtils::SetInputData(transform_filter, polydata);
|
||||
transform_filter->SetTransform(transform);
|
||||
transform_filter->Update();
|
||||
return transform_filter->GetOutput();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#include "interactor_style.hpp"
|
||||
#include "vizimpl.hpp"
|
||||
|
||||
|
||||
#endif
|
1088
modules/viz/src/shapes.cpp
Normal file
1088
modules/viz/src/shapes.cpp
Normal file
File diff suppressed because it is too large
Load Diff
206
modules/viz/src/types.cpp
Normal file
206
modules/viz/src/types.cpp
Normal file
@@ -0,0 +1,206 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's 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.
|
||||
//
|
||||
// * The name of the copyright holders may not 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 Intel Corporation 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.
|
||||
//
|
||||
// Authors:
|
||||
// * Ozan Tonkal, ozantonkal@gmail.com
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/// Events
|
||||
|
||||
cv::viz::KeyboardEvent::KeyboardEvent(Action _action, const String& _symbol, unsigned char _code, int _modifiers)
|
||||
: action(_action), symbol(_symbol), code(_code), modifiers(_modifiers) {}
|
||||
|
||||
cv::viz::MouseEvent::MouseEvent(const Type& _type, const MouseButton& _button, const Point& _pointer, int _modifiers)
|
||||
: type(_type), button(_button), pointer(_pointer), modifiers(_modifiers) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/// cv::viz::Mesh3d
|
||||
|
||||
cv::viz::Mesh cv::viz::Mesh::load(const String& file)
|
||||
{
|
||||
vtkSmartPointer<vtkPLYReader> reader = vtkSmartPointer<vtkPLYReader>::New();
|
||||
reader->SetFileName(file.c_str());
|
||||
reader->Update();
|
||||
|
||||
vtkSmartPointer<vtkPolyData> polydata = reader->GetOutput();
|
||||
CV_Assert("File does not exist or file format is not supported." && polydata);
|
||||
|
||||
Mesh mesh;
|
||||
vtkSmartPointer<vtkCloudMatSink> sink = vtkSmartPointer<vtkCloudMatSink>::New();
|
||||
sink->SetOutput(mesh.cloud, mesh.colors, mesh.normals, mesh.tcoords);
|
||||
sink->SetInputConnection(reader->GetOutputPort());
|
||||
sink->Write();
|
||||
|
||||
// Now handle the polygons
|
||||
vtkSmartPointer<vtkCellArray> polygons = polydata->GetPolys();
|
||||
mesh.polygons.create(1, polygons->GetSize(), CV_32SC1);
|
||||
int* poly_ptr = mesh.polygons.ptr<int>();
|
||||
|
||||
polygons->InitTraversal();
|
||||
vtkIdType nr_cell_points, *cell_points;
|
||||
while (polygons->GetNextCell(nr_cell_points, cell_points))
|
||||
{
|
||||
*poly_ptr++ = nr_cell_points;
|
||||
for (vtkIdType i = 0; i < nr_cell_points; ++i)
|
||||
*poly_ptr++ = (int)cell_points[i];
|
||||
}
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/// Camera implementation
|
||||
|
||||
cv::viz::Camera::Camera(double fx, double fy, double cx, double cy, const Size &window_size)
|
||||
{
|
||||
init(fx, fy, cx, cy, window_size);
|
||||
}
|
||||
|
||||
cv::viz::Camera::Camera(const Vec2d &fov, const Size &window_size)
|
||||
{
|
||||
CV_Assert(window_size.width > 0 && window_size.height > 0);
|
||||
setClip(Vec2d(0.01, 1000.01)); // Default clipping
|
||||
setFov(fov);
|
||||
window_size_ = window_size;
|
||||
// Principal point at the center
|
||||
principal_point_ = Vec2f(static_cast<float>(window_size.width)*0.5f, static_cast<float>(window_size.height)*0.5f);
|
||||
focal_ = Vec2f(principal_point_[0] / tan(fov_[0]*0.5f), principal_point_[1] / tan(fov_[1]*0.5f));
|
||||
}
|
||||
|
||||
cv::viz::Camera::Camera(const cv::Matx33d & K, const Size &window_size)
|
||||
{
|
||||
double f_x = K(0,0);
|
||||
double f_y = K(1,1);
|
||||
double c_x = K(0,2);
|
||||
double c_y = K(1,2);
|
||||
init(f_x, f_y, c_x, c_y, window_size);
|
||||
}
|
||||
|
||||
cv::viz::Camera::Camera(const Matx44d &proj, const Size &window_size)
|
||||
{
|
||||
CV_Assert(window_size.width > 0 && window_size.height > 0);
|
||||
|
||||
double near = proj(2,3) / (proj(2,2) - 1.0);
|
||||
double far = near * (proj(2,2) - 1.0) / (proj(2,2) + 1.0);
|
||||
double left = near * (proj(0,2)-1) / proj(0,0);
|
||||
double right = 2.0 * near / proj(0,0) + left;
|
||||
double bottom = near * (proj(1,2)-1) / proj(1,1);
|
||||
double top = 2.0 * near / proj(1,1) + bottom;
|
||||
|
||||
double epsilon = 2.2204460492503131e-16;
|
||||
|
||||
principal_point_[0] = fabs(left-right) < epsilon ? window_size.width * 0.5 : (left * window_size.width) / (left - right);
|
||||
principal_point_[1] = fabs(top-bottom) < epsilon ? window_size.height * 0.5 : (top * window_size.height) / (top - bottom);
|
||||
|
||||
focal_[0] = -near * principal_point_[0] / left;
|
||||
focal_[1] = near * principal_point_[1] / top;
|
||||
|
||||
setClip(Vec2d(near, far));
|
||||
fov_[0] = atan2(principal_point_[0], focal_[0]) + atan2(window_size.width-principal_point_[0], focal_[0]);
|
||||
fov_[1] = atan2(principal_point_[1], focal_[1]) + atan2(window_size.height-principal_point_[1], focal_[1]);
|
||||
|
||||
window_size_ = window_size;
|
||||
}
|
||||
|
||||
void cv::viz::Camera::init(double fx, double fy, double cx, double cy, const Size &window_size)
|
||||
{
|
||||
CV_Assert(window_size.width > 0 && window_size.height > 0);
|
||||
setClip(Vec2d(0.01, 1000.01));// Default clipping
|
||||
|
||||
fov_[0] = atan2(cx, fx) + atan2(window_size.width - cx, fx);
|
||||
fov_[1] = atan2(cy, fy) + atan2(window_size.height - cy, fy);
|
||||
|
||||
principal_point_[0] = cx;
|
||||
principal_point_[1] = cy;
|
||||
|
||||
focal_[0] = fx;
|
||||
focal_[1] = fy;
|
||||
|
||||
window_size_ = window_size;
|
||||
}
|
||||
|
||||
void cv::viz::Camera::setWindowSize(const Size &window_size)
|
||||
{
|
||||
CV_Assert(window_size.width > 0 && window_size.height > 0);
|
||||
|
||||
// Get the scale factor and update the principal points
|
||||
float scalex = static_cast<float>(window_size.width) / static_cast<float>(window_size_.width);
|
||||
float scaley = static_cast<float>(window_size.height) / static_cast<float>(window_size_.height);
|
||||
|
||||
principal_point_[0] *= scalex;
|
||||
principal_point_[1] *= scaley;
|
||||
focal_ *= scaley;
|
||||
// Vertical field of view is fixed! Update horizontal field of view
|
||||
fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0]));
|
||||
|
||||
window_size_ = window_size;
|
||||
}
|
||||
|
||||
void cv::viz::Camera::computeProjectionMatrix(Matx44d &proj) const
|
||||
{
|
||||
double top = clip_[0] * principal_point_[1] / focal_[1];
|
||||
double left = -clip_[0] * principal_point_[0] / focal_[0];
|
||||
double right = clip_[0] * (window_size_.width - principal_point_[0]) / focal_[0];
|
||||
double bottom = -clip_[0] * (window_size_.height - principal_point_[1]) / focal_[1];
|
||||
|
||||
double temp1 = 2.0 * clip_[0];
|
||||
double temp2 = 1.0 / (right - left);
|
||||
double temp3 = 1.0 / (top - bottom);
|
||||
double temp4 = 1.0 / (clip_[0] - clip_[1]);
|
||||
|
||||
proj = Matx44d::zeros();
|
||||
proj(0,0) = temp1 * temp2;
|
||||
proj(1,1) = temp1 * temp3;
|
||||
proj(0,2) = (right + left) * temp2;
|
||||
proj(1,2) = (top + bottom) * temp3;
|
||||
proj(2,2) = (clip_[1]+clip_[0]) * temp4;
|
||||
proj(3,2) = -1.0;
|
||||
proj(2,3) = (temp1 * clip_[1]) * temp4;
|
||||
}
|
||||
|
||||
cv::viz::Camera cv::viz::Camera::KinectCamera(const Size &window_size)
|
||||
{
|
||||
Matx33d K(525.0, 0.0, 320.0, 0.0, 525.0, 240.0, 0.0, 0.0, 1.0);
|
||||
return Camera(K, window_size);
|
||||
}
|
148
modules/viz/src/viz3d.cpp
Normal file
148
modules/viz/src/viz3d.cpp
Normal file
@@ -0,0 +1,148 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's 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.
|
||||
//
|
||||
// * The name of the copyright holders may not 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 Intel Corporation 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.
|
||||
//
|
||||
// Authors:
|
||||
// * Ozan Tonkal, ozantonkal@gmail.com
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
cv::viz::Viz3d::Viz3d(const String& window_name) : impl_(0) { create(window_name); }
|
||||
|
||||
cv::viz::Viz3d::Viz3d(const Viz3d& other) : impl_(other.impl_)
|
||||
{
|
||||
if (impl_)
|
||||
CV_XADD(&impl_->ref_counter, 1);
|
||||
}
|
||||
|
||||
cv::viz::Viz3d& cv::viz::Viz3d::operator=(const Viz3d& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
release();
|
||||
impl_ = other.impl_;
|
||||
if (impl_)
|
||||
CV_XADD(&impl_->ref_counter, 1);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
cv::viz::Viz3d::~Viz3d() { release(); }
|
||||
|
||||
void cv::viz::Viz3d::create(const String &window_name)
|
||||
{
|
||||
if (impl_)
|
||||
release();
|
||||
|
||||
if (VizStorage::windowExists(window_name))
|
||||
*this = VizStorage::get(window_name);
|
||||
else
|
||||
{
|
||||
impl_ = new VizImpl(window_name);
|
||||
impl_->ref_counter = 1;
|
||||
|
||||
// Register the window
|
||||
VizStorage::add(*this);
|
||||
}
|
||||
}
|
||||
|
||||
void cv::viz::Viz3d::release()
|
||||
{
|
||||
if (impl_ && CV_XADD(&impl_->ref_counter, -1) == 1)
|
||||
{
|
||||
delete impl_;
|
||||
impl_ = 0;
|
||||
}
|
||||
|
||||
if (impl_ && impl_->ref_counter == 1)
|
||||
VizStorage::removeUnreferenced();
|
||||
|
||||
impl_ = 0;
|
||||
}
|
||||
|
||||
void cv::viz::Viz3d::spin() { impl_->spin(); }
|
||||
void cv::viz::Viz3d::spinOnce(int time, bool force_redraw) { impl_->spinOnce(time, force_redraw); }
|
||||
bool cv::viz::Viz3d::wasStopped() const { return impl_->wasStopped(); }
|
||||
void cv::viz::Viz3d::close() { impl_->close(); }
|
||||
|
||||
void cv::viz::Viz3d::registerKeyboardCallback(KeyboardCallback callback, void* cookie)
|
||||
{ impl_->registerKeyboardCallback(callback, cookie); }
|
||||
|
||||
void cv::viz::Viz3d::registerMouseCallback(MouseCallback callback, void* cookie)
|
||||
{ impl_->registerMouseCallback(callback, cookie); }
|
||||
|
||||
void cv::viz::Viz3d::showWidget(const String &id, const Widget &widget, const Affine3d &pose) { impl_->showWidget(id, widget, pose); }
|
||||
void cv::viz::Viz3d::removeWidget(const String &id) { impl_->removeWidget(id); }
|
||||
cv::viz::Widget cv::viz::Viz3d::getWidget(const String &id) const { return impl_->getWidget(id); }
|
||||
void cv::viz::Viz3d::removeAllWidgets() { impl_->removeAllWidgets(); }
|
||||
|
||||
void cv::viz::Viz3d::showImage(InputArray image, const Size& window_size) { impl_->showImage(image, window_size); }
|
||||
|
||||
void cv::viz::Viz3d::setWidgetPose(const String &id, const Affine3d &pose) { impl_->setWidgetPose(id, pose); }
|
||||
void cv::viz::Viz3d::updateWidgetPose(const String &id, const Affine3d &pose) { impl_->updateWidgetPose(id, pose); }
|
||||
cv::Affine3d cv::viz::Viz3d::getWidgetPose(const String &id) const { return impl_->getWidgetPose(id); }
|
||||
|
||||
void cv::viz::Viz3d::setCamera(const Camera &camera) { impl_->setCamera(camera); }
|
||||
cv::viz::Camera cv::viz::Viz3d::getCamera() const { return impl_->getCamera(); }
|
||||
void cv::viz::Viz3d::setViewerPose(const Affine3d &pose) { impl_->setViewerPose(pose); }
|
||||
cv::Affine3d cv::viz::Viz3d::getViewerPose() { return impl_->getViewerPose(); }
|
||||
|
||||
void cv::viz::Viz3d::resetCameraViewpoint(const String &id) { impl_->resetCameraViewpoint(id); }
|
||||
void cv::viz::Viz3d::resetCamera() { impl_->resetCamera(); }
|
||||
|
||||
void cv::viz::Viz3d::convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord) { impl_->convertToWindowCoordinates(pt, window_coord); }
|
||||
void cv::viz::Viz3d::converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction) { impl_->converTo3DRay(window_coord, origin, direction); }
|
||||
|
||||
cv::Size cv::viz::Viz3d::getWindowSize() const { return impl_->getWindowSize(); }
|
||||
void cv::viz::Viz3d::setWindowSize(const Size &window_size) { impl_->setWindowSize(window_size); }
|
||||
cv::String cv::viz::Viz3d::getWindowName() const { return impl_->getWindowName(); }
|
||||
void cv::viz::Viz3d::saveScreenshot(const String &file) { impl_->saveScreenshot(file); }
|
||||
void cv::viz::Viz3d::setWindowPosition(const Point& window_position) { impl_->setWindowPosition(window_position); }
|
||||
void cv::viz::Viz3d::setFullScreen(bool mode) { impl_->setFullScreen(mode); }
|
||||
void cv::viz::Viz3d::setBackgroundColor(const Color& color, const Color& color2) { impl_->setBackgroundColor(color, color2); }
|
||||
|
||||
void cv::viz::Viz3d::setBackgroundTexture(InputArray image) { impl_->setBackgroundTexture(image); }
|
||||
void cv::viz::Viz3d::setBackgroundMeshLab() {impl_->setBackgroundMeshLab(); }
|
||||
|
||||
void cv::viz::Viz3d::setRenderingProperty(const String &id, int property, double value) { getWidget(id).setRenderingProperty(property, value); }
|
||||
double cv::viz::Viz3d::getRenderingProperty(const String &id, int property) { return getWidget(id).getRenderingProperty(property); }
|
||||
|
||||
void cv::viz::Viz3d::setRepresentation(int representation) { impl_->setRepresentation(representation); }
|
312
modules/viz/src/vizcore.cpp
Normal file
312
modules/viz/src/vizcore.cpp
Normal file
@@ -0,0 +1,312 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's 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.
|
||||
//
|
||||
// * The name of the copyright holders may not 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 Intel Corporation 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.
|
||||
//
|
||||
// Authors:
|
||||
// * Ozan Tonkal, ozantonkal@gmail.com
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
cv::Affine3d cv::viz::makeTransformToGlobal(const Vec3d& axis_x, const Vec3d& axis_y, const Vec3d& axis_z, const Vec3d& origin)
|
||||
{
|
||||
Affine3d::Mat3 R(axis_x[0], axis_y[0], axis_z[0],
|
||||
axis_x[1], axis_y[1], axis_z[1],
|
||||
axis_x[2], axis_y[2], axis_z[2]);
|
||||
|
||||
return Affine3d(R, origin);
|
||||
}
|
||||
|
||||
cv::Affine3d cv::viz::makeCameraPose(const Vec3d& position, const Vec3d& focal_point, const Vec3d& y_dir)
|
||||
{
|
||||
// Compute the transformation matrix for drawing the camera frame in a scene
|
||||
Vec3d n = normalize(focal_point - position);
|
||||
Vec3d u = normalize(y_dir.cross(n));
|
||||
Vec3d v = n.cross(u);
|
||||
|
||||
return makeTransformToGlobal(u, v, n, position);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// VizStorage implementation
|
||||
|
||||
cv::viz::VizMap cv::viz::VizStorage::storage;
|
||||
void cv::viz::VizStorage::unregisterAll() { storage.clear(); }
|
||||
|
||||
cv::viz::Viz3d& cv::viz::VizStorage::get(const String &window_name)
|
||||
{
|
||||
String name = generateWindowName(window_name);
|
||||
VizMap::iterator vm_itr = storage.find(name);
|
||||
CV_Assert(vm_itr != storage.end());
|
||||
return vm_itr->second;
|
||||
}
|
||||
|
||||
void cv::viz::VizStorage::add(const Viz3d& window)
|
||||
{
|
||||
String window_name = window.getWindowName();
|
||||
VizMap::iterator vm_itr = storage.find(window_name);
|
||||
CV_Assert(vm_itr == storage.end());
|
||||
storage.insert(std::make_pair(window_name, window));
|
||||
}
|
||||
|
||||
bool cv::viz::VizStorage::windowExists(const String &window_name)
|
||||
{
|
||||
String name = generateWindowName(window_name);
|
||||
return storage.find(name) != storage.end();
|
||||
}
|
||||
|
||||
void cv::viz::VizStorage::removeUnreferenced()
|
||||
{
|
||||
for(VizMap::iterator pos = storage.begin(); pos != storage.end();)
|
||||
if(pos->second.impl_->ref_counter == 1)
|
||||
storage.erase(pos++);
|
||||
else
|
||||
++pos;
|
||||
}
|
||||
|
||||
cv::String cv::viz::VizStorage::generateWindowName(const String &window_name)
|
||||
{
|
||||
String output = "Viz";
|
||||
// Already is Viz
|
||||
if (window_name == output)
|
||||
return output;
|
||||
|
||||
String prefixed = output + " - ";
|
||||
if (window_name.substr(0, prefixed.length()) == prefixed)
|
||||
output = window_name; // Already has "Viz - "
|
||||
else if (window_name.substr(0, output.length()) == output)
|
||||
output = prefixed + window_name; // Doesn't have prefix
|
||||
else
|
||||
output = (window_name == "" ? output : prefixed + window_name);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
cv::viz::Viz3d cv::viz::getWindowByName(const String &window_name) { return Viz3d (window_name); }
|
||||
void cv::viz::unregisterAllWindows() { VizStorage::unregisterAll(); }
|
||||
|
||||
cv::viz::Viz3d cv::viz::imshow(const String& window_name, InputArray image, const Size& window_size)
|
||||
{
|
||||
Viz3d viz = getWindowByName(window_name);
|
||||
viz.showImage(image, window_size);
|
||||
return viz;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Read/write clouds. Supported formats: ply, stl, xyz, obj
|
||||
|
||||
void cv::viz::writeCloud(const String& file, InputArray cloud, InputArray colors, InputArray normals, bool binary)
|
||||
{
|
||||
CV_Assert(file.size() > 4 && "Extention is required");
|
||||
String extention = file.substr(file.size()-4);
|
||||
|
||||
vtkSmartPointer<vtkCloudMatSource> source = vtkSmartPointer<vtkCloudMatSource>::New();
|
||||
source->SetColorCloudNormals(cloud, colors, normals);
|
||||
|
||||
vtkSmartPointer<vtkWriter> writer;
|
||||
if (extention == ".xyz")
|
||||
{
|
||||
writer = vtkSmartPointer<vtkXYZWriter>::New();
|
||||
vtkXYZWriter::SafeDownCast(writer)->SetFileName(file.c_str());
|
||||
}
|
||||
else if (extention == ".ply")
|
||||
{
|
||||
writer = vtkSmartPointer<vtkPLYWriter>::New();
|
||||
vtkPLYWriter::SafeDownCast(writer)->SetFileName(file.c_str());
|
||||
vtkPLYWriter::SafeDownCast(writer)->SetFileType(binary ? VTK_BINARY : VTK_ASCII);
|
||||
vtkPLYWriter::SafeDownCast(writer)->SetArrayName("Colors");
|
||||
}
|
||||
else if (extention == ".obj")
|
||||
{
|
||||
writer = vtkSmartPointer<vtkOBJWriter>::New();
|
||||
vtkOBJWriter::SafeDownCast(writer)->SetFileName(file.c_str());
|
||||
}
|
||||
else
|
||||
CV_Assert(!"Unsupported format");
|
||||
|
||||
writer->SetInputConnection(source->GetOutputPort());
|
||||
writer->Write();
|
||||
}
|
||||
|
||||
cv::Mat cv::viz::readCloud(const String& file, OutputArray colors, OutputArray normals)
|
||||
{
|
||||
CV_Assert(file.size() > 4 && "Extention is required");
|
||||
String extention = file.substr(file.size()-4);
|
||||
|
||||
vtkSmartPointer<vtkPolyDataAlgorithm> reader;
|
||||
if (extention == ".xyz")
|
||||
{
|
||||
reader = vtkSmartPointer<vtkSimplePointsReader>::New();
|
||||
vtkSimplePointsReader::SafeDownCast(reader)->SetFileName(file.c_str());
|
||||
}
|
||||
else if (extention == ".ply")
|
||||
{
|
||||
reader = vtkSmartPointer<vtkPLYReader>::New();
|
||||
CV_Assert(vtkPLYReader::CanReadFile(file.c_str()));
|
||||
vtkPLYReader::SafeDownCast(reader)->SetFileName(file.c_str());
|
||||
}
|
||||
else if (extention == ".obj")
|
||||
{
|
||||
reader = vtkSmartPointer<vtkOBJReader>::New();
|
||||
vtkOBJReader::SafeDownCast(reader)->SetFileName(file.c_str());
|
||||
}
|
||||
else if (extention == ".stl")
|
||||
{
|
||||
reader = vtkSmartPointer<vtkSTLReader>::New();
|
||||
vtkSTLReader::SafeDownCast(reader)->SetFileName(file.c_str());
|
||||
}
|
||||
else
|
||||
CV_Assert(!"Unsupported format");
|
||||
|
||||
cv::Mat cloud;
|
||||
|
||||
vtkSmartPointer<vtkCloudMatSink> sink = vtkSmartPointer<vtkCloudMatSink>::New();
|
||||
sink->SetInputConnection(reader->GetOutputPort());
|
||||
sink->SetOutput(cloud, colors, normals);
|
||||
sink->Write();
|
||||
|
||||
return cloud;
|
||||
}
|
||||
|
||||
cv::viz::Mesh cv::viz::readMesh(const String& file) { return Mesh::load(file); }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Read/write poses and trajectories
|
||||
|
||||
bool cv::viz::readPose(const String& file, Affine3d& pose, const String& tag)
|
||||
{
|
||||
FileStorage fs(file, FileStorage::READ);
|
||||
if (!fs.isOpened())
|
||||
return false;
|
||||
|
||||
Mat hdr(pose.matrix, false);
|
||||
fs[tag] >> hdr;
|
||||
if (hdr.empty() || hdr.cols != pose.matrix.cols || hdr.rows != pose.matrix.rows)
|
||||
return false;
|
||||
|
||||
hdr.convertTo(pose.matrix, CV_64F);
|
||||
return true;
|
||||
}
|
||||
|
||||
void cv::viz::writePose(const String& file, const Affine3d& pose, const String& tag)
|
||||
{
|
||||
FileStorage fs(file, FileStorage::WRITE);
|
||||
fs << tag << Mat(pose.matrix, false);
|
||||
}
|
||||
|
||||
void cv::viz::readTrajectory(OutputArray _traj, const String& files_format, int start, int end, const String& tag)
|
||||
{
|
||||
CV_Assert(_traj.kind() == _InputArray::STD_VECTOR || _traj.kind() == _InputArray::MAT);
|
||||
|
||||
start = max(0, std::min(start, end));
|
||||
end = std::max(start, end);
|
||||
|
||||
std::vector<Affine3d> traj;
|
||||
|
||||
for(int i = start; i < end; ++i)
|
||||
{
|
||||
Affine3d affine;
|
||||
bool ok = readPose(cv::format(files_format.c_str(), i), affine, tag);
|
||||
if (!ok)
|
||||
break;
|
||||
|
||||
traj.push_back(affine);
|
||||
}
|
||||
|
||||
Mat(traj).convertTo(_traj, _traj.depth());
|
||||
}
|
||||
|
||||
void cv::viz::writeTrajectory(InputArray _traj, const String& files_format, int start, const String& tag)
|
||||
{
|
||||
if (_traj.kind() == _InputArray::STD_VECTOR_MAT)
|
||||
{
|
||||
std::vector<Mat>& v = *(std::vector<Mat>*)_traj.obj;
|
||||
|
||||
for(size_t i = 0, index = max(0, start); i < v.size(); ++i, ++index)
|
||||
{
|
||||
Affine3d affine;
|
||||
Mat pose = v[i];
|
||||
CV_Assert(pose.type() == CV_32FC(16) || pose.type() == CV_64FC(16));
|
||||
pose.copyTo(affine.matrix);
|
||||
writePose(cv::format(files_format.c_str(), index), affine, tag);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (_traj.kind() == _InputArray::STD_VECTOR || _traj.kind() == _InputArray::MAT)
|
||||
{
|
||||
CV_Assert(_traj.type() == CV_32FC(16) || _traj.type() == CV_64FC(16));
|
||||
|
||||
Mat traj = _traj.getMat();
|
||||
|
||||
if (traj.depth() == CV_32F)
|
||||
for(size_t i = 0, index = max(0, start); i < traj.total(); ++i, ++index)
|
||||
writePose(cv::format(files_format.c_str(), index), traj.at<Affine3f>(i), tag);
|
||||
|
||||
if (traj.depth() == CV_64F)
|
||||
for(size_t i = 0, index = max(0, start); i < traj.total(); ++i, ++index)
|
||||
writePose(cv::format(files_format.c_str(), index), traj.at<Affine3d>(i), tag);
|
||||
}
|
||||
|
||||
CV_Assert(!"Unsupported array kind");
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Computing normals for mesh
|
||||
|
||||
void cv::viz::computeNormals(const Mesh& mesh, OutputArray _normals)
|
||||
{
|
||||
vtkSmartPointer<vtkPolyData> polydata = getPolyData(WMesh(mesh));
|
||||
vtkSmartPointer<vtkPolyData> with_normals = VtkUtils::ComputeNormals(polydata);
|
||||
|
||||
vtkSmartPointer<vtkDataArray> generic_normals = with_normals->GetPointData()->GetNormals();
|
||||
if(generic_normals)
|
||||
{
|
||||
Mat normals(1, generic_normals->GetNumberOfTuples(), CV_64FC3);
|
||||
Vec3d *optr = normals.ptr<Vec3d>();
|
||||
|
||||
for(int i = 0; i < generic_normals->GetNumberOfTuples(); ++i, ++optr)
|
||||
generic_normals->GetTuple(i, optr->val);
|
||||
|
||||
normals.convertTo(_normals, mesh.cloud.type());
|
||||
}
|
||||
else
|
||||
_normals.release();
|
||||
}
|
542
modules/viz/src/vizimpl.cpp
Normal file
542
modules/viz/src/vizimpl.cpp
Normal file
@@ -0,0 +1,542 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's 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.
|
||||
//
|
||||
// * The name of the copyright holders may not 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 Intel Corporation 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.
|
||||
//
|
||||
// Authors:
|
||||
// * Ozan Tonkal, ozantonkal@gmail.com
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
cv::viz::Viz3d::VizImpl::VizImpl(const String &name) : spin_once_state_(false),
|
||||
window_position_(Vec2i(std::numeric_limits<int>::min())), widget_actor_map_(new WidgetActorMap)
|
||||
{
|
||||
renderer_ = vtkSmartPointer<vtkRenderer>::New();
|
||||
window_name_ = VizStorage::generateWindowName(name);
|
||||
|
||||
// Create render window
|
||||
window_ = vtkSmartPointer<vtkRenderWindow>::New();
|
||||
cv::Vec2i window_size = cv::Vec2i(window_->GetScreenSize()) / 2;
|
||||
window_->SetSize(window_size.val);
|
||||
window_->AddRenderer(renderer_);
|
||||
|
||||
// Create the interactor style
|
||||
style_ = vtkSmartPointer<InteractorStyle>::New();
|
||||
style_->setWidgetActorMap(widget_actor_map_);
|
||||
style_->UseTimersOn();
|
||||
style_->Initialize();
|
||||
|
||||
timer_callback_ = vtkSmartPointer<TimerCallback>::New();
|
||||
exit_callback_ = vtkSmartPointer<ExitCallback>::New();
|
||||
exit_callback_->viz = this;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::TimerCallback::Execute(vtkObject* caller, unsigned long event_id, void* cookie)
|
||||
{
|
||||
if (event_id == vtkCommand::TimerEvent && timer_id == *reinterpret_cast<int*>(cookie))
|
||||
{
|
||||
vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkRenderWindowInteractor::SafeDownCast(caller);
|
||||
interactor->TerminateApp();
|
||||
}
|
||||
}
|
||||
|
||||
void cv::viz::Viz3d::VizImpl::ExitCallback::Execute(vtkObject*, unsigned long event_id, void*)
|
||||
{
|
||||
if (event_id == vtkCommand::ExitEvent)
|
||||
{
|
||||
viz->interactor_->TerminateApp();
|
||||
viz->interactor_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool cv::viz::Viz3d::VizImpl::wasStopped() const
|
||||
{
|
||||
bool stopped = spin_once_state_ ? interactor_ == 0 : false;
|
||||
spin_once_state_ &= !stopped;
|
||||
return stopped;
|
||||
}
|
||||
|
||||
void cv::viz::Viz3d::VizImpl::close()
|
||||
{
|
||||
if (!interactor_)
|
||||
return;
|
||||
interactor_->GetRenderWindow()->Finalize();
|
||||
interactor_->TerminateApp(); // This tends to close the window...
|
||||
interactor_ = 0;
|
||||
}
|
||||
|
||||
void cv::viz::Viz3d::VizImpl::recreateRenderWindow()
|
||||
{
|
||||
#if !defined _MSC_VER
|
||||
//recreating is workaround for Ubuntu -- a crash in x-server
|
||||
Vec2i window_size(window_->GetSize());
|
||||
int fullscreen = window_->GetFullScreen();
|
||||
|
||||
window_ = vtkSmartPointer<vtkRenderWindow>::New();
|
||||
if (window_position_[0] != std::numeric_limits<int>::min()) //also workaround
|
||||
window_->SetPosition(window_position_.val);
|
||||
|
||||
window_->SetSize(window_size.val);
|
||||
window_->SetFullScreen(fullscreen);
|
||||
window_->AddRenderer(renderer_);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::spin()
|
||||
{
|
||||
recreateRenderWindow();
|
||||
interactor_ = vtkSmartPointer<vtkRenderWindowInteractor>::New();
|
||||
interactor_->SetRenderWindow(window_);
|
||||
interactor_->SetInteractorStyle(style_);
|
||||
window_->AlphaBitPlanesOff();
|
||||
window_->PointSmoothingOff();
|
||||
window_->LineSmoothingOff();
|
||||
window_->PolygonSmoothingOff();
|
||||
window_->SwapBuffersOn();
|
||||
window_->SetStereoTypeToAnaglyph();
|
||||
window_->Render();
|
||||
window_->SetWindowName(window_name_.c_str());
|
||||
interactor_->Start();
|
||||
interactor_ = 0;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::spinOnce(int time, bool force_redraw)
|
||||
{
|
||||
if (interactor_ == 0)
|
||||
{
|
||||
spin_once_state_ = true;
|
||||
recreateRenderWindow();
|
||||
interactor_ = vtkSmartPointer<vtkRenderWindowInteractor>::New();
|
||||
interactor_->SetRenderWindow(window_);
|
||||
interactor_->SetInteractorStyle(style_);
|
||||
interactor_->AddObserver(vtkCommand::TimerEvent, timer_callback_);
|
||||
interactor_->AddObserver(vtkCommand::ExitEvent, exit_callback_);
|
||||
window_->AlphaBitPlanesOff();
|
||||
window_->PointSmoothingOff();
|
||||
window_->LineSmoothingOff();
|
||||
window_->PolygonSmoothingOff();
|
||||
window_->SwapBuffersOn();
|
||||
window_->SetStereoTypeToAnaglyph();
|
||||
window_->Render();
|
||||
window_->SetWindowName(window_name_.c_str());
|
||||
}
|
||||
|
||||
vtkSmartPointer<vtkRenderWindowInteractor> local = interactor_;
|
||||
|
||||
if (force_redraw)
|
||||
local->Render();
|
||||
|
||||
timer_callback_->timer_id = local->CreateRepeatingTimer(std::max(1, time));
|
||||
local->Start();
|
||||
local->DestroyTimer(timer_callback_->timer_id);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget, const Affine3d &pose)
|
||||
{
|
||||
WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id);
|
||||
bool exists = wam_itr != widget_actor_map_->end();
|
||||
if (exists)
|
||||
{
|
||||
// Remove it if it exists and add it again
|
||||
removeActorFromRenderer(wam_itr->second);
|
||||
}
|
||||
// Get the actor and set the user matrix
|
||||
vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(widget));
|
||||
if (actor)
|
||||
{
|
||||
// If the actor is 3D, apply pose
|
||||
vtkSmartPointer<vtkMatrix4x4> matrix = vtkmatrix(pose.matrix);
|
||||
actor->SetUserMatrix(matrix);
|
||||
actor->Modified();
|
||||
}
|
||||
// If the actor is a vtkFollower, then it should always face the camera
|
||||
vtkFollower *follower = vtkFollower::SafeDownCast(actor);
|
||||
if (follower)
|
||||
{
|
||||
follower->SetCamera(renderer_->GetActiveCamera());
|
||||
}
|
||||
|
||||
renderer_->AddActor(WidgetAccessor::getProp(widget));
|
||||
(*widget_actor_map_)[id] = WidgetAccessor::getProp(widget);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::removeWidget(const String &id)
|
||||
{
|
||||
WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id);
|
||||
bool exists = wam_itr != widget_actor_map_->end();
|
||||
CV_Assert("Widget does not exist." && exists);
|
||||
CV_Assert("Widget could not be removed." && removeActorFromRenderer(wam_itr->second));
|
||||
widget_actor_map_->erase(wam_itr);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
cv::viz::Widget cv::viz::Viz3d::VizImpl::getWidget(const String &id) const
|
||||
{
|
||||
WidgetActorMap::const_iterator wam_itr = widget_actor_map_->find(id);
|
||||
bool exists = wam_itr != widget_actor_map_->end();
|
||||
CV_Assert("Widget does not exist." && exists);
|
||||
|
||||
Widget widget;
|
||||
WidgetAccessor::setProp(widget, wam_itr->second);
|
||||
return widget;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::setWidgetPose(const String &id, const Affine3d &pose)
|
||||
{
|
||||
WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id);
|
||||
bool exists = wam_itr != widget_actor_map_->end();
|
||||
CV_Assert("Widget does not exist." && exists);
|
||||
|
||||
vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second);
|
||||
CV_Assert("Widget is not 3D." && actor);
|
||||
|
||||
vtkSmartPointer<vtkMatrix4x4> matrix = vtkmatrix(pose.matrix);
|
||||
actor->SetUserMatrix(matrix);
|
||||
actor->Modified();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::updateWidgetPose(const String &id, const Affine3d &pose)
|
||||
{
|
||||
WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id);
|
||||
bool exists = wam_itr != widget_actor_map_->end();
|
||||
CV_Assert("Widget does not exist." && exists);
|
||||
|
||||
vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second);
|
||||
CV_Assert("Widget is not 3D." && actor);
|
||||
|
||||
vtkSmartPointer<vtkMatrix4x4> matrix = actor->GetUserMatrix();
|
||||
if (!matrix)
|
||||
{
|
||||
setWidgetPose(id, pose);
|
||||
return ;
|
||||
}
|
||||
Affine3d updated_pose = pose * Affine3d(*matrix->Element);
|
||||
matrix = vtkmatrix(updated_pose.matrix);
|
||||
|
||||
actor->SetUserMatrix(matrix);
|
||||
actor->Modified();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
cv::Affine3d cv::viz::Viz3d::VizImpl::getWidgetPose(const String &id) const
|
||||
{
|
||||
WidgetActorMap::const_iterator wam_itr = widget_actor_map_->find(id);
|
||||
bool exists = wam_itr != widget_actor_map_->end();
|
||||
CV_Assert("Widget does not exist." && exists);
|
||||
|
||||
vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second);
|
||||
CV_Assert("Widget is not 3D." && actor);
|
||||
|
||||
return Affine3d(*actor->GetUserMatrix()->Element);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::saveScreenshot(const String &file) { style_->saveScreenshot(file.c_str()); }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::registerMouseCallback(MouseCallback callback, void* cookie)
|
||||
{ style_->registerMouseCallback(callback, cookie); }
|
||||
|
||||
void cv::viz::Viz3d::VizImpl::registerKeyboardCallback(KeyboardCallback callback, void* cookie)
|
||||
{ style_->registerKeyboardCallback(callback, cookie); }
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::removeAllWidgets()
|
||||
{
|
||||
widget_actor_map_->clear();
|
||||
renderer_->RemoveAllViewProps();
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::showImage(InputArray image, const Size& window_size)
|
||||
{
|
||||
removeAllWidgets();
|
||||
if (window_size.width > 0 && window_size.height > 0)
|
||||
setWindowSize(window_size);
|
||||
|
||||
showWidget("showImage", WImageOverlay(image, Rect(Point(0,0), getWindowSize())));
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool cv::viz::Viz3d::VizImpl::removeActorFromRenderer(vtkSmartPointer<vtkProp> actor)
|
||||
{
|
||||
vtkPropCollection* actors = renderer_->GetViewProps();
|
||||
actors->InitTraversal();
|
||||
vtkProp* current_actor = NULL;
|
||||
while ((current_actor = actors->GetNextProp()) != NULL)
|
||||
if (current_actor == actor)
|
||||
{
|
||||
renderer_->RemoveActor(actor);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::setBackgroundColor(const Color& color, const Color& color2)
|
||||
{
|
||||
Color c = vtkcolor(color), c2 = vtkcolor(color2);
|
||||
bool gradient = color2[0] >= 0 && color2[1] >= 0 && color2[2] >= 0;
|
||||
|
||||
if (gradient)
|
||||
{
|
||||
renderer_->SetBackground(c2.val);
|
||||
renderer_->SetBackground2(c.val);
|
||||
renderer_->GradientBackgroundOn();
|
||||
}
|
||||
else
|
||||
{
|
||||
renderer_->SetBackground(c.val);
|
||||
renderer_->GradientBackgroundOff();
|
||||
}
|
||||
}
|
||||
|
||||
void cv::viz::Viz3d::VizImpl::setBackgroundMeshLab()
|
||||
{ setBackgroundColor(Color(2, 1, 1), Color(240, 120, 120)); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::setBackgroundTexture(InputArray image)
|
||||
{
|
||||
if (image.empty())
|
||||
{
|
||||
renderer_->SetBackgroundTexture(0);
|
||||
renderer_->TexturedBackgroundOff();
|
||||
return;
|
||||
}
|
||||
|
||||
vtkSmartPointer<vtkImageMatSource> source = vtkSmartPointer<vtkImageMatSource>::New();
|
||||
source->SetImage(image);
|
||||
|
||||
vtkSmartPointer<vtkImageFlip> image_flip = vtkSmartPointer<vtkImageFlip>::New();
|
||||
image_flip->SetFilteredAxis(1); // Vertical flip
|
||||
image_flip->SetInputConnection(source->GetOutputPort());
|
||||
|
||||
vtkSmartPointer<vtkTexture> texture = vtkSmartPointer<vtkTexture>::New();
|
||||
texture->SetInputConnection(image_flip->GetOutputPort());
|
||||
//texture->Update();
|
||||
|
||||
renderer_->SetBackgroundTexture(texture);
|
||||
renderer_->TexturedBackgroundOn();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::setCamera(const Camera &camera)
|
||||
{
|
||||
vtkSmartPointer<vtkCamera> active_camera = renderer_->GetActiveCamera();
|
||||
|
||||
// Set the intrinsic parameters of the camera
|
||||
window_->SetSize(camera.getWindowSize().width, camera.getWindowSize().height);
|
||||
double aspect_ratio = static_cast<double>(camera.getWindowSize().width)/static_cast<double>(camera.getWindowSize().height);
|
||||
|
||||
Matx44d proj_mat;
|
||||
camera.computeProjectionMatrix(proj_mat);
|
||||
|
||||
// Use the intrinsic parameters of the camera to simulate more realistically
|
||||
vtkSmartPointer<vtkMatrix4x4> vtk_matrix = active_camera->GetProjectionTransformMatrix(aspect_ratio, -1.0, 1.0);
|
||||
Matx44d old_proj_mat(*vtk_matrix->Element);
|
||||
|
||||
// This is a hack around not being able to set Projection Matrix
|
||||
vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
|
||||
transform->SetMatrix(vtkmatrix(proj_mat * old_proj_mat.inv()));
|
||||
active_camera->SetUserTransform(transform);
|
||||
|
||||
renderer_->ResetCameraClippingRange();
|
||||
renderer_->Render();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
cv::viz::Camera cv::viz::Viz3d::VizImpl::getCamera() const
|
||||
{
|
||||
vtkSmartPointer<vtkCamera> active_camera = renderer_->GetActiveCamera();
|
||||
|
||||
Size window_size(renderer_->GetRenderWindow()->GetSize()[0],
|
||||
renderer_->GetRenderWindow()->GetSize()[1]);
|
||||
double aspect_ratio = window_size.width / (double)window_size.height;
|
||||
|
||||
vtkSmartPointer<vtkMatrix4x4> proj_matrix = active_camera->GetProjectionTransformMatrix(aspect_ratio, -1.0f, 1.0f);
|
||||
return Camera(Matx44d(*proj_matrix->Element), window_size);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::setViewerPose(const Affine3d &pose)
|
||||
{
|
||||
vtkCamera& camera = *renderer_->GetActiveCamera();
|
||||
|
||||
// Position = extrinsic translation
|
||||
cv::Vec3d pos_vec = pose.translation();
|
||||
|
||||
// Rotate the view vector
|
||||
cv::Matx33d rotation = pose.rotation();
|
||||
cv::Vec3d y_axis(0.0, 1.0, 0.0);
|
||||
cv::Vec3d up_vec(rotation * y_axis);
|
||||
|
||||
// Compute the new focal point
|
||||
cv::Vec3d z_axis(0.0, 0.0, 1.0);
|
||||
cv::Vec3d focal_vec = pos_vec + rotation * z_axis;
|
||||
|
||||
camera.SetPosition(pos_vec.val);
|
||||
camera.SetFocalPoint(focal_vec.val);
|
||||
camera.SetViewUp(up_vec.val);
|
||||
|
||||
renderer_->ResetCameraClippingRange();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
cv::Affine3d cv::viz::Viz3d::VizImpl::getViewerPose()
|
||||
{
|
||||
vtkCamera& camera = *renderer_->GetActiveCamera();
|
||||
|
||||
Vec3d pos(camera.GetPosition());
|
||||
Vec3d view_up(camera.GetViewUp());
|
||||
Vec3d focal(camera.GetFocalPoint());
|
||||
|
||||
Vec3d y_axis = normalized(view_up);
|
||||
Vec3d z_axis = normalized(focal - pos);
|
||||
Vec3d x_axis = normalized(y_axis.cross(z_axis));
|
||||
|
||||
return makeTransformToGlobal(x_axis, y_axis, z_axis, pos);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord)
|
||||
{
|
||||
Vec3d window_pt;
|
||||
vtkInteractorObserver::ComputeWorldToDisplay(renderer_, pt.x, pt.y, pt.z, window_pt.val);
|
||||
window_coord = window_pt;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction)
|
||||
{
|
||||
Vec4d world_pt;
|
||||
vtkInteractorObserver::ComputeDisplayToWorld(renderer_, window_coord.x, window_coord.y, window_coord.z, world_pt.val);
|
||||
Vec3d cam_pos(renderer_->GetActiveCamera()->GetPosition());
|
||||
origin = cam_pos;
|
||||
direction = normalize(Vec3d(world_pt.val) - cam_pos);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::resetCameraViewpoint(const String &id)
|
||||
{
|
||||
vtkSmartPointer<vtkMatrix4x4> camera_pose;
|
||||
static WidgetActorMap::iterator it = widget_actor_map_->find(id);
|
||||
if (it != widget_actor_map_->end())
|
||||
{
|
||||
vtkProp3D *actor = vtkProp3D::SafeDownCast(it->second);
|
||||
CV_Assert("Widget is not 3D." && actor);
|
||||
camera_pose = actor->GetUserMatrix();
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
// Prevent a segfault
|
||||
if (!camera_pose) return;
|
||||
|
||||
vtkSmartPointer<vtkCamera> cam = renderer_->GetActiveCamera();
|
||||
cam->SetPosition(camera_pose->GetElement(0, 3),
|
||||
camera_pose->GetElement(1, 3),
|
||||
camera_pose->GetElement(2, 3));
|
||||
|
||||
cam->SetFocalPoint(camera_pose->GetElement(0, 3) - camera_pose->GetElement(0, 2),
|
||||
camera_pose->GetElement(1, 3) - camera_pose->GetElement(1, 2),
|
||||
camera_pose->GetElement(2, 3) - camera_pose->GetElement(2, 2));
|
||||
|
||||
cam->SetViewUp(camera_pose->GetElement(0, 1),
|
||||
camera_pose->GetElement(1, 1),
|
||||
camera_pose->GetElement(2, 1));
|
||||
|
||||
renderer_->SetActiveCamera(cam);
|
||||
renderer_->ResetCameraClippingRange();
|
||||
renderer_->Render();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::resetCamera()
|
||||
{
|
||||
renderer_->ResetCamera();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::setRepresentation(int representation)
|
||||
{
|
||||
vtkActorCollection * actors = renderer_->GetActors();
|
||||
actors->InitTraversal();
|
||||
vtkActor * actor;
|
||||
switch (representation)
|
||||
{
|
||||
case REPRESENTATION_POINTS:
|
||||
{
|
||||
while ((actor = actors->GetNextActor()) != NULL)
|
||||
actor->GetProperty()->SetRepresentationToPoints();
|
||||
break;
|
||||
}
|
||||
case REPRESENTATION_SURFACE:
|
||||
{
|
||||
while ((actor = actors->GetNextActor()) != NULL)
|
||||
actor->GetProperty()->SetRepresentationToSurface();
|
||||
break;
|
||||
}
|
||||
case REPRESENTATION_WIREFRAME:
|
||||
{
|
||||
while ((actor = actors->GetNextActor()) != NULL)
|
||||
actor->GetProperty()->SetRepresentationToWireframe();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
cv::String cv::viz::Viz3d::VizImpl::getWindowName() const { return window_name_; }
|
||||
void cv::viz::Viz3d::VizImpl::setFullScreen(bool mode) { window_->SetFullScreen(mode); }
|
||||
void cv::viz::Viz3d::VizImpl::setWindowPosition(const Point& position) { window_position_ = position; window_->SetPosition(position.x, position.y); }
|
||||
void cv::viz::Viz3d::VizImpl::setWindowSize(const Size& window_size) { window_->SetSize(window_size.width, window_size.height); }
|
||||
cv::Size cv::viz::Viz3d::VizImpl::getWindowSize() const { return Size(Point(Vec2i(window_->GetSize()))); }
|
138
modules/viz/src/vizimpl.hpp
Normal file
138
modules/viz/src/vizimpl.hpp
Normal file
@@ -0,0 +1,138 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's 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.
|
||||
//
|
||||
// * The name of the copyright holders may not 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 Intel Corporation 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.
|
||||
//
|
||||
// Authors:
|
||||
// * Ozan Tonkal, ozantonkal@gmail.com
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __OPENCV_VIZ_VIZ3D_IMPL_HPP__
|
||||
#define __OPENCV_VIZ_VIZ3D_IMPL_HPP__
|
||||
|
||||
struct cv::viz::Viz3d::VizImpl
|
||||
{
|
||||
public:
|
||||
typedef Viz3d::KeyboardCallback KeyboardCallback;
|
||||
typedef Viz3d::MouseCallback MouseCallback;
|
||||
|
||||
int ref_counter;
|
||||
|
||||
VizImpl(const String &name);
|
||||
virtual ~VizImpl() {}
|
||||
|
||||
bool wasStopped() const;
|
||||
void close();
|
||||
|
||||
void spin();
|
||||
void spinOnce(int time = 1, bool force_redraw = false);
|
||||
|
||||
void showWidget(const String &id, const Widget &widget, const Affine3d &pose = Affine3d::Identity());
|
||||
void removeWidget(const String &id);
|
||||
Widget getWidget(const String &id) const;
|
||||
void removeAllWidgets();
|
||||
|
||||
void showImage(InputArray image, const Size& window_size);
|
||||
|
||||
void setWidgetPose(const String &id, const Affine3d &pose);
|
||||
void updateWidgetPose(const String &id, const Affine3d &pose);
|
||||
Affine3d getWidgetPose(const String &id) const;
|
||||
|
||||
void setRepresentation(int representation);
|
||||
|
||||
void setCamera(const Camera &camera);
|
||||
Camera getCamera() const;
|
||||
|
||||
/** \brief Reset the camera to a given widget */
|
||||
void resetCameraViewpoint(const String& id);
|
||||
void resetCamera();
|
||||
|
||||
void setViewerPose(const Affine3d &pose);
|
||||
Affine3d getViewerPose();
|
||||
|
||||
void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord);
|
||||
void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction);
|
||||
|
||||
void saveScreenshot(const String &file);
|
||||
void setWindowPosition(const Point& position);
|
||||
Size getWindowSize() const;
|
||||
void setWindowSize(const Size& window_size);
|
||||
void setFullScreen(bool mode);
|
||||
String getWindowName() const;
|
||||
void setBackgroundColor(const Color& color, const Color& color2);
|
||||
void setBackgroundTexture(InputArray image);
|
||||
void setBackgroundMeshLab();
|
||||
|
||||
void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0);
|
||||
void registerMouseCallback(MouseCallback callback, void* cookie = 0);
|
||||
|
||||
private:
|
||||
struct TimerCallback : public vtkCommand
|
||||
{
|
||||
static TimerCallback* New() { return new TimerCallback; }
|
||||
virtual void Execute(vtkObject* caller, unsigned long event_id, void* cookie);
|
||||
int timer_id;
|
||||
};
|
||||
|
||||
struct ExitCallback : public vtkCommand
|
||||
{
|
||||
static ExitCallback* New() { return new ExitCallback; }
|
||||
virtual void Execute(vtkObject*, unsigned long event_id, void*);
|
||||
VizImpl* viz;
|
||||
};
|
||||
|
||||
mutable bool spin_once_state_;
|
||||
vtkSmartPointer<vtkRenderWindowInteractor> interactor_;
|
||||
|
||||
vtkSmartPointer<vtkRenderWindow> window_;
|
||||
String window_name_;
|
||||
Vec2i window_position_;
|
||||
|
||||
vtkSmartPointer<TimerCallback> timer_callback_;
|
||||
vtkSmartPointer<ExitCallback> exit_callback_;
|
||||
|
||||
vtkSmartPointer<vtkRenderer> renderer_;
|
||||
vtkSmartPointer<InteractorStyle> style_;
|
||||
Ptr<WidgetActorMap> widget_actor_map_;
|
||||
|
||||
bool removeActorFromRenderer(vtkSmartPointer<vtkProp> actor);
|
||||
void recreateRenderWindow();
|
||||
};
|
||||
|
||||
#endif
|
158
modules/viz/src/vtk/vtkCloudMatSink.cpp
Normal file
158
modules/viz/src/vtk/vtkCloudMatSink.cpp
Normal file
@@ -0,0 +1,158 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's 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.
|
||||
//
|
||||
// * The name of the copyright holders may not 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 Intel Corporation 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.
|
||||
//
|
||||
// Authors:
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
namespace cv { namespace viz
|
||||
{
|
||||
vtkStandardNewMacro(vtkCloudMatSink);
|
||||
}}
|
||||
|
||||
cv::viz::vtkCloudMatSink::vtkCloudMatSink() {}
|
||||
cv::viz::vtkCloudMatSink::~vtkCloudMatSink() {}
|
||||
|
||||
void cv::viz::vtkCloudMatSink::SetOutput(OutputArray _cloud, OutputArray _colors, OutputArray _normals, OutputArray _tcoords)
|
||||
{
|
||||
cloud = _cloud;
|
||||
colors = _colors;
|
||||
normals = _normals;
|
||||
tcoords = _tcoords;
|
||||
}
|
||||
|
||||
void cv::viz::vtkCloudMatSink::WriteData()
|
||||
{
|
||||
vtkPolyData *input = this->GetInput();
|
||||
if (!input)
|
||||
return;
|
||||
|
||||
vtkSmartPointer<vtkPoints> points_Data = input->GetPoints();
|
||||
|
||||
if (cloud.needed() && points_Data)
|
||||
{
|
||||
int vtktype = points_Data->GetDataType();
|
||||
CV_Assert(vtktype == VTK_FLOAT || vtktype == VTK_DOUBLE);
|
||||
|
||||
cloud.create(1, points_Data->GetNumberOfPoints(), vtktype == VTK_FLOAT ? CV_32FC3 : CV_64FC3);
|
||||
Vec3d *ddata = cloud.getMat().ptr<Vec3d>();
|
||||
Vec3f *fdata = cloud.getMat().ptr<Vec3f>();
|
||||
|
||||
if (cloud.depth() == CV_32F)
|
||||
for(size_t i = 0; i < cloud.total(); ++i)
|
||||
*fdata++ = Vec3d(points_Data->GetPoint(i));
|
||||
|
||||
if (cloud.depth() == CV_64F)
|
||||
for(size_t i = 0; i < cloud.total(); ++i)
|
||||
*ddata++ = Vec3d(points_Data->GetPoint(i));
|
||||
}
|
||||
else
|
||||
cloud.release();
|
||||
|
||||
vtkSmartPointer<vtkDataArray> scalars_data = input->GetPointData() ? input->GetPointData()->GetScalars() : 0;
|
||||
|
||||
if (colors.needed() && scalars_data)
|
||||
{
|
||||
int channels = scalars_data->GetNumberOfComponents();
|
||||
int vtktype = scalars_data->GetDataType();
|
||||
|
||||
CV_Assert((channels == 3 || channels == 4) && "Only 3- or 4-channel color data support is implemented");
|
||||
CV_Assert(cloud.total() == (size_t)scalars_data->GetNumberOfTuples());
|
||||
|
||||
Mat buffer(cloud.size(), CV_64FC(channels));
|
||||
Vec3d *cptr = buffer.ptr<Vec3d>();
|
||||
for(size_t i = 0; i < buffer.total(); ++i)
|
||||
*cptr++ = Vec3d(scalars_data->GetTuple(i));
|
||||
|
||||
buffer.convertTo(colors, CV_8U, vtktype == VTK_FLOAT || VTK_FLOAT == VTK_DOUBLE ? 255.0 : 1.0);
|
||||
}
|
||||
else
|
||||
colors.release();
|
||||
|
||||
vtkSmartPointer<vtkDataArray> normals_data = input->GetPointData() ? input->GetPointData()->GetNormals() : 0;
|
||||
|
||||
if (normals.needed() && normals_data)
|
||||
{
|
||||
int channels = normals_data->GetNumberOfComponents();
|
||||
int vtktype = normals_data->GetDataType();
|
||||
|
||||
CV_Assert((vtktype == VTK_FLOAT || VTK_FLOAT == VTK_DOUBLE) && (channels == 3 || channels == 4));
|
||||
CV_Assert(cloud.total() == (size_t)normals_data->GetNumberOfTuples());
|
||||
|
||||
Mat buffer(cloud.size(), CV_64FC(channels));
|
||||
Vec3d *cptr = buffer.ptr<Vec3d>();
|
||||
for(size_t i = 0; i < buffer.total(); ++i)
|
||||
*cptr++ = Vec3d(normals_data->GetTuple(i));
|
||||
|
||||
buffer.convertTo(normals, vtktype == VTK_FLOAT ? CV_32F : CV_64F);
|
||||
}
|
||||
else
|
||||
normals.release();
|
||||
|
||||
vtkSmartPointer<vtkDataArray> coords_data = input->GetPointData() ? input->GetPointData()->GetTCoords() : 0;
|
||||
|
||||
if (tcoords.needed() && coords_data)
|
||||
{
|
||||
int vtktype = coords_data->GetDataType();
|
||||
|
||||
CV_Assert(vtktype == VTK_FLOAT || VTK_FLOAT == VTK_DOUBLE);
|
||||
CV_Assert(cloud.total() == (size_t)coords_data->GetNumberOfTuples());
|
||||
|
||||
Mat buffer(cloud.size(), CV_64FC2);
|
||||
Vec2d *cptr = buffer.ptr<Vec2d>();
|
||||
for(size_t i = 0; i < buffer.total(); ++i)
|
||||
*cptr++ = Vec2d(coords_data->GetTuple(i));
|
||||
|
||||
buffer.convertTo(tcoords, vtktype == VTK_FLOAT ? CV_32F : CV_64F);
|
||||
|
||||
}
|
||||
else
|
||||
tcoords.release();
|
||||
}
|
||||
|
||||
void cv::viz::vtkCloudMatSink::PrintSelf(ostream& os, vtkIndent indent)
|
||||
{
|
||||
Superclass::PrintSelf(os, indent);
|
||||
os << indent << "Cloud: " << cloud.needed() << "\n";
|
||||
os << indent << "Colors: " << colors.needed() << "\n";
|
||||
os << indent << "Normals: " << normals.needed() << "\n";
|
||||
}
|
79
modules/viz/src/vtk/vtkCloudMatSink.h
Normal file
79
modules/viz/src/vtk/vtkCloudMatSink.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's 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.
|
||||
//
|
||||
// * The name of the copyright holders may not 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 Intel Corporation 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.
|
||||
//
|
||||
// Authors:
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __vtkCloudMatSink_h
|
||||
#define __vtkCloudMatSink_h
|
||||
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <vtkPolyDataWriter.h>
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace viz
|
||||
{
|
||||
class vtkCloudMatSink : public vtkPolyDataWriter
|
||||
{
|
||||
public:
|
||||
static vtkCloudMatSink *New();
|
||||
vtkTypeMacro(vtkCloudMatSink,vtkPolyDataWriter)
|
||||
void PrintSelf(ostream& os, vtkIndent indent);
|
||||
|
||||
void SetOutput(OutputArray cloud, OutputArray colors = noArray(), OutputArray normals = noArray(), OutputArray tcoords = noArray());
|
||||
|
||||
protected:
|
||||
vtkCloudMatSink();
|
||||
~vtkCloudMatSink();
|
||||
|
||||
void WriteData();
|
||||
|
||||
_OutputArray cloud, colors, normals, tcoords;
|
||||
|
||||
private:
|
||||
vtkCloudMatSink(const vtkCloudMatSink&); // Not implemented.
|
||||
void operator=(const vtkCloudMatSink&); // Not implemented.
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
286
modules/viz/src/vtk/vtkCloudMatSource.cpp
Normal file
286
modules/viz/src/vtk/vtkCloudMatSource.cpp
Normal file
@@ -0,0 +1,286 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's 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.
|
||||
//
|
||||
// * The name of the copyright holders may not 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 Intel Corporation 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.
|
||||
//
|
||||
// Authors:
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
namespace cv { namespace viz
|
||||
{
|
||||
vtkStandardNewMacro(vtkCloudMatSource);
|
||||
|
||||
template<typename _Tp> struct VtkDepthTraits;
|
||||
|
||||
template<> struct VtkDepthTraits<float>
|
||||
{
|
||||
const static int data_type = VTK_FLOAT;
|
||||
typedef vtkFloatArray array_type;
|
||||
};
|
||||
|
||||
template<> struct VtkDepthTraits<double>
|
||||
{
|
||||
const static int data_type = VTK_DOUBLE;
|
||||
typedef vtkDoubleArray array_type;
|
||||
};
|
||||
}}
|
||||
|
||||
cv::viz::vtkCloudMatSource::vtkCloudMatSource() { SetNumberOfInputPorts(0); }
|
||||
cv::viz::vtkCloudMatSource::~vtkCloudMatSource() {}
|
||||
|
||||
int cv::viz::vtkCloudMatSource::SetCloud(InputArray _cloud)
|
||||
{
|
||||
CV_Assert(_cloud.depth() == CV_32F || _cloud.depth() == CV_64F);
|
||||
CV_Assert(_cloud.channels() == 3 || _cloud.channels() == 4);
|
||||
|
||||
Mat cloud = _cloud.getMat();
|
||||
|
||||
int total = _cloud.depth() == CV_32F ? filterNanCopy<float>(cloud) : filterNanCopy<double>(cloud);
|
||||
|
||||
vertices = vtkSmartPointer<vtkCellArray>::New();
|
||||
vertices->Allocate(vertices->EstimateSize(1, total));
|
||||
vertices->InsertNextCell(total);
|
||||
for(int i = 0; i < total; ++i)
|
||||
vertices->InsertCellPoint(i);
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
int cv::viz::vtkCloudMatSource::SetColorCloud(InputArray _cloud, InputArray _colors)
|
||||
{
|
||||
int total = SetCloud(_cloud);
|
||||
|
||||
if (_colors.empty())
|
||||
return total;
|
||||
|
||||
CV_Assert(_colors.depth() == CV_8U && _colors.channels() <= 4 && _colors.channels() != 2);
|
||||
CV_Assert(_colors.size() == _cloud.size());
|
||||
|
||||
Mat cloud = _cloud.getMat();
|
||||
Mat colors = _colors.getMat();
|
||||
|
||||
if (cloud.depth() == CV_32F)
|
||||
filterNanColorsCopy<float>(colors, cloud, total);
|
||||
else if (cloud.depth() == CV_64F)
|
||||
filterNanColorsCopy<double>(colors, cloud, total);
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
int cv::viz::vtkCloudMatSource::SetColorCloudNormals(InputArray _cloud, InputArray _colors, InputArray _normals)
|
||||
{
|
||||
int total = SetColorCloud(_cloud, _colors);
|
||||
|
||||
if (_normals.empty())
|
||||
return total;
|
||||
|
||||
CV_Assert(_normals.depth() == CV_32F || _normals.depth() == CV_64F);
|
||||
CV_Assert(_normals.channels() == 3 || _normals.channels() == 4);
|
||||
CV_Assert(_normals.size() == _cloud.size());
|
||||
|
||||
Mat c = _cloud.getMat();
|
||||
Mat n = _normals.getMat();
|
||||
|
||||
if (n.depth() == CV_32F && c.depth() == CV_32F)
|
||||
filterNanNormalsCopy<float, float>(n, c, total);
|
||||
else if (n.depth() == CV_32F && c.depth() == CV_64F)
|
||||
filterNanNormalsCopy<float, double>(n, c, total);
|
||||
else if (n.depth() == CV_64F && c.depth() == CV_32F)
|
||||
filterNanNormalsCopy<double, float>(n, c, total);
|
||||
else if (n.depth() == CV_64F && c.depth() == CV_64F)
|
||||
filterNanNormalsCopy<double, double>(n, c, total);
|
||||
else
|
||||
CV_Assert(!"Unsupported normals/cloud type");
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
int cv::viz::vtkCloudMatSource::SetColorCloudNormalsTCoords(InputArray _cloud, InputArray _colors, InputArray _normals, InputArray _tcoords)
|
||||
{
|
||||
int total = SetColorCloudNormals(_cloud, _colors, _normals);
|
||||
|
||||
if (_tcoords.empty())
|
||||
return total;
|
||||
|
||||
CV_Assert(_tcoords.depth() == CV_32F || _tcoords.depth() == CV_64F);
|
||||
CV_Assert(_tcoords.channels() == 2 && _tcoords.size() == _cloud.size());
|
||||
|
||||
Mat cl = _cloud.getMat();
|
||||
Mat tc = _tcoords.getMat();
|
||||
|
||||
if (tc.depth() == CV_32F && cl.depth() == CV_32F)
|
||||
filterNanTCoordsCopy<float, float>(tc, cl, total);
|
||||
else if (tc.depth() == CV_32F && cl.depth() == CV_64F)
|
||||
filterNanTCoordsCopy<float, double>(tc, cl, total);
|
||||
else if (tc.depth() == CV_64F && cl.depth() == CV_32F)
|
||||
filterNanTCoordsCopy<double, float>(tc, cl, total);
|
||||
else if (tc.depth() == CV_64F && cl.depth() == CV_64F)
|
||||
filterNanTCoordsCopy<double, double>(tc, cl, total);
|
||||
else
|
||||
CV_Assert(!"Unsupported tcoords/cloud type");
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
int cv::viz::vtkCloudMatSource::RequestData(vtkInformation *vtkNotUsed(request), vtkInformationVector **vtkNotUsed(inputVector), vtkInformationVector *outputVector)
|
||||
{
|
||||
vtkInformation *outInfo = outputVector->GetInformationObject(0);
|
||||
vtkPolyData *output = vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
|
||||
|
||||
output->SetPoints(points);
|
||||
output->SetVerts(vertices);
|
||||
if (scalars)
|
||||
output->GetPointData()->SetScalars(scalars);
|
||||
|
||||
if (normals)
|
||||
output->GetPointData()->SetNormals(normals);
|
||||
|
||||
if (tcoords)
|
||||
output->GetPointData()->SetTCoords(tcoords);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
template<typename _Tp>
|
||||
int cv::viz::vtkCloudMatSource::filterNanCopy(const Mat& cloud)
|
||||
{
|
||||
CV_DbgAssert(DataType<_Tp>::depth == cloud.depth());
|
||||
points = vtkSmartPointer<vtkPoints>::New();
|
||||
points->SetDataType(VtkDepthTraits<_Tp>::data_type);
|
||||
points->Allocate(cloud.total());
|
||||
points->SetNumberOfPoints(cloud.total());
|
||||
|
||||
int s_chs = cloud.channels();
|
||||
int total = 0;
|
||||
for (int y = 0; y < cloud.rows; ++y)
|
||||
{
|
||||
const _Tp* srow = cloud.ptr<_Tp>(y);
|
||||
const _Tp* send = srow + cloud.cols * s_chs;
|
||||
|
||||
for (; srow != send; srow += s_chs)
|
||||
if (!isNan(srow))
|
||||
points->SetPoint(total++, srow);
|
||||
}
|
||||
points->SetNumberOfPoints(total);
|
||||
points->Squeeze();
|
||||
return total;
|
||||
}
|
||||
|
||||
template<typename _Msk>
|
||||
void cv::viz::vtkCloudMatSource::filterNanColorsCopy(const Mat& cloud_colors, const Mat& mask, int total)
|
||||
{
|
||||
Vec3b* array = new Vec3b[total];
|
||||
Vec3b* pos = array;
|
||||
|
||||
int s_chs = cloud_colors.channels();
|
||||
int m_chs = mask.channels();
|
||||
for (int y = 0; y < cloud_colors.rows; ++y)
|
||||
{
|
||||
const unsigned char* srow = cloud_colors.ptr<unsigned char>(y);
|
||||
const unsigned char* send = srow + cloud_colors.cols * s_chs;
|
||||
const _Msk* mrow = mask.ptr<_Msk>(y);
|
||||
|
||||
if (cloud_colors.channels() == 1)
|
||||
{
|
||||
for (; srow != send; srow += s_chs, mrow += m_chs)
|
||||
if (!isNan(mrow))
|
||||
*pos++ = Vec3b(srow[0], srow[0], srow[0]);
|
||||
}
|
||||
else
|
||||
for (; srow != send; srow += s_chs, mrow += m_chs)
|
||||
if (!isNan(mrow))
|
||||
*pos++ = Vec3b(srow[2], srow[1], srow[0]);
|
||||
|
||||
}
|
||||
|
||||
scalars = vtkSmartPointer<vtkUnsignedCharArray>::New();
|
||||
scalars->SetName("Colors");
|
||||
scalars->SetNumberOfComponents(3);
|
||||
scalars->SetNumberOfTuples(total);
|
||||
scalars->SetArray(array->val, total * 3, 0);
|
||||
}
|
||||
|
||||
template<typename _Tn, typename _Msk>
|
||||
void cv::viz::vtkCloudMatSource::filterNanNormalsCopy(const Mat& cloud_normals, const Mat& mask, int total)
|
||||
{
|
||||
normals = vtkSmartPointer< typename VtkDepthTraits<_Tn>::array_type >::New();
|
||||
normals->SetName("Normals");
|
||||
normals->SetNumberOfComponents(3);
|
||||
normals->SetNumberOfTuples(total);
|
||||
|
||||
int s_chs = cloud_normals.channels();
|
||||
int m_chs = mask.channels();
|
||||
|
||||
int pos = 0;
|
||||
for (int y = 0; y < cloud_normals.rows; ++y)
|
||||
{
|
||||
const _Tn* srow = cloud_normals.ptr<_Tn>(y);
|
||||
const _Tn* send = srow + cloud_normals.cols * s_chs;
|
||||
|
||||
const _Msk* mrow = mask.ptr<_Msk>(y);
|
||||
|
||||
for (; srow != send; srow += s_chs, mrow += m_chs)
|
||||
if (!isNan(mrow))
|
||||
normals->SetTuple(pos++, srow);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename _Tn, typename _Msk>
|
||||
void cv::viz::vtkCloudMatSource::filterNanTCoordsCopy(const Mat& _tcoords, const Mat& mask, int total)
|
||||
{
|
||||
typedef Vec<_Tn, 2> Vec2;
|
||||
tcoords = vtkSmartPointer< typename VtkDepthTraits<_Tn>::array_type >::New();
|
||||
tcoords->SetName("TextureCoordinates");
|
||||
tcoords->SetNumberOfComponents(2);
|
||||
tcoords->SetNumberOfTuples(total);
|
||||
|
||||
int pos = 0;
|
||||
for (int y = 0; y < mask.rows; ++y)
|
||||
{
|
||||
const Vec2* srow = _tcoords.ptr<Vec2>(y);
|
||||
const Vec2* send = srow + _tcoords.cols;
|
||||
const _Msk* mrow = mask.ptr<_Msk>(y);
|
||||
|
||||
for (; srow != send; ++srow, mrow += mask.channels())
|
||||
if (!isNan(mrow))
|
||||
tcoords->SetTuple(pos++, srow->val);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user