Save snapshot without metadata as a jpeg

I know this question has been posted multiple times however I’ve seemed to run into a different issue.

My application requires a snapshot at a certain time interval, I’m able to save frames as a jpeg but it gets saved as a grayscale image instead of rgb. This is roughly my save snapshot method. Is it an opencv error on my part or am I missing something? Thanks in advance.

void saveSnapshot() {
GstBuffer *inbuf = GST_PAD_PROBE_INFO_BUFFER(info);
        GstMapInfo in_map_info;
        NvBufSurface *surface = NULL;
        memset(&in_map_info, 0, sizeof(in_map_info));
        if (!gst_buffer_map(inbuf, &in_map_info, GST_MAP_READ)) {
            g_error("Error: Failed to map gst buffer\n");
            gst_buffer_unmap (inbuf, &in_map_info);
            return;
        }

        NvDsBatchMeta *batch_meta = gst_buffer_get_nvds_batch_meta (inbuf);
        NvDsMetaList *l_frame = nullptr;
        
        surface = (NvBufSurface*) in_map_info.data;

        for (l_frame = batch_meta->frame_meta_list; l_frame != NULL; l_frame = l_frame->next) {
            NvDsFrameMeta *frame_meta = (NvDsFrameMeta *) (l_frame->data);
            int queue_number = frame_meta->pad_index;
            if (surface->surfaceList[frame_meta->batch_id].mappedAddr.addr[0] == NULL) {
                if (NvBufSurfaceMap(surface, frame_meta->batch_id, 0, NVBUF_MAP_READ_WRITE) != 0) {
                    g_error("Buffer map to be accessed by CPU failed\n");
                }
            }

            /* Cache the mapped data for CPU access */
            NvBufSurfaceColorFormat color_format = surface->surfaceList[frame_meta->batch_id].colorFormat;
            if (color_format == NVBUF_COLOR_FORMAT_NV12) {
                LOG(INFO) << "Color format is nv12";
            }

            NvBufSurfaceSyncForCpu(surface, frame_meta->batch_id, 0);
            cv::Mat in_mat = cv::Mat(surface->surfaceList[frame_meta->batch_id].planeParams.height[0],
                        surface->surfaceList[frame_meta->batch_id].planeParams.width[0], 
                        CV_8UC4,
                        surface->surfaceList[frame_meta->batch_id].mappedAddr.addr[0],
                        surface->surfaceList[frame_meta->batch_id].planeParams.pitch[0]);
            cv::Mat bgr_frame = cv::Mat(cv::Size(surface->surfaceList[frame_meta->batch_id].planeParams.height[0], surface->surfaceList[frame_meta->batch_id].planeParams.width[0]), CV_8UC3);

            cv::cvtColor(in_mat, bgr_frame, cv::COLOR_RGBA2BGR);
            std::string file_name = “test" + ".jpg";
            cv::imwrite(file_name, bgr_frame);
        }
        gst_buffer_unmap(inbuf, &in_map_info);
}

• Hardware Platform (Jetson / GPU) dGPU
• DeepStream Version 6.0.1
• JetPack Version (valid for Jetson only)
• TensorRT Version
• NVIDIA GPU Driver Version (valid for GPU only) 470.63
• Issue Type( questions, new requirements, bugs)
• How to reproduce the issue ? (This is for bugs. Including which sample app is using, the configuration files content, the command line used and other details for reproducing)
• Requirement details( This is for new requirement. Including the module name-for which plugin or for which sample application, the function description)

here are some samples:Help,dump image from nvv4l2decoder problem
Dump jpeg in deepstream5.0

@fanzh gosh thank you for the above links. Made an error in my color conversion, I didn’t understand the nv12 image format correctly. The snippet below works perfectly for me.

Another question, I’m converting it to opencv just to make use of cv::imwrite which is convenient however my application doesn’t depend on opencv, it there an alternate, more efficient way like using a Gstreamer plugin to directly create a jpeg event? Any links or suggestions would be nice. Thanks again.

cv::Mat in_mat = cv::Mat(surface->surfaceList[frame_meta->batch_id].planeParams.height[0] * 3/2,
                        surface->surfaceList[frame_meta->batch_id].planeParams.width[0],
                        CV_8UC1,
                        surface->surfaceList[frame_meta->batch_id].mappedAddr.addr[0],
                        surface->surfaceList[frame_meta->batch_id].planeParams.pitch[0]);
            cv::Mat bgr_frame = cv::Mat(cv::Size(surface->surfaceList[frame_meta->batch_id].planeParams.height[0], surface->surfaceList[frame_meta->batch_id].planeParams.width[0]), CV_8UC1);
            cv::cvtColor(in_mat, bgr_frame, cv::COLOR_YUV2BGRA_NV12);

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