Hello, I’ve been trying to access the pipeline frames with OpenCV. I was able to get the frames correctly in my dGPU Desktop, but not in Jetson Nano. The error I’m getting is the following:
terminate called after throwing an instance of 'cv::Exception'
what(): OpenCV(4.1.1) /home/dlinano/opencv/modules/core/src/cuda/gpu_mat.cu:249: error: (-217:Gpu API call) invalid argument in function 'download'
Aborted (core dumped)
I tested my OpenCV installation and it is not the problem. I’ve read in this link (Implementing a Custom GStreamer Plugin with OpenCV Integration Example — DeepStream 6.1.1 Release documentation) that “if memory of NvBufSurface
is not in CUDA you must convert it to CUDA through CUDA-EGL interop before accessing it in OpenCV.” But I couldn’t find in the sources/gst-plugins/gst-dsexample/gstdsexample.cpp
how to do that conversion and I’m not sure if this is my problem. If it is, what should I do? If it’s not what is causing this?
This is the sample code that I’m using inside of the osd_sink_pad_buffer_probe
method:
static GstPadProbeReturn osd_sink_pad_buffer_probe (GstPad * pad, GstPadProbeInfo * info, gpointer u_data){
GstBuffer *buf = (GstBuffer *) info->data;
NvDsFrameMeta *frame_meta = NULL;
guint vehicle_count = 0;
guint person_count = 0;
gboolean is_first_object = TRUE;
NvDsMetaList *l_frame, *l_obj;
NvDsBatchMeta *batch_meta = gst_buffer_get_nvds_batch_meta (buf);
if (!batch_meta) {
// No batch meta attached.
return GST_PAD_PROBE_OK;
}
GstMapInfo in_map_info;
NvBufSurface *surface = NULL;
memset (&in_map_info, 0, sizeof (in_map_info));
if (gst_buffer_map (buf, &in_map_info, GST_MAP_READWRITE)) {
surface = (NvBufSurface *) in_map_info.data;
NvBufSurfaceMap(surface, -1, -1, NVBUF_MAP_READ_WRITE);
NvBufSurfaceSyncForCpu(surface, -1, -1);
batch_meta = gst_buffer_get_nvds_batch_meta(buf);
for (l_frame = batch_meta->frame_meta_list; l_frame; l_frame = l_frame->next) {
frame_meta = (NvDsFrameMeta *) l_frame->data;
#ifdef PLATFORM_TEGRA
if (NvBufSurfaceMapEglImage(surface, frame_meta->batch_id) != 0)
cout "ERROR on converting the EGL Buffer.";
#endif
gint frame_width = (gint) surface->surfaceList[frame_meta->batch_id].width;
gint frame_height = (gint) surface->surfaceList[frame_meta->batch_id].height;
cv::cuda::GpuMat frame;
frame = cv::cuda::GpuMat(frame_height, frame_width, CV_8UC4,
(void *) surface->surfaceList[frame_meta->batch_id].dataPtr,
surface->surfaceList[frame_meta->batch_id].pitch);
cv::Mat src_mat_BGRA;
frame.download(src_mat_BGRA);
cv::cvtColor(src_mat_BGRA, src_mat_BGRA, COLOR_RGBA2BGR);
string filename = "cv_frames/frame_" + to_string(frame_number) + ".jpg";
cv::imwrite(filename, src_mat_BGRA);
...
}
As you can see above I tried using this part of the code to resolve the issue, but I’ve got the same error I mentioned above.
#ifdef PLATFORM_TEGRA if (NvBufSurfaceMapEglImage(surface, frame_meta->batch_id) != 0){ cout << "ERROR on converting the EGL Buffer." << endl; } #endif
I’m using a modified version of deepstream-test1-app
with a segmentation model that I’ve trained. Any help would be appreciated. Thanks in advance.