Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
70a81db5
Commit
70a81db5
authored
Jan 01, 2014
by
Anatoly Baksheev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fixed bugs in cloud collection and added test
parent
cb580616
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
57 additions
and
196 deletions
+57
-196
viz3d.rst
modules/viz/doc/viz3d.rst
+4
-4
types.hpp
modules/viz/include/opencv2/viz/types.hpp
+1
-1
clouds.cpp
modules/viz/src/clouds.cpp
+36
-190
types.cpp
modules/viz/src/types.cpp
+1
-1
tests_simple.cpp
modules/viz/test/tests_simple.cpp
+15
-0
No files found.
modules/viz/doc/viz3d.rst
View file @
70a81db5
...
...
@@ -482,19 +482,19 @@ This class wraps mesh attributes, and it can load a mesh from a ``ply`` file. ::
Mat polygons;
//! Loads mesh from a given ply file
static Mesh3d load
Mesh
(const String& file);
static Mesh3d load(const String& file);
private:
/* hidden */
};
viz::Mesh3d::load
Mesh
viz::Mesh3d::load
---------------------
Loads a mesh from a ``ply`` file.
.. ocv:function:: static Mesh3d load
Mesh
(const String& file)
.. ocv:function:: static Mesh3d load(const String& file)
:param file: File name
.
:param file: File name
(for no only PLY is supported)
viz::KeyboardEvent
...
...
modules/viz/include/opencv2/viz/types.hpp
View file @
70a81db5
...
...
@@ -112,7 +112,7 @@ namespace cv
Mat
polygons
;
//! Loads mesh from a given ply file
static
Mesh3d
load
Mesh
(
const
String
&
file
);
static
Mesh3d
load
(
const
String
&
file
);
};
class
CV_EXPORTS
Camera
...
...
modules/viz/src/clouds.cpp
View file @
70a81db5
...
...
@@ -106,121 +106,52 @@ template<> cv::viz::WCloud cv::viz::Widget::cast<cv::viz::WCloud>()
///////////////////////////////////////////////////////////////////////////////////////////////
/// Cloud Collection Widget implementation
namespace
cv
{
namespace
viz
{
namespace
cv
::
viz
::
WCloudCollection
::
WCloudCollection
()
{
struct
CloudCollectionUtils
{
static
inline
vtkSmartPointer
<
vtkPolyData
>
create
(
const
Mat
&
cloud
,
vtkIdType
&
nr_points
)
{
vtkSmartPointer
<
vtkPolyData
>
polydata
=
vtkSmartPointer
<
vtkPolyData
>::
New
();
vtkSmartPointer
<
vtkCellArray
>
vertices
=
vtkSmartPointer
<
vtkCellArray
>::
New
();
polydata
->
SetVerts
(
vertices
);
vtkSmartPointer
<
vtkPoints
>
points
=
polydata
->
GetPoints
();
vtkSmartPointer
<
vtkIdTypeArray
>
initcells
;
nr_points
=
cloud
.
total
();
// Just create the actor
vtkSmartPointer
<
vtkLODActor
>
actor
=
vtkSmartPointer
<
vtkLODActor
>::
New
();
WidgetAccessor
::
setProp
(
*
this
,
actor
);
}
if
(
!
points
)
{
points
=
vtkSmartPointer
<
vtkPoints
>::
New
();
if
(
cloud
.
depth
()
==
CV_32F
)
points
->
SetDataTypeToFloat
();
else
if
(
cloud
.
depth
()
==
CV_64F
)
points
->
SetDataTypeToDouble
();
polydata
->
SetPoints
(
points
);
}
points
->
SetNumberOfPoints
(
nr_points
);
void
cv
::
viz
::
WCloudCollection
::
addCloud
(
InputArray
cloud
,
InputArray
colors
,
const
Affine3d
&
pose
)
{
vtkSmartPointer
<
vtkCloudMatSource
>
source
=
vtkSmartPointer
<
vtkCloudMatSource
>::
New
();
source
->
SetColorCloud
(
cloud
,
colors
);
if
(
cloud
.
depth
()
==
CV_32F
)
{
// Get a pointer to the beginning of the data array
Vec3f
*
data_beg
=
vtkpoints_data
<
float
>
(
points
);
Vec3f
*
data_end
=
NanFilter
::
copy
(
cloud
,
data_beg
,
cloud
);
nr_points
=
data_end
-
data_beg
;
}
else
if
(
cloud
.
depth
()
==
CV_64F
)
{
// Get a pointer to the beginning of the data array
Vec3d
*
data_beg
=
vtkpoints_data
<
double
>
(
points
);
Vec3d
*
data_end
=
NanFilter
::
copy
(
cloud
,
data_beg
,
cloud
);
nr_points
=
data_end
-
data_beg
;
}
points
->
SetNumberOfPoints
(
nr_points
);
vtkSmartPointer
<
vtkTransform
>
transform
=
vtkSmartPointer
<
vtkTransform
>::
New
();
transform
->
SetMatrix
(
pose
.
matrix
.
val
);
// Update cells
vtkSmartPointer
<
vtkIdTypeArray
>
cells
=
vertices
->
GetData
();
// If no init cells and cells has not been initialized...
if
(
!
cells
)
cells
=
vtkSmartPointer
<
vtkIdTypeArray
>::
New
();
vtkSmartPointer
<
vtkTransformPolyDataFilter
>
transform_filter
=
vtkSmartPointer
<
vtkTransformPolyDataFilter
>::
New
();
transform_filter
->
SetInputConnection
(
source
->
GetOutputPort
());
transform_filter
->
SetTransform
(
transform
);
transform_filter
->
Update
();
// If we have less values then we need to recreate the array
if
(
cells
->
GetNumberOfTuples
()
<
nr_points
)
{
cells
=
vtkSmartPointer
<
vtkIdTypeArray
>::
New
();
vtkSmartPointer
<
vtkLODActor
>
actor
=
vtkLODActor
::
SafeDownCast
(
WidgetAccessor
::
getProp
(
*
this
));
CV_Assert
(
"Incompatible widget type."
&&
actor
);
// If init cells is given, and there's enough data in it, use it
if
(
initcells
&&
initcells
->
GetNumberOfTuples
()
>=
nr_points
)
{
cells
->
DeepCopy
(
initcells
);
cells
->
SetNumberOfComponents
(
2
);
cells
->
SetNumberOfTuples
(
nr_points
);
}
else
{
// If the number of tuples is still too small, we need to recreate the array
cells
->
SetNumberOfComponents
(
2
);
cells
->
SetNumberOfTuples
(
nr_points
);
vtkIdType
*
cell
=
cells
->
GetPointer
(
0
);
// Fill it with 1s
std
::
fill
(
cell
,
cell
+
nr_points
*
2
,
1
);
cell
++
;
for
(
vtkIdType
i
=
0
;
i
<
nr_points
;
++
i
,
cell
+=
2
)
*
cell
=
i
;
// Save the results in initcells
initcells
=
vtkSmartPointer
<
vtkIdTypeArray
>::
New
();
initcells
->
DeepCopy
(
cells
);
}
}
else
{
// The assumption here is that the current set of cells has more data than needed
cells
->
SetNumberOfComponents
(
2
);
cells
->
SetNumberOfTuples
(
nr_points
);
}
vtkSmartPointer
<
vtkPolyData
>
poly_data
=
transform_filter
->
GetOutput
();
// Set the cells and the vertices
vertices
->
SetCells
(
nr_points
,
cells
);
return
polydata
;
}
vtkSmartPointer
<
vtkPolyDataMapper
>
mapper
=
vtkPolyDataMapper
::
SafeDownCast
(
actor
->
GetMapper
());
static
void
createMapper
(
vtkSmartPointer
<
vtkLODActor
>
actor
,
vtkSmartPointer
<
vtkPolyData
>
poly_data
)
{
vtkDataSetMapper
*
mapper
=
vtkDataSetMapper
::
SafeDownCast
(
actor
->
GetMapper
());
if
(
!
mapper
)
{
// This is the first cloud
vtkSmartPointer
<
vtkPolyDataMapper
>
mapper_new
=
vtkSmartPointer
<
vtkPolyDataMapper
>::
New
();
mapper
=
vtkSmartPointer
<
vtkPolyDataMapper
>::
New
();
#if VTK_MAJOR_VERSION <= 5
mapper_new
->
SetInputConnection
(
poly_data
->
GetProducerPort
()
);
mapper
->
SetInput
(
poly_data
);
#else
mapper_new
->
SetInputData
(
poly_data
);
mapper
->
SetInputData
(
poly_data
);
#endif
mapper
->
SetScalarRange
(
0
,
255
);
mapper
->
SetScalarModeToUsePointData
();
mapper
->
ScalarVisibilityOn
();
mapper
->
ImmediateModeRenderingOff
();
mapper_new
->
SetScalarRange
(
0
,
255
);
mapper_new
->
SetScalarModeToUsePointData
();
bool
interpolation
=
(
poly_data
&&
poly_data
->
GetNumberOfCells
()
!=
poly_data
->
GetNumberOfVerts
());
mapper_new
->
SetInterpolateScalarsBeforeMapping
(
interpolation
);
mapper_new
->
ScalarVisibilityOn
();
mapper_new
->
ImmediateModeRenderingOff
();
actor
->
SetNumberOfCloudPoints
(
int
(
std
::
max
<
vtkIdType
>
(
1
,
poly_data
->
GetNumberOfPoints
()
/
10
)));
actor
->
SetNumberOfCloudPoints
(
std
::
max
(
1
,
poly_data
->
GetNumberOfPoints
()
/
10
));
actor
->
GetProperty
()
->
SetInterpolationToFlat
();
actor
->
GetProperty
()
->
BackfaceCullingOn
();
actor
->
SetMapper
(
mapper_new
);
return
;
actor
->
SetMapper
(
mapper
);
return
;
}
vtkPolyData
*
data
=
vtkPolyData
::
SafeDownCast
(
mapper
->
GetInput
());
...
...
@@ -228,106 +159,21 @@ namespace cv { namespace viz { namespace
vtkSmartPointer
<
vtkAppendPolyData
>
appendFilter
=
vtkSmartPointer
<
vtkAppendPolyData
>::
New
();
#if VTK_MAJOR_VERSION <= 5
appendFilter
->
AddInputConnection
(
mapper
->
GetInput
()
->
GetProducerPort
());
appendFilter
->
AddInputConnection
(
poly_data
->
GetProducerPort
());
appendFilter
->
AddInput
(
data
);
appendFilter
->
AddInput
(
poly_data
);
mapper
->
SetInput
(
appendFilter
->
GetOutput
());
#else
appendFilter
->
AddInputData
(
data
);
appendFilter
->
AddInputData
(
poly_data
);
mapper
->
SetInputData
(
appendFilter
->
GetOutput
());
#endif
mapper
->
SetInputConnection
(
appendFilter
->
GetOutputPort
());
// Update the number of cloud points
vtkIdType
old_cloud_points
=
actor
->
GetNumberOfCloudPoints
();
actor
->
SetNumberOfCloudPoints
(
int
(
std
::
max
<
vtkIdType
>
(
1
,
old_cloud_points
+
poly_data
->
GetNumberOfPoints
()
/
10
)));
}
};
}}}
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
)
{
Mat
cloud
=
_cloud
.
getMat
();
Mat
colors
=
_colors
.
getMat
();
CV_Assert
(
cloud
.
type
()
==
CV_32FC3
||
cloud
.
type
()
==
CV_64FC3
||
cloud
.
type
()
==
CV_32FC4
||
cloud
.
type
()
==
CV_64FC4
);
CV_Assert
(
colors
.
depth
()
==
CV_8U
&&
cloud
.
size
()
==
colors
.
size
());
vtkIdType
nr_points
;
vtkSmartPointer
<
vtkPolyData
>
polydata
=
CloudCollectionUtils
::
create
(
cloud
,
nr_points
);
// Filter colors
Vec3b
*
colors_data
=
new
Vec3b
[
nr_points
];
NanFilter
::
copyColor
(
colors
,
colors_data
,
cloud
);
vtkSmartPointer
<
vtkUnsignedCharArray
>
scalars
=
vtkSmartPointer
<
vtkUnsignedCharArray
>::
New
();
scalars
->
SetNumberOfComponents
(
3
);
scalars
->
SetNumberOfTuples
(
nr_points
);
scalars
->
SetArray
(
colors_data
->
val
,
3
*
nr_points
,
0
);
// Assign the colors
polydata
->
GetPointData
()
->
SetScalars
(
scalars
);
// Transform the poly data based on the pose
vtkSmartPointer
<
vtkTransform
>
transform
=
vtkSmartPointer
<
vtkTransform
>::
New
();
transform
->
PreMultiply
();
transform
->
SetMatrix
(
convertToVtkMatrix
(
pose
.
matrix
));
vtkSmartPointer
<
vtkTransformPolyDataFilter
>
transform_filter
=
vtkSmartPointer
<
vtkTransformPolyDataFilter
>::
New
();
transform_filter
->
SetTransform
(
transform
);
#if VTK_MAJOR_VERSION <= 5
transform_filter
->
SetInputConnection
(
polydata
->
GetProducerPort
());
#else
transform_filter
->
SetInputData
(
polydata
);
#endif
transform_filter
->
Update
();
vtkLODActor
*
actor
=
vtkLODActor
::
SafeDownCast
(
WidgetAccessor
::
getProp
(
*
this
));
CV_Assert
(
"Incompatible widget type."
&&
actor
);
CloudCollectionUtils
::
createMapper
(
actor
,
transform_filter
->
GetOutput
());
actor
->
SetNumberOfCloudPoints
(
std
::
max
(
1
,
actor
->
GetNumberOfCloudPoints
()
+
poly_data
->
GetNumberOfPoints
()
/
10
));
}
void
cv
::
viz
::
WCloudCollection
::
addCloud
(
InputArray
_
cloud
,
const
Color
&
color
,
const
Affine3d
&
pose
)
void
cv
::
viz
::
WCloudCollection
::
addCloud
(
InputArray
cloud
,
const
Color
&
color
,
const
Affine3d
&
pose
)
{
Mat
cloud
=
_cloud
.
getMat
();
CV_Assert
(
cloud
.
type
()
==
CV_32FC3
||
cloud
.
type
()
==
CV_64FC3
||
cloud
.
type
()
==
CV_32FC4
||
cloud
.
type
()
==
CV_64FC4
);
vtkIdType
nr_points
;
vtkSmartPointer
<
vtkPolyData
>
polydata
=
CloudCollectionUtils
::
create
(
cloud
,
nr_points
);
vtkSmartPointer
<
vtkUnsignedCharArray
>
scalars
=
vtkSmartPointer
<
vtkUnsignedCharArray
>::
New
();
scalars
->
SetNumberOfComponents
(
3
);
scalars
->
SetNumberOfTuples
(
nr_points
);
scalars
->
FillComponent
(
0
,
color
[
2
]);
scalars
->
FillComponent
(
1
,
color
[
1
]);
scalars
->
FillComponent
(
2
,
color
[
0
]);
// Assign the colors
polydata
->
GetPointData
()
->
SetScalars
(
scalars
);
// Transform the poly data based on the pose
vtkSmartPointer
<
vtkTransform
>
transform
=
vtkSmartPointer
<
vtkTransform
>::
New
();
transform
->
PreMultiply
();
transform
->
SetMatrix
(
convertToVtkMatrix
(
pose
.
matrix
));
vtkSmartPointer
<
vtkTransformPolyDataFilter
>
transform_filter
=
vtkSmartPointer
<
vtkTransformPolyDataFilter
>::
New
();
transform_filter
->
SetTransform
(
transform
);
#if VTK_MAJOR_VERSION <= 5
transform_filter
->
SetInputConnection
(
polydata
->
GetProducerPort
());
#else
transform_filter
->
SetInputData
(
polydata
);
#endif
transform_filter
->
Update
();
vtkLODActor
*
actor
=
vtkLODActor
::
SafeDownCast
(
WidgetAccessor
::
getProp
(
*
this
));
CV_Assert
(
"Incompatible widget type."
&&
actor
);
CloudCollectionUtils
::
createMapper
(
actor
,
transform_filter
->
GetOutput
());
addCloud
(
cloud
,
Mat
(
cloud
.
size
(),
CV_8UC3
,
color
),
pose
);
}
template
<>
cv
::
viz
::
WCloudCollection
cv
::
viz
::
Widget
::
cast
<
cv
::
viz
::
WCloudCollection
>
()
...
...
modules/viz/src/types.cpp
View file @
70a81db5
...
...
@@ -128,7 +128,7 @@ namespace cv { namespace viz { namespace
};
}}}
cv
::
viz
::
Mesh3d
cv
::
viz
::
Mesh3d
::
load
Mesh
(
const
String
&
file
)
cv
::
viz
::
Mesh3d
cv
::
viz
::
Mesh3d
::
load
(
const
String
&
file
)
{
return
MeshUtils
::
loadMesh
(
file
);
}
...
...
modules/viz/test/tests_simple.cpp
View file @
70a81db5
...
...
@@ -85,3 +85,18 @@ TEST(Viz, DISABLED_show_cloud_masked)
viz
.
showWidget
(
"dragon"
,
WCloud
(
dragon_cloud
));
viz
.
spin
();
}
TEST
(
Viz
,
DISABLED_show_cloud_collection
)
{
Mat
cloud
=
readCloud
(
get_dragon_ply_file_path
());
WCloudCollection
ccol
;
ccol
.
addCloud
(
cloud
,
Color
::
white
(),
Affine3d
().
translate
(
Vec3d
(
0
,
0
,
0
)).
rotate
(
Vec3d
(
1.57
,
0
,
0
)));
ccol
.
addCloud
(
cloud
,
Color
::
blue
(),
Affine3d
().
translate
(
Vec3d
(
1
,
0
,
0
)));
ccol
.
addCloud
(
cloud
,
Color
::
red
(),
Affine3d
().
translate
(
Vec3d
(
2
,
0
,
0
)));
Viz3d
viz
(
"show_cloud_collection"
);
viz
.
showWidget
(
"coosys"
,
WCoordinateSystem
());
viz
.
showWidget
(
"ccol"
,
ccol
);
viz
.
spin
();
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment