Segmentation fault on plotting rectangle on image

Please provide complete information as applicable to your setup.

**• Hardware Platform (Jetson / GPU)**Orin Nano
• DeepStream Version 6.3
**• JetPack Version (valid for Jetson only)**5.1.3
I’m trying to plot rectangle on gst-dsexample plugin.
I have segmentation fault when cv::rectangle api is applied.
When segmentation fault happened for that API?

The whole code is as follows.

static GstFlowReturn
get_converted_mat (GstDsExample * dsexample, NvBufSurface *input_buf, NvOSD_RectParams * crop_rect_params, gint idx, vector<NvOSD_RectParams> &objects, gdouble & ratio, gdouble & ratio_w, gdouble & ratio_h)
{
  NvBufSurfTransform_Error err;
  NvBufSurfTransformConfigParams transform_config_params;
  NvBufSurfTransformParams transform_params;
  NvBufSurfTransformRect src_rect;
  NvBufSurfTransformRect dst_rect;
  NvBufSurface ip_surf;
#ifdef WITH_OPENCV
  cv::Mat in_mat;
#endif
  ip_surf = *input_buf;

  ip_surf.numFilled = ip_surf.batchSize = 1;
  ip_surf.surfaceList = &(input_buf->surfaceList[idx]);
  //file name
  std::time_t rawtime;
  std::tm* timeinfo;
  char buffer [80];
  std::time(&rawtime);
  timeinfo = std::localtime(&rawtime);
  std::strftime(buffer, 80, "%d%m%Y_%H%M_bishan_", timeinfo); 
  cnt++;
  std::stringstream stream;
  stream << cnt;
  std::string str;
  stream >> str;
  str = str+".jpg";  
  strcat(buffer, str.c_str()); 
                  
  gint src_left = GST_ROUND_UP_2((unsigned int)crop_rect_params->left);
  gint src_top = GST_ROUND_UP_2((unsigned int)crop_rect_params->top);
  gint src_width = GST_ROUND_DOWN_2((unsigned int)crop_rect_params->width);
  gint src_height = GST_ROUND_DOWN_2((unsigned int)crop_rect_params->height);
  
  double hdest = dsexample->processing_width * src_height / (double) src_width;
  double wdest = dsexample->processing_height * src_width / (double) src_height;
  guint dest_width, dest_height;

  if (hdest <= dsexample->processing_height) {
    dest_width = dsexample->processing_width;
    dest_height = hdest;
  } else {
    dest_width = wdest;
    dest_height = dsexample->processing_height;
  }
  
  transform_config_params.compute_mode = NvBufSurfTransformCompute_Default;
  transform_config_params.gpu_id = dsexample->gpu_id;
  transform_config_params.cuda_stream = dsexample->cuda_stream;

  err = NvBufSurfTransformSetSessionParams (&transform_config_params);
  if (err != NvBufSurfTransformError_Success) {
    GST_ELEMENT_ERROR (dsexample, STREAM, FAILED, ("NvBufSurfTransformSetSessionParams failed with error %d", err), (NULL));
    goto error;
  }

  ratio = MIN (1.0 * dest_width/ src_width, 1.0 * dest_height / src_height);

  if ((crop_rect_params->width == 0) || (crop_rect_params->height == 0)) {
    GST_ELEMENT_ERROR (dsexample, STREAM, FAILED, ("%s:crop_rect_params dimensions are zero",__func__), (NULL));
    goto error;
  }

#ifdef __aarch64__
  if (ratio <= 1.0 / 16 || ratio >= 16.0) {
    goto error;
  }
#endif
  src_rect = {(guint)src_top, (guint)src_left, (guint)src_width, (guint)src_height};
  dst_rect = {0, 0, (guint)dest_width, (guint)dest_height};
  /* Set the transform parameters */
  transform_params.src_rect = &src_rect;
  transform_params.dst_rect = &dst_rect;
  transform_params.transform_flag = NVBUFSURF_TRANSFORM_FILTER | NVBUFSURF_TRANSFORM_CROP_SRC | NVBUFSURF_TRANSFORM_CROP_DST;
  transform_params.transform_filter = NvBufSurfTransformInter_Default;

  /* Memset the memory */
  NvBufSurfaceMemSet (dsexample->inter_buf, 0, 0, 0);

  GST_DEBUG_OBJECT (dsexample, "Scaling and converting input buffer\n");

  /* Transformation scaling+format conversion if any. */
  err = NvBufSurfTransform (&ip_surf, dsexample->inter_buf, &transform_params);
  if (err != NvBufSurfTransformError_Success) {
    GST_ELEMENT_ERROR (dsexample, STREAM, FAILED, ("NvBufSurfTransform failed with error %d while converting buffer", err), (NULL));
    goto error;
  }
  /* Map the buffer so that it can be accessed by CPU */
  if (NvBufSurfaceMap (dsexample->inter_buf, 0, 0, NVBUF_MAP_READ) != 0){
    goto error;
  }
  if(dsexample->inter_buf->memType == NVBUF_MEM_SURFACE_ARRAY) {
    /* Cache the mapped data for CPU access */
    NvBufSurfaceSyncForCpu (dsexample->inter_buf, 0, 0);
  }

#ifdef WITH_OPENCV
  /* Use openCV to remove padding and convert RGBA to BGR. Can be skipped if
   * algorithm can handle padded RGBA data. */
  in_mat =
      cv::Mat (dsexample->processing_height, dsexample->processing_width,
      CV_8UC4, dsexample->inter_buf->surfaceList[0].mappedAddr.addr[0],
      dsexample->inter_buf->surfaceList[0].pitch);

#if (CV_MAJOR_VERSION >= 4)
  cv::cvtColor (in_mat, *dsexample->cvmat, cv::COLOR_RGBA2BGR);
#else
  cv::cvtColor (in_mat, *dsexample->cvmat, CV_RGBA2BGR);
#endif
#endif
   
   for(int obj_id=0; obj_id < objects.size(); obj_id++){
      //gint obj_left = GST_ROUND_UP_2((unsigned int)objects[obj_id].left);
      //gint obj_top = GST_ROUND_UP_2((unsigned int)objects[obj_id].top);
      //gint obj_right = obj_left + GST_ROUND_DOWN_2((unsigned int)objects[obj_id].width);
      //gint obj_bottom = obj_top + GST_ROUND_DOWN_2((unsigned int)objects[obj_id].height);      
      cv::Point p1(10, 10); 
      cv::Point p2(100, 100); 
      cv::rectangle(in_mat, p1, p2, cv::Scalar(0, 0, 255), 3, cv::LINE_8);
   }
   cv::imwrite(buffer, in_mat); 
   if (NvBufSurfaceUnMap (dsexample->inter_buf, 0, 0)){
      goto error;
   }

/*  if(dsexample->is_integrated) {
#ifdef __aarch64__
    
    if (USE_EGLIMAGE) {
      if (NvBufSurfaceMapEglImage (dsexample->inter_buf, 0) !=0 ) {
        goto error;
      }
      NvBufSurfaceUnMapEglImage (dsexample->inter_buf, 0);
    }
#endif
  }
*/ 
  return GST_FLOW_OK;

error:
  return GST_FLOW_ERROR;
}

Could you refer to our source code in gstdsexample.cpp?

/* rectangle for cropped objects */
  crop_rect = cv::Rect (crop_rect_params->left, crop_rect_params->top,
  crop_rect_params->width, crop_rect_params->height);

That is cropping rectangle. I am plotting a rectangle on image using opencv’s api cv::rectangle

If you just want to draw the rectangle on the image, you don’t have to use the opencv or gstexample plugin. You can just use a probe function and set some parameters to our NvDsDisplayMeta like deepstream-test1.

Ok let me check. Thanks

My main intention is I like to plot rectangle on the saved image.
I have earlier posts like plotting bounding box on saved image, in which I tried to shift the position of gst-dsexample plugin to after osd plugin. But doesn’t succeed.
@ rajupadhyay59 suggested me to plot using opencv.
So I tried to plot rectangle using opencv and have faced another issue like Segmentation fault on plotting rectangle on image. Then you suggested me to use NvDsDisplayMeta.
My dificulty is to plot rectangle on the saved image.

This is my code in gst-dsexample to save image in gst_dsexample_transform_ip function.

for (l_obj = frame_meta->obj_meta_list; l_obj != NULL; l_obj = l_obj->next) {
              obj_meta = (NvDsObjectMeta *) (l_obj->data);
              if (obj_meta->class_id == PGIE_CLASS_ID_NOHELMET) {
                  found_nohelmet = true;
                  //objects.push_back(obj_meta->rect_params); 
                   NvDsObjEncUsrArgs frameData = { 0 };
		   frameData.isFrame = 1;
		   frameData.saveImg = true;
		   frameData.attachUsrMeta = false;
		   frameData.scaleImg = FALSE;
		   
		   std::time_t rawtime;
                  std::tm* timeinfo;
                  char buffer [80];
                  std::time(&rawtime);
                  timeinfo = std::localtime(&rawtime);
                  std::strftime(buffer, 80, "%d%m%Y_%H%M_bishan_", timeinfo); 
                  cnt++;
                  std::stringstream stream;
                  stream << cnt;
                  std::string str;
                  stream >> str;
                  str = str+".jpg";                 
                  strcpy(frameData.fileNameImg, buffer ); 
                  strcat(frameData.fileNameImg, str.c_str());
		   frameData.scaledWidth = 0;
		   frameData.scaledHeight = 0;
		   frameData.quality = 80;
	           nvds_obj_enc_process (dsexample->obj_ctx_handle, &frameData, surface, NULL, frame_meta);
	           queue.push(data_(frameData.fileNameImg, rawtime, obj_meta->object_id),  frame_meta->source_id);
              }
          }

The nvdsosd plugin draws the rectangle to the image. Is your dsexample plugin after the nvdsosd plugin in your pipeline?
There are many ways to draw the rectangle on the image. But if you don’t use the opencv to draw that by yourself, you need to save the image after the nvdsosd plugin.

No. I still not succeed putting gst-dsexample after osd plug-in.
Any sample for that? I tried but didn’t work.
Thanks

Could you refer to this topic 279003? I have provided a source code for saving images with Bboxes. Please customize your own needs based on this.

Ok thanks. Let me check. Thanks for the sample.