merge with origin

This commit is contained in:
Matti Picus
2014-02-21 11:59:49 +02:00
178 changed files with 18116 additions and 677 deletions

View File

@@ -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],

View File

@@ -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")

View File

@@ -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:

View 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__ */

View File

@@ -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;

View File

@@ -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 */

View File

@@ -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__

View File

@@ -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)

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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))
{

View File

@@ -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;
}
}
}

View File

@@ -40,8 +40,6 @@
//
//M*/
#define CUDA_DISABLER
#if !defined CUDA_DISABLER
#include <thrust/device_ptr.h>

View File

@@ -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;

View File

@@ -40,8 +40,6 @@
//
//M*/
#define CUDA_DISABLER
#include "precomp.hpp"
using namespace std;

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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)

View File

@@ -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(

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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());

View File

@@ -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

View File

@@ -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),

View File

@@ -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]) {

View File

@@ -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;

View File

@@ -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
{

View File

@@ -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:

View File

@@ -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");
}

View File

@@ -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_);

View File

@@ -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;

View File

@@ -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

View File

@@ -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>

View File

@@ -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();

View File

@@ -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;

View File

@@ -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

View File

@@ -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));
}

View File

@@ -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"

View File

@@ -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 (...) {

View File

@@ -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);
}
/**

View File

@@ -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)
{

View File

@@ -87,7 +87,6 @@ public class TermCriteria {
@Override
public String toString() {
if (this == null) return "null";
return "{ type: " + type + ", maxCount: " + maxCount + ", epsilon: " + epsilon + "}";
}
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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()

View File

@@ -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__

View File

@@ -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"

View File

@@ -4,6 +4,9 @@
static const char * impls[] = {
#ifdef HAVE_CUDA
"cuda",
#endif
#ifdef HAVE_OPENCL
"ocl",
#endif
"plain"
};

View File

@@ -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

View File

@@ -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"

View File

@@ -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

View File

@@ -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)

View File

@@ -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;

View File

@@ -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());

View File

@@ -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();
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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()

View File

@@ -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:

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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})

View File

@@ -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

View File

@@ -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

View 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()

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

9
modules/viz/doc/viz.rst Normal file
View File

@@ -0,0 +1,9 @@
***********************
viz. 3D Visualizer
***********************
.. toctree::
:maxdepth: 2
viz3d.rst
widget.rst

637
modules/viz/doc/viz3d.rst Normal file
View 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

File diff suppressed because it is too large Load Diff

View 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

View 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

View 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__ */

View 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

View 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 &center, 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 &center, 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
View 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);
}

View 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();
}

View 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
View 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

File diff suppressed because it is too large Load Diff

206
modules/viz/src/types.cpp Normal file
View 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
View 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
View 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
View 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
View 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

View 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";
}

View 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

View 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