Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/modules/viz/src/vtk/vtkCloudMatSource.cpp
16358 views
1
/*M///////////////////////////////////////////////////////////////////////////////////////
2
//
3
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4
//
5
// By downloading, copying, installing or using the software you agree to this license.
6
// If you do not agree to this license, do not download, install,
7
// copy or use the software.
8
//
9
//
10
// License Agreement
11
// For Open Source Computer Vision Library
12
//
13
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
14
// Third party copyrights are property of their respective owners.
15
//
16
// Redistribution and use in source and binary forms, with or without modification,
17
// are permitted provided that the following conditions are met:
18
//
19
// * Redistribution's of source code must retain the above copyright notice,
20
// this list of conditions and the following disclaimer.
21
//
22
// * Redistribution's in binary form must reproduce the above copyright notice,
23
// this list of conditions and the following disclaimer in the documentation
24
// and/or other materials provided with the distribution.
25
//
26
// * The name of the copyright holders may not be used to endorse or promote products
27
// derived from this software without specific prior written permission.
28
//
29
// This software is provided by the copyright holders and contributors "as is" and
30
// any express or implied warranties, including, but not limited to, the implied
31
// warranties of merchantability and fitness for a particular purpose are disclaimed.
32
// In no event shall the Intel Corporation or contributors be liable for any direct,
33
// indirect, incidental, special, exemplary, or consequential damages
34
// (including, but not limited to, procurement of substitute goods or services;
35
// loss of use, data, or profits; or business interruption) however caused
36
// and on any theory of liability, whether in contract, strict liability,
37
// or tort (including negligence or otherwise) arising in any way out of
38
// the use of this software, even if advised of the possibility of such damage.
39
//
40
// Authors:
41
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
42
//
43
//M*/
44
45
#include "../precomp.hpp"
46
47
namespace cv { namespace viz
48
{
49
vtkStandardNewMacro(vtkCloudMatSource);
50
51
template<typename _Tp> struct VtkDepthTraits;
52
53
template<> struct VtkDepthTraits<float>
54
{
55
const static int data_type = VTK_FLOAT;
56
typedef vtkFloatArray array_type;
57
};
58
59
template<> struct VtkDepthTraits<double>
60
{
61
const static int data_type = VTK_DOUBLE;
62
typedef vtkDoubleArray array_type;
63
};
64
}}
65
66
cv::viz::vtkCloudMatSource::vtkCloudMatSource() { SetNumberOfInputPorts(0); }
67
cv::viz::vtkCloudMatSource::~vtkCloudMatSource() {}
68
69
int cv::viz::vtkCloudMatSource::SetCloud(InputArray _cloud)
70
{
71
CV_Assert(_cloud.depth() == CV_32F || _cloud.depth() == CV_64F);
72
CV_Assert(_cloud.channels() == 3 || _cloud.channels() == 4);
73
74
Mat cloud = _cloud.getMat();
75
76
int total = _cloud.depth() == CV_32F ? filterNanCopy<float>(cloud) : filterNanCopy<double>(cloud);
77
78
vertices = vtkSmartPointer<vtkCellArray>::New();
79
vertices->Allocate(vertices->EstimateSize(1, total));
80
vertices->InsertNextCell(total);
81
for(int i = 0; i < total; ++i)
82
vertices->InsertCellPoint(i);
83
84
return total;
85
}
86
87
int cv::viz::vtkCloudMatSource::SetColorCloud(InputArray _cloud, InputArray _colors)
88
{
89
int total = SetCloud(_cloud);
90
91
if (_colors.empty())
92
return total;
93
94
CV_Assert(_colors.depth() == CV_8U && _colors.channels() <= 4 && _colors.channels() != 2);
95
CV_Assert(_colors.size() == _cloud.size());
96
97
Mat cloud = _cloud.getMat();
98
Mat colors = _colors.getMat();
99
100
if (cloud.depth() == CV_32F)
101
filterNanColorsCopy<float>(colors, cloud, total);
102
else if (cloud.depth() == CV_64F)
103
filterNanColorsCopy<double>(colors, cloud, total);
104
105
return total;
106
}
107
108
int cv::viz::vtkCloudMatSource::SetColorCloudNormals(InputArray _cloud, InputArray _colors, InputArray _normals)
109
{
110
int total = SetColorCloud(_cloud, _colors);
111
112
if (_normals.empty())
113
return total;
114
115
CV_Assert(_normals.depth() == CV_32F || _normals.depth() == CV_64F);
116
CV_Assert(_normals.channels() == 3 || _normals.channels() == 4);
117
CV_Assert(_normals.size() == _cloud.size());
118
119
Mat c = _cloud.getMat();
120
Mat n = _normals.getMat();
121
122
if (n.depth() == CV_32F && c.depth() == CV_32F)
123
filterNanNormalsCopy<float, float>(n, c, total);
124
else if (n.depth() == CV_32F && c.depth() == CV_64F)
125
filterNanNormalsCopy<float, double>(n, c, total);
126
else if (n.depth() == CV_64F && c.depth() == CV_32F)
127
filterNanNormalsCopy<double, float>(n, c, total);
128
else if (n.depth() == CV_64F && c.depth() == CV_64F)
129
filterNanNormalsCopy<double, double>(n, c, total);
130
else
131
CV_Error(Error::StsError, "Unsupported normals/cloud type");
132
133
return total;
134
}
135
136
int cv::viz::vtkCloudMatSource::SetColorCloudNormalsTCoords(InputArray _cloud, InputArray _colors, InputArray _normals, InputArray _tcoords)
137
{
138
int total = SetColorCloudNormals(_cloud, _colors, _normals);
139
140
if (_tcoords.empty())
141
return total;
142
143
CV_Assert(_tcoords.depth() == CV_32F || _tcoords.depth() == CV_64F);
144
CV_Assert(_tcoords.channels() == 2 && _tcoords.size() == _cloud.size());
145
146
Mat cl = _cloud.getMat();
147
Mat tc = _tcoords.getMat();
148
149
if (tc.depth() == CV_32F && cl.depth() == CV_32F)
150
filterNanTCoordsCopy<float, float>(tc, cl, total);
151
else if (tc.depth() == CV_32F && cl.depth() == CV_64F)
152
filterNanTCoordsCopy<float, double>(tc, cl, total);
153
else if (tc.depth() == CV_64F && cl.depth() == CV_32F)
154
filterNanTCoordsCopy<double, float>(tc, cl, total);
155
else if (tc.depth() == CV_64F && cl.depth() == CV_64F)
156
filterNanTCoordsCopy<double, double>(tc, cl, total);
157
else
158
CV_Error(Error::StsError, "Unsupported tcoords/cloud type");
159
160
return total;
161
}
162
163
int cv::viz::vtkCloudMatSource::RequestData(vtkInformation *vtkNotUsed(request), vtkInformationVector **vtkNotUsed(inputVector), vtkInformationVector *outputVector)
164
{
165
vtkInformation *outInfo = outputVector->GetInformationObject(0);
166
vtkPolyData *output = vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
167
168
output->SetPoints(points);
169
output->SetVerts(vertices);
170
if (scalars)
171
output->GetPointData()->SetScalars(scalars);
172
173
if (normals)
174
output->GetPointData()->SetNormals(normals);
175
176
if (tcoords)
177
output->GetPointData()->SetTCoords(tcoords);
178
179
return 1;
180
}
181
182
template<typename _Tp>
183
int cv::viz::vtkCloudMatSource::filterNanCopy(const Mat& cloud)
184
{
185
CV_DbgAssert(DataType<_Tp>::depth == cloud.depth());
186
points = vtkSmartPointer<vtkPoints>::New();
187
points->SetDataType(VtkDepthTraits<_Tp>::data_type);
188
points->Allocate((vtkIdType)cloud.total());
189
points->SetNumberOfPoints((vtkIdType)cloud.total());
190
191
int s_chs = cloud.channels();
192
int total = 0;
193
for (int y = 0; y < cloud.rows; ++y)
194
{
195
const _Tp* srow = cloud.ptr<_Tp>(y);
196
const _Tp* send = srow + cloud.cols * s_chs;
197
198
for (; srow != send; srow += s_chs)
199
if (!isNan(srow))
200
points->SetPoint(total++, srow);
201
}
202
points->SetNumberOfPoints(total);
203
points->Squeeze();
204
return total;
205
}
206
207
template<typename _Msk>
208
void cv::viz::vtkCloudMatSource::filterNanColorsCopy(const Mat& cloud_colors, const Mat& mask, int total)
209
{
210
Vec3b* array = new Vec3b[total];
211
Vec3b* pos = array;
212
213
int s_chs = cloud_colors.channels();
214
int m_chs = mask.channels();
215
for (int y = 0; y < cloud_colors.rows; ++y)
216
{
217
const unsigned char* srow = cloud_colors.ptr<unsigned char>(y);
218
const unsigned char* send = srow + cloud_colors.cols * s_chs;
219
const _Msk* mrow = mask.ptr<_Msk>(y);
220
221
if (cloud_colors.channels() == 1)
222
{
223
for (; srow != send; srow += s_chs, mrow += m_chs)
224
if (!isNan(mrow))
225
*pos++ = Vec3b(srow[0], srow[0], srow[0]);
226
}
227
else
228
for (; srow != send; srow += s_chs, mrow += m_chs)
229
if (!isNan(mrow))
230
*pos++ = Vec3b(srow[2], srow[1], srow[0]);
231
232
}
233
234
scalars = vtkSmartPointer<vtkUnsignedCharArray>::New();
235
scalars->SetName("Colors");
236
scalars->SetNumberOfComponents(3);
237
scalars->SetNumberOfTuples(total);
238
scalars->SetArray(array->val, total * 3, 0, vtkUnsignedCharArray::VTK_DATA_ARRAY_DELETE);
239
}
240
241
template<typename _Tn, typename _Msk>
242
void cv::viz::vtkCloudMatSource::filterNanNormalsCopy(const Mat& cloud_normals, const Mat& mask, int total)
243
{
244
normals = vtkSmartPointer< typename VtkDepthTraits<_Tn>::array_type >::New();
245
normals->SetName("Normals");
246
normals->SetNumberOfComponents(3);
247
normals->SetNumberOfTuples(total);
248
249
int s_chs = cloud_normals.channels();
250
int m_chs = mask.channels();
251
252
int pos = 0;
253
for (int y = 0; y < cloud_normals.rows; ++y)
254
{
255
const _Tn* srow = cloud_normals.ptr<_Tn>(y);
256
const _Tn* send = srow + cloud_normals.cols * s_chs;
257
258
const _Msk* mrow = mask.ptr<_Msk>(y);
259
260
for (; srow != send; srow += s_chs, mrow += m_chs)
261
if (!isNan(mrow))
262
normals->SetTuple(pos++, srow);
263
}
264
}
265
266
template<typename _Tn, typename _Msk>
267
void cv::viz::vtkCloudMatSource::filterNanTCoordsCopy(const Mat& _tcoords, const Mat& mask, int total)
268
{
269
typedef Vec<_Tn, 2> Vec2;
270
tcoords = vtkSmartPointer< typename VtkDepthTraits<_Tn>::array_type >::New();
271
tcoords->SetName("TextureCoordinates");
272
tcoords->SetNumberOfComponents(2);
273
tcoords->SetNumberOfTuples(total);
274
275
int pos = 0;
276
for (int y = 0; y < mask.rows; ++y)
277
{
278
const Vec2* srow = _tcoords.ptr<Vec2>(y);
279
const Vec2* send = srow + _tcoords.cols;
280
const _Msk* mrow = mask.ptr<_Msk>(y);
281
282
for (; srow != send; ++srow, mrow += mask.channels())
283
if (!isNan(mrow))
284
tcoords->SetTuple(pos++, srow->val);
285
}
286
}
287
288