From 55bc72a569e37ae029bf87a08ea479e960d2088c Mon Sep 17 00:00:00 2001 From: Matthias Vogelgesang Date: Wed, 30 May 2012 11:36:12 +0200 Subject: Rework setting of ROI Unfortunately, setting the binning does not yet work because it is only possible to set this parameter before initializing the frame grabber. --- src/cameras/uca-pco-camera.c | 136 ++++++++++++++++++------------------------- 1 file changed, 57 insertions(+), 79 deletions(-) (limited to 'src/cameras/uca-pco-camera.c') diff --git a/src/cameras/uca-pco-camera.c b/src/cameras/uca-pco-camera.c index 852a4f9..dfc29e4 100644 --- a/src/cameras/uca-pco-camera.c +++ b/src/cameras/uca-pco-camera.c @@ -139,6 +139,9 @@ struct _UcaPcoCameraPrivate { guint16 width, height; guint16 width_ex, height_ex; + guint16 binning_h, binning_v; + guint16 roi_x, roi_y; + guint16 roi_width, roi_height; GValueArray *horizontal_binnings; GValueArray *vertical_binnings; GValueArray *pixelrates; @@ -331,9 +334,17 @@ UcaPcoCamera *uca_pco_camera_new(GError **error) priv->pco = pco; pco_get_resolution(priv->pco, &priv->width, &priv->height, &priv->width_ex, &priv->height_ex); + pco_get_binning(priv->pco, &priv->binning_h, &priv->binning_v); pco_set_storage_mode(pco, STORAGE_MODE_RECORDER); pco_set_auto_transfer(pco, 1); + guint16 roi[4]; + pco_get_roi(priv->pco, roi); + priv->roi_x = roi[0] - 1; + priv->roi_y = roi[1] - 1; + priv->roi_width = roi[2] - roi[0] + 1; + priv->roi_height = roi[3] - roi[1] + 1; + guint16 camera_type, camera_subtype; pco_get_camera_type(priv->pco, &camera_type, &camera_subtype); pco_cl_map_entry *map_entry = get_pco_cl_map_entry(camera_type); @@ -386,19 +397,35 @@ static void uca_pco_camera_start_recording(UcaCamera *camera, GError **error) UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera); + guint16 binned_width = priv->width / priv->binning_h; + guint16 binned_height = priv->height / priv->binning_v; + + if ((priv->roi_x + priv->roi_width > binned_width) || (priv->roi_y + priv->roi_height > binned_height)) { + g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_UNSUPPORTED, + "ROI of size %ix%i @ (%i, %i) is outside of (binned) sensor size %ix%i\n", + priv->roi_width, priv->roi_height, priv->roi_x, priv->roi_y, binned_width, binned_height); + return; + } + /* - * Get the actual size of the frame that we are going to grab based on the - * currently selected region of interest. This size is fixed until recording - * has stopped. + * All parameters are valid. Now, set them on the camera. */ - guint16 roi[4] = {0}; - err = pco_get_roi(priv->pco, roi); - guint frame_width = roi[2] - roi[0] + 1; - guint frame_height = roi[3] - roi[1] + 1; - - if (priv->frame_width != frame_width || priv->frame_height != frame_height || priv->fg_mem == NULL) { - priv->frame_width = frame_width; - priv->frame_height = frame_height; + guint16 roi[4] = { priv->roi_x + 1, priv->roi_y + 1, priv->roi_x + priv->roi_width, priv->roi_y + priv->roi_height }; + pco_set_roi(priv->pco, roi); + + /* + * FIXME: We cannot set the binning here as this breaks communication with + * the camera. Setting the binning works _before_ initializing the frame + * grabber though. However, it is rather inconvenient to initialize and + * de-initialize the frame grabber for each recording sequence. + */ + + /* if (pco_set_binning(priv->pco, priv->binning_h, priv->binning_v) != PCO_NOERROR) */ + /* g_warning("Cannot set binning\n"); */ + + if (priv->frame_width != priv->roi_width || priv->frame_height != priv->roi_height || priv->fg_mem == NULL) { + priv->frame_width = priv->roi_width; + priv->frame_height = priv->roi_height; priv->num_bytes = 2; Fg_setParameter(priv->fg, FG_WIDTH, &priv->frame_width, priv->fg_port); @@ -448,7 +475,7 @@ static void uca_pco_camera_stop_recording(UcaCamera *camera, GError **error) err = Fg_setStatusEx(priv->fg, FG_UNBLOCK_ALL, 0, priv->fg_port, priv->fg_mem); if (err == FG_INVALID_PARAMETER) - g_print(" Unable to unblock all\n"); + g_warning(" Unable to unblock all\n"); } static void uca_pco_camera_start_readout(UcaCamera *camera, GError **error) @@ -541,50 +568,27 @@ static void uca_pco_camera_set_property(GObject *object, guint property_id, cons break; case PROP_ROI_X: - { - guint16 roi[4] = {0}; - pco_get_roi(priv->pco, roi); - - /* - * According to PCO specs, the image starts coordinates (1,1) - * rather than (0,0). Therefore we adjust the coordinates here. - */ - roi[0] = g_value_get_uint(value) + 1; - - if (pco_set_roi(priv->pco, roi) != PCO_NOERROR) - g_warning("Cannot set horizontal ROI position"); - } + priv->roi_x = g_value_get_uint(value); break; case PROP_ROI_Y: - { - guint16 roi[4] = {0}; - pco_get_roi(priv->pco, roi); - roi[1] = g_value_get_uint(value) + 1; - - if (pco_set_roi(priv->pco, roi) != PCO_NOERROR) - g_warning("Cannot set vertical ROI position"); - } + priv->roi_y = g_value_get_uint(value); break; case PROP_ROI_WIDTH: - { - guint16 roi[4] = {0}; - pco_get_roi(priv->pco, roi); - roi[2] = roi[0] + g_value_get_uint(value) - 1; - if (pco_set_roi(priv->pco, roi) != PCO_NOERROR) - g_warning("Cannot set ROI width"); - } + priv->roi_width = g_value_get_uint(value); break; case PROP_ROI_HEIGHT: - { - guint16 roi[4] = {0}; - pco_get_roi(priv->pco, roi); - roi[3] = roi[1] + g_value_get_uint(value) - 1; - if (pco_set_roi(priv->pco, roi) != PCO_NOERROR) - g_warning("Cannot set ROI height"); - } + priv->roi_height = g_value_get_uint(value); + break; + + case PROP_SENSOR_HORIZONTAL_BINNING: + priv->binning_h = g_value_get_uint(value); + break; + + case PROP_SENSOR_VERTICAL_BINNING: + priv->binning_v = g_value_get_uint(value); break; case PROP_EXPOSURE_TIME: @@ -776,12 +780,7 @@ static void uca_pco_camera_get_property(GObject *object, guint property_id, GVal break; case PROP_SENSOR_HORIZONTAL_BINNING: - { - uint16_t h, v; - /* TODO: check error */ - pco_get_binning(priv->pco, &h, &v); - g_value_set_uint(value, h); - } + g_value_set_uint(value, priv->binning_h); break; case PROP_SENSOR_HORIZONTAL_BINNINGS: @@ -789,12 +788,7 @@ static void uca_pco_camera_get_property(GObject *object, guint property_id, GVal break; case PROP_SENSOR_VERTICAL_BINNING: - { - uint16_t h, v; - /* TODO: check error */ - pco_get_binning(priv->pco, &h, &v); - g_value_set_uint(value, v); - } + g_value_set_uint(value, priv->binning_v); break; case PROP_SENSOR_VERTICAL_BINNINGS: @@ -945,35 +939,19 @@ static void uca_pco_camera_get_property(GObject *object, guint property_id, GVal break; case PROP_ROI_X: - { - guint16 roi[4] = {0}; - pco_get_roi(priv->pco, roi); - g_value_set_uint(value, roi[0] - 1); - } + g_value_set_uint(value, priv->roi_x); break; case PROP_ROI_Y: - { - guint16 roi[4] = {0}; - pco_get_roi(priv->pco, roi); - g_value_set_uint(value, roi[1] - 1); - } + g_value_set_uint(value, priv->roi_y); break; case PROP_ROI_WIDTH: - { - guint16 roi[4] = {0}; - pco_get_roi(priv->pco, roi); - g_value_set_uint(value, (roi[2] - roi[0] + 1)); - } + g_value_set_uint(value, priv->roi_width); break; case PROP_ROI_HEIGHT: - { - guint16 roi[4] = {0}; - pco_get_roi(priv->pco, roi); - g_value_set_uint(value, (roi[3] - roi[1] + 1)); - } + g_value_set_uint(value, priv->roi_height); break; case PROP_NAME: -- cgit v1.2.3