| 292 | } |
| 293 | |
| 294 | void GetImageByteVectorFromTensor(const TensorData &tensorData, int sample, std::vector<nvcv::Byte> &outData) |
| 295 | { |
| 296 | Optional<TensorDataAccessStridedImage> tDataAc = nvcv::TensorDataAccessStridedImage::Create(tensorData); |
| 297 | |
| 298 | if (!tDataAc) |
| 299 | throw std::runtime_error("Tensor Data not compatible with pitch access."); |
| 300 | if (tDataAc->infoLayout().isChannelFirst()) |
| 301 | return GetImageByteVectorFromTensorPlanar(tensorData, sample, outData); |
| 302 | |
| 303 | if (tDataAc->numSamples() <= sample || sample < 0) |
| 304 | throw std::runtime_error("Number of samples smaller than requested sample."); |
| 305 | |
| 306 | int bytesPerPixel = (tDataAc->dtype().bitsPerPixel() / 8) * tDataAc->numChannels(); |
| 307 | int outputSizeBytes = tDataAc->numRows() * tDataAc->numCols() * bytesPerPixel; |
| 308 | |
| 309 | // Make sure we have the right size. |
| 310 | outData.resize(outputSizeBytes); |
| 311 | |
| 312 | if (cudaSuccess |
| 313 | != cudaMemcpy2D(outData.data(), tDataAc->numCols() * bytesPerPixel, tDataAc->sampleData(sample), |
| 314 | tDataAc->rowStride(), tDataAc->numCols() * bytesPerPixel, tDataAc->numRows(), |
| 315 | cudaMemcpyDeviceToHost)) |
| 316 | { |
| 317 | throw std::runtime_error("CudaMemcpy failed"); |
| 318 | } |
| 319 | return; |
| 320 | } |
| 321 | |
| 322 | static void SetImageTensorFromByteVectorPlanar(const TensorData &tensorData, std::vector<nvcv::Byte> &data, int sample) |
| 323 | { |