Path: blob/master/modules/viz/src/vtk/vtkCloudMatSource.cpp
16358 views
/*M///////////////////////////////////////////////////////////////////////////////////////1//2// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.3//4// By downloading, copying, installing or using the software you agree to this license.5// If you do not agree to this license, do not download, install,6// copy or use the software.7//8//9// License Agreement10// For Open Source Computer Vision Library11//12// Copyright (C) 2013, OpenCV Foundation, all rights reserved.13// Third party copyrights are property of their respective owners.14//15// Redistribution and use in source and binary forms, with or without modification,16// are permitted provided that the following conditions are met:17//18// * Redistribution's of source code must retain the above copyright notice,19// this list of conditions and the following disclaimer.20//21// * Redistribution's in binary form must reproduce the above copyright notice,22// this list of conditions and the following disclaimer in the documentation23// and/or other materials provided with the distribution.24//25// * The name of the copyright holders may not be used to endorse or promote products26// derived from this software without specific prior written permission.27//28// This software is provided by the copyright holders and contributors "as is" and29// any express or implied warranties, including, but not limited to, the implied30// warranties of merchantability and fitness for a particular purpose are disclaimed.31// In no event shall the Intel Corporation or contributors be liable for any direct,32// indirect, incidental, special, exemplary, or consequential damages33// (including, but not limited to, procurement of substitute goods or services;34// loss of use, data, or profits; or business interruption) however caused35// and on any theory of liability, whether in contract, strict liability,36// or tort (including negligence or otherwise) arising in any way out of37// the use of this software, even if advised of the possibility of such damage.38//39// Authors:40// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com41//42//M*/4344#include "../precomp.hpp"4546namespace cv { namespace viz47{48vtkStandardNewMacro(vtkCloudMatSource);4950template<typename _Tp> struct VtkDepthTraits;5152template<> struct VtkDepthTraits<float>53{54const static int data_type = VTK_FLOAT;55typedef vtkFloatArray array_type;56};5758template<> struct VtkDepthTraits<double>59{60const static int data_type = VTK_DOUBLE;61typedef vtkDoubleArray array_type;62};63}}6465cv::viz::vtkCloudMatSource::vtkCloudMatSource() { SetNumberOfInputPorts(0); }66cv::viz::vtkCloudMatSource::~vtkCloudMatSource() {}6768int cv::viz::vtkCloudMatSource::SetCloud(InputArray _cloud)69{70CV_Assert(_cloud.depth() == CV_32F || _cloud.depth() == CV_64F);71CV_Assert(_cloud.channels() == 3 || _cloud.channels() == 4);7273Mat cloud = _cloud.getMat();7475int total = _cloud.depth() == CV_32F ? filterNanCopy<float>(cloud) : filterNanCopy<double>(cloud);7677vertices = vtkSmartPointer<vtkCellArray>::New();78vertices->Allocate(vertices->EstimateSize(1, total));79vertices->InsertNextCell(total);80for(int i = 0; i < total; ++i)81vertices->InsertCellPoint(i);8283return total;84}8586int cv::viz::vtkCloudMatSource::SetColorCloud(InputArray _cloud, InputArray _colors)87{88int total = SetCloud(_cloud);8990if (_colors.empty())91return total;9293CV_Assert(_colors.depth() == CV_8U && _colors.channels() <= 4 && _colors.channels() != 2);94CV_Assert(_colors.size() == _cloud.size());9596Mat cloud = _cloud.getMat();97Mat colors = _colors.getMat();9899if (cloud.depth() == CV_32F)100filterNanColorsCopy<float>(colors, cloud, total);101else if (cloud.depth() == CV_64F)102filterNanColorsCopy<double>(colors, cloud, total);103104return total;105}106107int cv::viz::vtkCloudMatSource::SetColorCloudNormals(InputArray _cloud, InputArray _colors, InputArray _normals)108{109int total = SetColorCloud(_cloud, _colors);110111if (_normals.empty())112return total;113114CV_Assert(_normals.depth() == CV_32F || _normals.depth() == CV_64F);115CV_Assert(_normals.channels() == 3 || _normals.channels() == 4);116CV_Assert(_normals.size() == _cloud.size());117118Mat c = _cloud.getMat();119Mat n = _normals.getMat();120121if (n.depth() == CV_32F && c.depth() == CV_32F)122filterNanNormalsCopy<float, float>(n, c, total);123else if (n.depth() == CV_32F && c.depth() == CV_64F)124filterNanNormalsCopy<float, double>(n, c, total);125else if (n.depth() == CV_64F && c.depth() == CV_32F)126filterNanNormalsCopy<double, float>(n, c, total);127else if (n.depth() == CV_64F && c.depth() == CV_64F)128filterNanNormalsCopy<double, double>(n, c, total);129else130CV_Error(Error::StsError, "Unsupported normals/cloud type");131132return total;133}134135int cv::viz::vtkCloudMatSource::SetColorCloudNormalsTCoords(InputArray _cloud, InputArray _colors, InputArray _normals, InputArray _tcoords)136{137int total = SetColorCloudNormals(_cloud, _colors, _normals);138139if (_tcoords.empty())140return total;141142CV_Assert(_tcoords.depth() == CV_32F || _tcoords.depth() == CV_64F);143CV_Assert(_tcoords.channels() == 2 && _tcoords.size() == _cloud.size());144145Mat cl = _cloud.getMat();146Mat tc = _tcoords.getMat();147148if (tc.depth() == CV_32F && cl.depth() == CV_32F)149filterNanTCoordsCopy<float, float>(tc, cl, total);150else if (tc.depth() == CV_32F && cl.depth() == CV_64F)151filterNanTCoordsCopy<float, double>(tc, cl, total);152else if (tc.depth() == CV_64F && cl.depth() == CV_32F)153filterNanTCoordsCopy<double, float>(tc, cl, total);154else if (tc.depth() == CV_64F && cl.depth() == CV_64F)155filterNanTCoordsCopy<double, double>(tc, cl, total);156else157CV_Error(Error::StsError, "Unsupported tcoords/cloud type");158159return total;160}161162int cv::viz::vtkCloudMatSource::RequestData(vtkInformation *vtkNotUsed(request), vtkInformationVector **vtkNotUsed(inputVector), vtkInformationVector *outputVector)163{164vtkInformation *outInfo = outputVector->GetInformationObject(0);165vtkPolyData *output = vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));166167output->SetPoints(points);168output->SetVerts(vertices);169if (scalars)170output->GetPointData()->SetScalars(scalars);171172if (normals)173output->GetPointData()->SetNormals(normals);174175if (tcoords)176output->GetPointData()->SetTCoords(tcoords);177178return 1;179}180181template<typename _Tp>182int cv::viz::vtkCloudMatSource::filterNanCopy(const Mat& cloud)183{184CV_DbgAssert(DataType<_Tp>::depth == cloud.depth());185points = vtkSmartPointer<vtkPoints>::New();186points->SetDataType(VtkDepthTraits<_Tp>::data_type);187points->Allocate((vtkIdType)cloud.total());188points->SetNumberOfPoints((vtkIdType)cloud.total());189190int s_chs = cloud.channels();191int total = 0;192for (int y = 0; y < cloud.rows; ++y)193{194const _Tp* srow = cloud.ptr<_Tp>(y);195const _Tp* send = srow + cloud.cols * s_chs;196197for (; srow != send; srow += s_chs)198if (!isNan(srow))199points->SetPoint(total++, srow);200}201points->SetNumberOfPoints(total);202points->Squeeze();203return total;204}205206template<typename _Msk>207void cv::viz::vtkCloudMatSource::filterNanColorsCopy(const Mat& cloud_colors, const Mat& mask, int total)208{209Vec3b* array = new Vec3b[total];210Vec3b* pos = array;211212int s_chs = cloud_colors.channels();213int m_chs = mask.channels();214for (int y = 0; y < cloud_colors.rows; ++y)215{216const unsigned char* srow = cloud_colors.ptr<unsigned char>(y);217const unsigned char* send = srow + cloud_colors.cols * s_chs;218const _Msk* mrow = mask.ptr<_Msk>(y);219220if (cloud_colors.channels() == 1)221{222for (; srow != send; srow += s_chs, mrow += m_chs)223if (!isNan(mrow))224*pos++ = Vec3b(srow[0], srow[0], srow[0]);225}226else227for (; srow != send; srow += s_chs, mrow += m_chs)228if (!isNan(mrow))229*pos++ = Vec3b(srow[2], srow[1], srow[0]);230231}232233scalars = vtkSmartPointer<vtkUnsignedCharArray>::New();234scalars->SetName("Colors");235scalars->SetNumberOfComponents(3);236scalars->SetNumberOfTuples(total);237scalars->SetArray(array->val, total * 3, 0, vtkUnsignedCharArray::VTK_DATA_ARRAY_DELETE);238}239240template<typename _Tn, typename _Msk>241void cv::viz::vtkCloudMatSource::filterNanNormalsCopy(const Mat& cloud_normals, const Mat& mask, int total)242{243normals = vtkSmartPointer< typename VtkDepthTraits<_Tn>::array_type >::New();244normals->SetName("Normals");245normals->SetNumberOfComponents(3);246normals->SetNumberOfTuples(total);247248int s_chs = cloud_normals.channels();249int m_chs = mask.channels();250251int pos = 0;252for (int y = 0; y < cloud_normals.rows; ++y)253{254const _Tn* srow = cloud_normals.ptr<_Tn>(y);255const _Tn* send = srow + cloud_normals.cols * s_chs;256257const _Msk* mrow = mask.ptr<_Msk>(y);258259for (; srow != send; srow += s_chs, mrow += m_chs)260if (!isNan(mrow))261normals->SetTuple(pos++, srow);262}263}264265template<typename _Tn, typename _Msk>266void cv::viz::vtkCloudMatSource::filterNanTCoordsCopy(const Mat& _tcoords, const Mat& mask, int total)267{268typedef Vec<_Tn, 2> Vec2;269tcoords = vtkSmartPointer< typename VtkDepthTraits<_Tn>::array_type >::New();270tcoords->SetName("TextureCoordinates");271tcoords->SetNumberOfComponents(2);272tcoords->SetNumberOfTuples(total);273274int pos = 0;275for (int y = 0; y < mask.rows; ++y)276{277const Vec2* srow = _tcoords.ptr<Vec2>(y);278const Vec2* send = srow + _tcoords.cols;279const _Msk* mrow = mask.ptr<_Msk>(y);280281for (; srow != send; ++srow, mrow += mask.channels())282if (!isNan(mrow))283tcoords->SetTuple(pos++, srow->val);284}285}286287288