Problems about image resolution

**• Hardware Platform (Jetson / GPU)**Jetson
• DeepStream Version6.1.1

Dear all,I am trying to apply edgedetection to detected object of each frame.Here is my codes:

static GstPadProbeReturn
gie_processing_done_buf_prob (GstPad * pad, GstPadProbeInfo * info,
    gpointer u_data)
{
  GstBuffer *buf = (GstBuffer *) info->data;
  NvDsInstanceBin *bin = (NvDsInstanceBin *) u_data;
  guint index = bin->index;
  AppCtx *appCtx = bin->appCtx;
  //extra  
  NvDsBatchMeta *batch_meta = gst_buffer_get_nvds_batch_meta(buf);
  // Get original raw data
  GstMapInfo in_map_info;
  g_mutex_lock(&buffer_lock);
  gst_buffer_map (buf, &in_map_info, GST_MAP_READ);
  NvBufSurface *surface = (NvBufSurface *)in_map_info.data;
  for (NvDsMetaList * l_frame = batch_meta->frame_meta_list; l_frame != NULL;
          l_frame = l_frame->next) {
          NvDsFrameMeta *frame_meta = l_frame->data;
          //TODO for cuda device memory we need to use cudamemcpy
          NvBufSurfaceMap (surface, -1, -1, NVBUF_MAP_READ);
          /* Cache the mapped data for CPU access */
          NvBufSurfaceSyncForCpu (surface, 0, 0); //will do nothing for unified memory type on dGPU
          guint height = surface->surfaceList[frame_meta->batch_id].height;
          guint width = surface->surfaceList[frame_meta->batch_id].width;
          float angle;
          edgedetection(height,width,surface,frame_meta,angle);
          }
  NvBufSurfaceUnMap(surface,0,0);
  gst_buffer_unmap (buf, &in_map_info);
  g_mutex_unlock(&buffer_lock);
  if (gst_buffer_is_writable (buf))
    process_buffer (buf, appCtx, index);
  return GST_PAD_PROBE_OK;
}

For edgedetection function,it is defined in another cpp file:

//custom function
void edgedetection(guint height,guint width,NvBufSurface *surface,NvDsFrameMeta *frame_meta,float angle){
  Mat nv12_mat = Mat(height*3/2, width, CV_8UC1, surface->surfaceList[frame_meta->batch_id].mappedAddr.addr[0],
  surface->surfaceList[frame_meta->batch_id].pitch);
  for (NvDsMetaList * l_obj = frame_meta->obj_meta_list; l_obj != NULL;
  l_obj = l_obj->next) {
    NvDsObjectMeta *obj = (NvDsObjectMeta *) l_obj->data;
    
    Rect bbox(obj->rect_params.left, obj->rect_params.top,
                obj->rect_params.width, obj->rect_params.height);
    Mat imgray;
    cvtColor(nv12_mat, imgray, COLOR_YUV2GRAY_NV12);

  // 确保 bbox 的宽度和高度是有效的
  if (bbox.width > 0 && bbox.height > 0) {
    Mat roi = imgray(bbox);

    Mat edges;
    Canny(roi, edges, 100, 200,3);

    Mat thresh;
    threshold(edges, thresh, 127, 255, THRESH_BINARY);
 
    std::vector<std::vector<Point>> contours;
    std::vector<Vec4i> hierarchy;
    findContours(thresh, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

    bool found_ellipse=false;
    for (const auto& cnt : contours) {
        if (cnt.size() > 100) {
            RotatedRect ellipse_rect=fitEllipse(cnt);
           }
            angle=ellipse_rect.angle;
            cout << "角度是: " << std::fixed<<std::setprecision(2)<<angle <<endl;
            break;
        }
    }
    obj->misc_obj_info[0]=angle;
  }
}

Besides,in order to see the angle on the screen,I print it on the text in process_meta() function:

//add angle
      float angle=obj->misc_obj_info[0];
      sprintf (str_ins_pos, ",%.2f",angle);
      str_ins_pos += strlen (str_ins_pos);

Thats’s all,my problem is,I can’t get the really angle of detected object when I apply edgedetection.

I suspect that it may be image resolution problem.I mean that:

    Rect bbox(obj->rect_params.left, obj->rect_params.top,
                obj->rect_params.width, obj->rect_params.height);

What is the rect_params’s resolution based on?I mean the parameters like width and height must depend on some exact resolution.

When I get the raw images:

Mat nv12_mat = Mat(height*3/2, width, CV_8UC1, surface->surfaceList[frame_meta->batch_id].mappedAddr.addr[0],
  surface->surfaceList[frame_meta->batch_id].pitch);

So, is the resolution of nv12_mat same as rect_params?
And if it’s not resolution problem,anything else may result in this?

Since you are using OpenCV, you can try to draw the rect_params on your nv12_mat and save the image using OpenCV. This can directly confirm whether the bbox and image are correct from the image you saved.

Thanks,but I may not get your point.
Since I am using the deepstream_app sample,the parameters in NvDsObjectlist like rect_params are already integrated if I am not mistaken.So there may not be space for me to manipulate the rect_params .

Besides,I even tried some videos like;


As you can see,I use some pictures to make the video with one picture displaying some seconds.

And I don’t apply ROI in order to test, but I still get the wrong angle as you can see:-1 on the screen.

I have test the pictures appearing on this video in a simple cpp program,and there should be angle displaying.
So it makes me doubt that if I really get the raw images of the input video?

That’s what I wanted you to confirm before. Just use the API of OpenCV like cv::imwrite to save the image of nv12_mat you used. You can also learn how to use the OpenCV API to draw the bbox with our rect_params parameters.

Hi,I have check the codes you provide before,do you mean this part?

#if 0
        cv::Mat rgba_mat, frame;
	frame = cv::Mat(height * 3 / 2, width, CV_8UC1, tmp_buffer, in_surf->surfaceList[frame_meta->batch_id].pitch);
        cv::cvtColor(frame, rgba_mat, cv::COLOR_YUV2BGRA_NV12);
	cv::imwrite("frame_10.jpg", rgba_mat);

Hi,I have add this line:
cv::imwrite("nv12mat.jpg", nv12_mat);The result:


The video seems to stop at this frame and the pipeline stops also.And the picture I save seems to be broken.

Besides,i also try another video,if I don’t add that line:


If I add,the saved image of nv12_mat is:

At the same time,the pipeline also crashes.

Hi,I’m here to bring good news.Thanks for telling to pay attention to the image format,I print:
surface->surfaceList[frame_meta->batch_id].colorFormat
It gives a numble 19,namely the RGBA format according to my check.
So,here the mat nv12_mat should be RGBA_mat:

Mat RGBA_mat = Mat(height, width, CV_8UC4, surface->surfaceList[frame_meta->batch_id].mappedAddr.addr[0],
  surface->surfaceList[frame_meta->batch_id].pitch);

Now,it works fine!Thank you!

Glad to hear that!

Hi,sorry to bother,I am using a USB camera to apply object detection.No long time before I create the RGBA image, can I also create the depth image?

Please file a new topic for the new issue. Thanks

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