Populating NvBuvSurface from cv::Mat in Jetson

Please provide complete information as applicable to your setup.

• Hardware Platform (Jetson / GPU)
Jetson
• DeepStream Version
6.1.1

i’m trying t populate the NvBufSurface surf with the cv::Mat image with this function that basically

  1. creates a NvBufSurface* new_image then

  2. NvBufSurfaceMap (new_image, 0, 0, NVBUF_MAP_READ_WRITE)
    NvBufSurfaceSyncForCpu (new_image, 0, 0)

  3. copy the buffer into new_image with
    memcpy(new_image->surfaceList[0].mappedAddr.addr[0], rgba.ptr(), 112 * 112 * 4);

  4. and then copy the surface new_image to the original surface surf
    NvBufSurfaceCopy(new_image, surf)

but when i try to read back the data from the surf i get this strange disalignment of the pixels
the first row is ok, then the next rows starts to shifts somehome as shown here

this is the code of the function

 void put_surf_image_back3(NvBufSurface *surf, cv::Mat &image, bool use_pitch_alignment) {
        std::cout << "put_surf_image_back3 start" << "\n";

        NvBufSurfTransformParams surf_transform_params = {
                .transform_flag =  NVBUFSURF_TRANSFORM_FILTER,
                .transform_flip = NvBufSurfTransform_None,
                .transform_filter = NvBufSurfTransformInter_Default,
                .src_rect = nullptr,
                .dst_rect = nullptr
        };

        if ((surf == nullptr) || (surf->numFilled <= 0)) {
            std::cerr << "write_surf_bgra_to_disk: surf is nullptr or numFilled is 0" << std::endl;
            return;
        }

        std::cout << "surf->surfaceList[0].width : " << surf->surfaceList[0].width << "\n";
        std::cout << "surf->surfaceList[0].height : " << surf->surfaceList[0].height << "\n";
        std::cout << "surf->surfaceList[0].colorFormat : " << surf->surfaceList[0].colorFormat << "\n";
        std::cout << "surf->numFilled : " << surf->numFilled << "\n";

        NvBufSurface *new_image = nullptr;

        NvBufSurfaceCreateParams nvbufsurface_create_params{
                .gpuId  = surf->gpuId,
                .width  = surf->surfaceList[0].width,
                .height = surf->surfaceList[0].height,
                .size = 0,
                .isContiguous = true,
                .colorFormat = NVBUF_COLOR_FORMAT_RGBA,
                .layout = NVBUF_LAYOUT_PITCH,
                .memType = NVBUF_MEM_DEFAULT
        };

        // we create the new surface new_image
        if (NvBufSurfaceCreate(&new_image, 1, &nvbufsurface_create_params) != 0) {
            std::cerr << "put_surf_image_back: failed to allocate memory" << std::endl;
            return;
        }

        std::cout << "new_image->surfaceList[0].width : " << new_image->surfaceList[0].width << "\n";
        std::cout << "new_image->surfaceList[0].height : " << new_image->surfaceList[0].height << "\n";
        std::cout << "new_image->surfaceList[0].colorFormat : " << new_image->surfaceList[0].colorFormat << "\n";
        std::cout << "new_image->numFilled : " << new_image->numFilled << "\n";

        new_image->numFilled = 1;

        if (NvBufSurfaceMap (new_image, 0, 0, NVBUF_MAP_READ_WRITE) != 0){
            printf("Err in Map\n");
        }
        if (NvBufSurfaceSyncForCpu (new_image, 0, 0) !=0) {
            printf("Err in Synccpu");
        }

        cv::Mat rgba;

        std::cout << "image.size() : " << image.size() << "\n";
        // std::cout << "image.at(0,0) : " << image.at(0,0) << "\n";

        cv::cvtColor(image, rgba, cv::COLOR_BGR2RGBA);

        memcpy(new_image->surfaceList[0].mappedAddr.addr[0], rgba.ptr(), 112 * 112 * 4);

        // Copy the buffers to the allocated memory
        if (NvBufSurfaceCopy(new_image, surf) != 0) {
            std::cerr << "put_surf_image_back: failed to copy buffers" << std::endl;
            NvBufSurfaceDestroy(new_image);
            return;
        }

        std::cout << "new_image->surfaceList[0].width : " << new_image->surfaceList[0].width << "\n";
        std::cout << "new_image->surfaceList[0].height : " << new_image->surfaceList[0].height << "\n";
        std::cout << "new_image->surfaceList[0].colorFormat : " << new_image->surfaceList[0].colorFormat << "\n";
        std::cout << "new_image->numFilled : " << new_image->numFilled << "\n";

        NvBufSurfaceDestroy(new_image);

        std::cout << "put_surf_image_back3 end" << "\n";
    }

and this if the output debug of the function

put_surf_image_back3 start
surf->surfaceList[0].width : 112
surf->surfaceList[0].height : 112
surf->surfaceList[0].colorFormat : 19
surf->numFilled : 1
new_image->surfaceList[0].width : 112
new_image->surfaceList[0].height : 112
new_image->surfaceList[0].colorFormat : 19
new_image->numFilled : 0
image.size() : [112 x 112]
new_image->surfaceList[0].width : 112
new_image->surfaceList[0].height : 112
new_image->surfaceList[0].colorFormat : 19
new_image->numFilled : 1
put_surf_image_back3 end

what i’m missing here?

There is no update from you for a period, assuming this is not an issue anymore. Hence we are closing this topic. If need further support, please open a new one. Thanks

Please check the “memType” in NvBufSurface. NVIDIA DeepStream SDK API Reference: NvBufSurface Struct Reference | NVIDIA Docs

Please check the “pitch” of NVIDIA DeepStream SDK API Reference: NvBufSurfaceParams Struct Reference | NVIDIA Docs

There is a sample of get the read/write buffer from NvBufSurface. DeepStream SDK FAQ - Intelligent Video Analytics / DeepStream SDK - NVIDIA Developer Forums. It is a little complicated for Jetson.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.