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
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
63 additions
and
202 deletions
+63
-202
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
+42
-196
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,143 +106,6 @@ template<> cv::viz::WCloud cv::viz::Widget::cast<cv::viz::WCloud>()
///////////////////////////////////////////////////////////////////////////////////////////////
/// Cloud Collection Widget implementation
namespace
cv
{
namespace
viz
{
namespace
{
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
();
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
);
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
);
// Update cells
vtkSmartPointer
<
vtkIdTypeArray
>
cells
=
vertices
->
GetData
();
// If no init cells and cells has not been initialized...
if
(
!
cells
)
cells
=
vtkSmartPointer
<
vtkIdTypeArray
>::
New
();
// If we have less values then we need to recreate the array
if
(
cells
->
GetNumberOfTuples
()
<
nr_points
)
{
cells
=
vtkSmartPointer
<
vtkIdTypeArray
>::
New
();
// 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
);
}
// Set the cells and the vertices
vertices
->
SetCells
(
nr_points
,
cells
);
return
polydata
;
}
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
();
#if VTK_MAJOR_VERSION <= 5
mapper_new
->
SetInputConnection
(
poly_data
->
GetProducerPort
());
#else
mapper_new
->
SetInputData
(
poly_data
);
#endif
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
->
GetProperty
()
->
SetInterpolationToFlat
();
actor
->
GetProperty
()
->
BackfaceCullingOn
();
actor
->
SetMapper
(
mapper_new
);
return
;
}
vtkPolyData
*
data
=
vtkPolyData
::
SafeDownCast
(
mapper
->
GetInput
());
CV_Assert
(
"Cloud Widget without data"
&&
data
);
vtkSmartPointer
<
vtkAppendPolyData
>
appendFilter
=
vtkSmartPointer
<
vtkAppendPolyData
>::
New
();
#if VTK_MAJOR_VERSION <= 5
appendFilter
->
AddInputConnection
(
mapper
->
GetInput
()
->
GetProducerPort
());
appendFilter
->
AddInputConnection
(
poly_data
->
GetProducerPort
());
#else
appendFilter
->
AddInputData
(
data
);
appendFilter
->
AddInputData
(
poly_data
);
#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
...
...
@@ -250,84 +113,67 @@ cv::viz::WCloudCollection::WCloudCollection()
WidgetAccessor
::
setProp
(
*
this
,
actor
);
}
void
cv
::
viz
::
WCloudCollection
::
addCloud
(
InputArray
_cloud
,
InputArray
_
colors
,
const
Affine3d
&
pose
)
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
<
vtkCloudMatSource
>
source
=
vtkSmartPointer
<
vtkCloudMatSource
>::
New
();
source
->
SetColorCloud
(
cloud
,
colors
);
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
));
transform
->
SetMatrix
(
pose
.
matrix
.
val
);
vtkSmartPointer
<
vtkTransformPolyDataFilter
>
transform_filter
=
vtkSmartPointer
<
vtkTransformPolyDataFilter
>::
New
();
transform_filter
->
SetInputConnection
(
source
->
GetOutputPort
());
transform_filter
->
SetTransform
(
transform
);
#if VTK_MAJOR_VERSION <= 5
transform_filter
->
SetInputConnection
(
polydata
->
GetProducerPort
());
#else
transform_filter
->
SetInputData
(
polydata
);
#endif
transform_filter
->
Update
();
vtk
LODActor
*
actor
=
vtkLODActor
::
SafeDownCast
(
WidgetAccessor
::
getProp
(
*
this
));
vtk
SmartPointer
<
vtkLODActor
>
actor
=
vtkLODActor
::
SafeDownCast
(
WidgetAccessor
::
getProp
(
*
this
));
CV_Assert
(
"Incompatible widget type."
&&
actor
);
CloudCollectionUtils
::
createMapper
(
actor
,
transform_filter
->
GetOutput
());
}
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
<
vtkPolyData
>
poly_data
=
transform_filter
->
GetOutput
();
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
]);
vtkSmartPointer
<
vtkPolyDataMapper
>
mapper
=
vtkPolyDataMapper
::
SafeDownCast
(
actor
->
GetMapper
());
// Assign the colors
polydata
->
GetPointData
()
->
SetScalars
(
scalars
);
if
(
!
mapper
)
{
// This is the first cloud
mapper
=
vtkSmartPointer
<
vtkPolyDataMapper
>::
New
();
#if VTK_MAJOR_VERSION <= 5
mapper
->
SetInput
(
poly_data
);
#else
mapper
->
SetInputData
(
poly_data
);
#endif
mapper
->
SetScalarRange
(
0
,
255
);
mapper
->
SetScalarModeToUsePointData
();
mapper
->
ScalarVisibilityOn
();
mapper
->
ImmediateModeRenderingOff
();
actor
->
SetNumberOfCloudPoints
(
std
::
max
(
1
,
poly_data
->
GetNumberOfPoints
()
/
10
));
actor
->
GetProperty
()
->
SetInterpolationToFlat
();
actor
->
GetProperty
()
->
BackfaceCullingOn
();
actor
->
SetMapper
(
mapper
);
return
;
}
// Transform the poly data based on the pose
vtkSmartPointer
<
vtkTransform
>
transform
=
vtkSmartPointer
<
vtkTransform
>::
New
();
transform
->
PreMultiply
();
transform
->
SetMatrix
(
convertToVtkMatrix
(
pose
.
matrix
));
vtkPolyData
*
data
=
vtkPolyData
::
SafeDownCast
(
mapper
->
GetInput
());
CV_Assert
(
"Cloud Widget without data"
&&
data
);
vtkSmartPointer
<
vtkTransformPolyDataFilter
>
transform_filter
=
vtkSmartPointer
<
vtkTransformPolyDataFilter
>::
New
();
transform_filter
->
SetTransform
(
transform
);
vtkSmartPointer
<
vtkAppendPolyData
>
appendFilter
=
vtkSmartPointer
<
vtkAppendPolyData
>::
New
();
#if VTK_MAJOR_VERSION <= 5
transform_filter
->
SetInputConnection
(
polydata
->
GetProducerPort
());
appendFilter
->
AddInput
(
data
);
appendFilter
->
AddInput
(
poly_data
);
mapper
->
SetInput
(
appendFilter
->
GetOutput
());
#else
transform_filter
->
SetInputData
(
polydata
);
appendFilter
->
AddInputData
(
data
);
appendFilter
->
AddInputData
(
poly_data
);
mapper
->
SetInputData
(
appendFilter
->
GetOutput
());
#endif
transform_filter
->
Update
();
vtkLODActor
*
actor
=
vtkLODActor
::
SafeDownCast
(
WidgetAccessor
::
getProp
(
*
this
));
CV_Assert
(
"Incompatible widget type."
&&
actor
);
actor
->
SetNumberOfCloudPoints
(
std
::
max
(
1
,
actor
->
GetNumberOfCloudPoints
()
+
poly_data
->
GetNumberOfPoints
()
/
10
));
}
CloudCollectionUtils
::
createMapper
(
actor
,
transform_filter
->
GetOutput
());
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
>
()
...
...
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