How to crop the image and save

Hi,
Please refer to the following sample:

static GstFlowReturn get_converted_mat (GstDsExample * dsexample, NvBufSurface *input_buf, gint idx, NvOSD_RectParams * crop_rect_params, gdouble & ratio, gint input_width, gint input_height) { NvBufSurfTransform_Error err; NvBufSurfTransformConfigParams transform_config_params; NvBufSurfTransformParams transform_params; NvBufSurfTransformRect src_rect; NvBufSurfTransformRect dst_rect; NvBufSurface ip_surf; cv::Mat in_mat, out_mat; ip_surf = *input_buf; ip_surf.numFilled = ip_surf.batchSize = 1; ip_surf.surfaceList = &(input_buf->surfaceList[idx]); gint src_left = GST_ROUND_UP_2(crop_rect_params->left); gint src_top = GST_ROUND_UP_2(crop_rect_params->top); gint src_width = GST_ROUND_DOWN_2(crop_rect_params->width); gint src_height = GST_ROUND_DOWN_2(crop_rect_params->height); //g_print("ltwh = %d %d %d %d \n", src_left, src_top, src_width, src_height); guint dest_width, dest_height; dest_width = src_width; dest_height = src_height; NvBufSurface *nvbuf; NvBufSurfaceCreateParams create_params; create_params.gpuId = dsexample->gpu_id; create_params.width = dest_width; create_params.height = dest_height; create_params.size = 0; create_params.colorFormat = NVBUF_COLOR_FORMAT_RGBA; create_params.layout = NVBUF_LAYOUT_PITCH; #ifdef __aarch64__ create_params.memType = NVBUF_MEM_DEFAULT; #else create_params.memType = NVBUF_MEM_CUDA_UNIFIED; #endif NvBufSurfaceCreate (&nvbuf, 1, &create_params); // Configure transform session parameters for the transformation transform_config_params.compute_mode = NvBufSurfTransformCompute_Default; transform_config_params.gpu_id = dsexample->gpu_id; transform_config_params.cuda_stream = dsexample->cuda_stream; // Set the transform session parameters for the conversions executed in this // thread. err = NvBufSurfTransformSetSessionParams (&transform_config_params); if (err != NvBufSurfTransformError_Success) { GST_ELEMENT_ERROR (dsexample, STREAM, FAILED, ("NvBufSurfTransformSetSessionParams failed with error %d", err), (NULL)); goto error; } // Calculate scaling ratio while maintaining aspect ratio 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) { // Currently cannot scale by ratio > 16 or < 1/16 for Jetson goto error; } #endif // Set the transform ROIs for source and destination 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 (nvbuf, 0, 0, 0); GST_DEBUG_OBJECT (dsexample, "Scaling and converting input buffer\n"); // Transformation scaling+format conversion if any. err = NvBufSurfTransform (&ip_surf, nvbuf, &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 (nvbuf, 0, 0, NVBUF_MAP_READ) != 0){ goto error; } // Cache the mapped data for CPU access NvBufSurfaceSyncForCpu (nvbuf, 0, 0); // Use openCV to remove padding and convert RGBA to BGR. Can be skipped if // algorithm can handle padded RGBA data. in_mat = cv::Mat (dest_height, dest_width, CV_8UC4, nvbuf->surfaceList[0].mappedAddr.addr[0], nvbuf->surfaceList[0].pitch); out_mat = cv::Mat (cv::Size(dest_width, dest_height), CV_8UC3); cv::cvtColor (in_mat, out_mat, CV_RGBA2BGR); static gint dump = 0; if (dump < 150) { char filename[64]; snprintf(filename, 64, "/home/nvidia/image%03d.jpg", dump); cv::imwrite(filename, out_mat); dump++; } if (NvBufSurfaceUnMap (nvbuf, 0, 0)){ goto error; } NvBufSurfaceDestroy(nvbuf); #ifdef __aarch64__ // To use the converted buffer in CUDA, create an EGLImage and then use // CUDA-EGL interop APIs if (USE_EGLIMAGE) { if (NvBufSurfaceMapEglImage (dsexample->inter_buf, 0) !=0 ) { goto error; } // dsexample->inter_buf->surfaceList[0].mappedAddr.eglImage // Use interop APIs cuGraphicsEGLRegisterImage and // cuGraphicsResourceGetMappedEglFrame to access the buffer in CUDA // Destroy the EGLImage NvBufSurfaceUnMapEglImage (dsexample->inter_buf, 0); } #endif /* We will first convert only the Region of Interest (the entire frame or the * object bounding box) to RGB and then scale the converted RGB frame to * processing resolution. */ return GST_FLOW_OK; error: return GST_FLOW_ERROR; } 

It creates a NvBufSurface for each object and saves it to a jpg file.