| 179 | } |
| 180 | |
| 181 | nvcv::Tensor CreateTensor(int numImages, int imgWidth, int imgHeight, const nvcv::ImageFormat &imgFormat) |
| 182 | { |
| 183 | //semi planar 420 NV12/21 format |
| 184 | if (imgFormat == NVCV_IMAGE_FORMAT_NV12 || imgFormat == NVCV_IMAGE_FORMAT_NV12_ER |
| 185 | || imgFormat == NVCV_IMAGE_FORMAT_NV21 || imgFormat == NVCV_IMAGE_FORMAT_NV21_ER) |
| 186 | { |
| 187 | // Width and height must be a multiple of 2 (i.e., even). |
| 188 | if (imgHeight % 2 != 0 || imgWidth % 2 != 0) |
| 189 | { |
| 190 | throw nvcv::Exception(nvcv::Status::ERROR_INVALID_ARGUMENT, |
| 191 | "Invalid height or width: height and width need to be a " |
| 192 | "multiple of 2 for planar and semi-planar YUV420 formats."); |
| 193 | } |
| 194 | |
| 195 | // Tensor height is 3/2 times the image height to accommodate the half-height chroma planes. |
| 196 | int height420 = (imgHeight * 3) / 2; |
| 197 | |
| 198 | if (numImages == 1) |
| 199 | { |
| 200 | return nvcv::Tensor( |
| 201 | { |
| 202 | {height420, imgWidth, 1}, |
| 203 | "HWC" |
| 204 | }, |
| 205 | imgFormat.planeDataType(0).channelType(0)); |
| 206 | } |
| 207 | else |
| 208 | { |
| 209 | // Note this tensor is being passed an YUV8 format, but the tensor is actually YUV420 however the tensor |
| 210 | // class does not yet understand semi planar formats such as NV12/21 hence we just create an Y8 tensor with |
| 211 | // modified height. |
| 212 | return nvcv::Tensor(numImages, {imgWidth, height420}, nvcv::ImageFormat(NVCV_IMAGE_FORMAT_Y8)); |
| 213 | } |
| 214 | } |
| 215 | else if (imgFormat == NVCV_IMAGE_FORMAT_UYVY || imgFormat == NVCV_IMAGE_FORMAT_UYVY_ER |
| 216 | || imgFormat == NVCV_IMAGE_FORMAT_YUYV || imgFormat == NVCV_IMAGE_FORMAT_YUYV_ER) |
| 217 | { |
| 218 | if (imgWidth % 2 != 0) |
| 219 | { |
| 220 | throw nvcv::Exception(nvcv::Status::ERROR_INVALID_ARGUMENT, |
| 221 | "Invalid width: width needs to be a multiple of 2 for interleaved YUV422 formats."); |
| 222 | } |
| 223 | |
| 224 | int wdth422 = 2 * imgWidth; // Tensor width is 2x the image width to accomodate two chromaticity values for |
| 225 | // each group of two luma values (UYVY or YUYV). |
| 226 | // clang-format off |
| 227 | nvcv::DataType type = imgFormat.planeDataType(0).channelType(0); |
| 228 | nvcv::TensorShape shape = numImages > 1 ? nvcv::TensorShape({numImages, imgHeight, wdth422, 1}, "NHWC") |
| 229 | : nvcv::TensorShape( {imgHeight, wdth422, 1}, "HWC"); |
| 230 | |
| 231 | return nvcv::Tensor(shape, type); |
| 232 | // clang-format on |
| 233 | } |
| 234 | if (numImages == 1) |
| 235 | { |
| 236 | int numChannels = imgFormat.numPlanes() == 1 ? imgFormat.planeNumChannels(0) : imgFormat.numPlanes(); |
| 237 | |
| 238 | if (imgFormat.numPlanes() > 1) |