/******************************************************************************* * Copyright (c) 2021 Nerian Vision GmbH * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. *******************************************************************************/ #ifndef VISIONTRANSFER_RECONSTRUCT3D_PCL_H #define VISIONTRANSFER_RECONSTRUCT3D_PCL_H #ifdef PCL_MAJOR_VERSION namespace visiontransfer { /* * PCL-specific implementations that need to be inlined in order to avoid * dependencies for projects that do not make use of PCL */ template typename pcl::PointCloud::Ptr Reconstruct3D::initPointCloud(const ImageSet& imageSet, const char* frameId) { int sec, microsec; imageSet.getTimestamp(sec, microsec); typename pcl::PointCloud::Ptr ret( new pcl::PointCloud(imageSet.getWidth(), imageSet.getHeight())); ret->header.frame_id = frameId; ret->header.seq = imageSet.getSequenceNumber(); ret->header.stamp = sec * 1000000LL + microsec; ret->width = imageSet.getWidth(); ret->height = imageSet.getHeight(); ret->is_dense = true; return ret; } inline pcl::PointCloud::Ptr Reconstruct3D::createXYZCloud(const ImageSet& imageSet, const char* frameId, unsigned short minDisparity) { float* pointMap = createPointMap(imageSet, minDisparity); pcl::PointCloud::Ptr ret = initPointCloud(imageSet, frameId); memcpy(&ret->points[0].x, pointMap, ret->width*ret->height*sizeof(float)*4); return ret; } inline pcl::PointCloud::Ptr Reconstruct3D::createXYZICloud(const ImageSet& imageSet, const char* frameId, unsigned short minDisparity) { float* pointMap = createPointMap(imageSet, minDisparity); pcl::PointCloud::Ptr ret = initPointCloud(imageSet, frameId); pcl::PointXYZI* dstPtr = &ret->points[0]; if(imageSet.getPixelFormat(0) == ImageSet::FORMAT_8_BIT_MONO) { for(int y = 0; y < imageSet.getHeight(); y++) { unsigned char* rowPtr = imageSet.getPixelData(0) + y*imageSet.getRowStride(0); unsigned char* endPtr = rowPtr + imageSet.getWidth(); for(; rowPtr < endPtr; rowPtr++) { dstPtr->intensity = static_cast(*rowPtr)/255.0F; dstPtr->x = *pointMap++; dstPtr->y = *pointMap++; dstPtr->z = *pointMap++; pointMap++; dstPtr++; } } } else if(imageSet.getPixelFormat(0) == ImageSet::FORMAT_12_BIT_MONO) { for(int y = 0; y < imageSet.getHeight(); y++) { unsigned short* rowPtr = reinterpret_cast(imageSet.getPixelData(0) + y*imageSet.getRowStride(0)); unsigned short* endPtr = rowPtr + imageSet.getWidth(); for(; rowPtr < endPtr; rowPtr++) { dstPtr->intensity = static_cast(*rowPtr)/4095.0F; dstPtr->x = *pointMap++; dstPtr->y = *pointMap++; dstPtr->z = *pointMap++; pointMap++; dstPtr++; } } } else { throw std::runtime_error("Left image does not have a valid greyscale format"); } return ret; } inline pcl::PointCloud::Ptr Reconstruct3D::createXYZRGBCloud(const ImageSet& imageSet, const char* frameId, unsigned short minDisparity) { float* pointMap = createPointMap(imageSet, minDisparity); pcl::PointCloud::Ptr ret = initPointCloud(imageSet, frameId); pcl::PointXYZRGB* dstPtr = &ret->points[0]; if(imageSet.getPixelFormat(0) != ImageSet::FORMAT_8_BIT_RGB) { throw std::runtime_error("Left image is not an RGB image"); } for(int y = 0; y < imageSet.getHeight(); y++) { unsigned char* rowPtr = imageSet.getPixelData(0) + y*imageSet.getRowStride(0); unsigned char* endPtr = rowPtr + 3*imageSet.getWidth(); for(; rowPtr < endPtr;rowPtr +=3) { dstPtr->r = rowPtr[0]; dstPtr->g = rowPtr[1]; dstPtr->b = rowPtr[2]; dstPtr->x = *pointMap++; dstPtr->y = *pointMap++; dstPtr->z = *pointMap++; pointMap++; dstPtr++; } } return ret; } } // namespace #endif #endif