diff --git a/opencv-glib/image.cpp b/opencv-glib/image.cpp index 1a9b66e..9d6f1c5 100644 --- a/opencv-glib/image.cpp +++ b/opencv-glib/image.cpp @@ -201,6 +201,291 @@ gcv_drawing_options_new(void) return GCV_DRAWING_OPTIONS(g_object_new(GCV_TYPE_DRAWING_OPTIONS, NULL)); } +/*************************************/ + +typedef struct { + gboolean normalize; +// const Scalar &borderValue=morphologyDefaultBorderValue() +// const Size &dstsize=Size() + gdouble delta; + gdouble psi; + gdouble scale; + gdouble sigma_y; + gint border_type; + gint iterations; + gint ksize; + GCVKType ktype; + //gint ktype; + gint max_level; + GCVPoint *anchor; +// TermCriteria termcrit=TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 5, 1) +} GCVImageFilterOptionsPrivate; + +G_DEFINE_TYPE_WITH_PRIVATE(GCVImageFilterOptions, + gcv_image_filter_options, + G_TYPE_OBJECT) + +#define GCV_IMAGE_FILTER_OPTIONS_GET_PRIVATE(object) \ + static_cast( \ + gcv_image_filter_options_get_instance_private( \ + GCV_IMAGE_FILTER_OPTIONS(object))) + +// TODO +enum { + PROP_NORMALIZE = 1, + PROP_BORDER_VALUE, + PROP_DSTSIZE, + PROP_DELTA, + PROP_PSI, + PROP_SCALE, + PROP_SIGMA_Y, + PROP_BORDER_TYPE, + PROP_ITERATIONS, + PROP_KSIZE, + PROP_KTYPE, + PROP_MAX_LEVEL, + PROP_ANCHOR, +}; + +static void +gcv_image_filter_options_get_property(GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + auto priv = GCV_IMAGE_FILTER_OPTIONS_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_NORMALIZE: + g_value_set_boolean(value, priv->normalize); + break; +/* TODO + case PROP_BORDER_VALUE: + g_value_set_XXX(value, priv->border_value); + break; + case PROP_DSTSIZE: + g_value_set_XXX(value, priv->dstsize); + break; +*/ + case PROP_DELTA: + g_value_set_double(value, priv->delta); + break; + case PROP_PSI: + g_value_set_double(value, priv->psi); + break; + case PROP_SCALE: + g_value_set_double(value, priv->scale); + break; + case PROP_SIGMA_Y: + g_value_set_double(value, priv->sigma_y); + break; + case PROP_BORDER_TYPE: + g_value_set_enum(value, priv->border_type); + break; + case PROP_ITERATIONS: + g_value_set_int(value, priv->iterations); + break; + case PROP_KSIZE: + g_value_set_int(value, priv->ksize); + break; + case PROP_KTYPE: + g_value_set_enum(value, priv->ktype); + break; + case PROP_MAX_LEVEL: + g_value_set_int(value, priv->max_level); + break; + case PROP_ANCHOR: + g_value_set_object(value, priv->anchor); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } + +} + +static void +gcv_image_filter_options_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + auto priv = GCV_IMAGE_FILTER_OPTIONS_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_NORMALIZE: + priv->normalize = g_value_get_boolean(value); + break; +/* TODO + case PROP_BORDER_VALUE: + priv->border_value = g_value_get_XXX(value); + break; + case PROP_DSTSIZE: + priv->dstsize = g_value_get_XXX(value); + break; +*/ + case PROP_DELTA: + priv->delta = g_value_get_double(value); + break; + case PROP_PSI: + priv->psi = g_value_get_double(value); + break; + case PROP_SCALE: + priv->scale = g_value_get_double(value); + break; + case PROP_SIGMA_Y: + priv->sigma_y = g_value_get_double(value); + break; + case PROP_BORDER_TYPE: + priv->border_type = static_cast(g_value_get_enum(value)); + break; + case PROP_ITERATIONS: + priv->iterations = g_value_get_int(value); + break; + case PROP_KSIZE: + priv->ksize = g_value_get_int(value); + break; + case PROP_KTYPE: + priv->ktype = static_cast(g_value_get_enum(value)); + break; + case PROP_MAX_LEVEL: + priv->max_level = g_value_get_int(value); + break; + case PROP_ANCHOR: + { + auto anchor = g_value_get_object(value); + if (priv->anchor && priv->anchor == anchor) { + break; + } + if (priv->anchor) { + g_object_unref(priv->anchor); + } + if (anchor) { + priv->anchor = GCV_POINT(g_object_ref(anchor)); + } else { + priv->anchor = NULL; + } + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + + +static void +gcv_image_filter_options_init(GCVImageFilterOptions *object) +{ +} + +static void +gcv_image_filter_options_class_init(GCVImageFilterOptionsClass *klass) +{ + GParamSpec *spec; + + auto gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->get_property = gcv_image_filter_options_get_property; + gobject_class->set_property = gcv_image_filter_options_set_property; + + spec = g_param_spec_boolean("normalize", + "Normalize", + "normalize", // TODO + FALSE, + static_cast(G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, PROP_NORMALIZE, spec); + + spec = g_param_spec_double("delta", + "Delta", + "added to the filtered pixels before storing them in dst.", + 0, G_MAXDOUBLE, 0, + static_cast(G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, PROP_DELTA, spec); + +/* + spec = g_param_spec_double("psi", + "Psi", + "PSI TODO", + 0, G_MAXDOUBLE, cv::CV_PI * 0.5, + static_cast(G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, PROP_PSI, spec); +*/ + + spec = g_param_spec_double("scale", + "Scale", + "Scale TODO", + 0, G_MAXDOUBLE, 1.0, + static_cast(G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, PROP_SCALE, spec); + + spec = g_param_spec_double("sigmaY", + "Sigma Y", + "sigmaY TODO", + 0, G_MAXDOUBLE, 0.0, + static_cast(G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, PROP_SIGMA_Y, spec); + + spec = g_param_spec_enum("border-type", + "Border type", + "The type of border to be filter", + GCV_TYPE_BORDER_TYPE, + GCV_BORDER_TYPE_BORDER_DEFAULT, + static_cast(G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, PROP_BORDER_TYPE, spec); + + spec = g_param_spec_int("iterations", + "Iterations", + "The number of iterations", + 0, G_MAXINT, 1, + static_cast(G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, PROP_ITERATIONS, spec); + + spec = g_param_spec_int("ksize", + "Ksize", + "KSize", // TODO + 0, G_MAXINT, 1, // TODO + static_cast(G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, PROP_KSIZE, spec); + + spec = g_param_spec_enum("ktype", + "Ktype", + "KType", // TODO + GCV_TYPE_KTYPE, GCV_KTYPE_CV32F, // TODO + static_cast(G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, PROP_KTYPE, spec); + + spec = g_param_spec_int("max-level", + "Max Level", + "Max Level", // TODO + 0, G_MAXINT, 1, + static_cast(G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, PROP_MAX_LEVEL, spec); + + spec = g_param_spec_object("anchor", + "Anchor", + "Anchor", // TODO + GCV_TYPE_POINT, + static_cast(G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, PROP_ANCHOR, spec); +} + +/** + * gcv_image_filter_options_new: + * + * Returns a newly created #GCVImageFilterOptions. + * + * Since: 1.0.2 + */ +GCVImageFilterOptions * +gcv_image_filter_options_new(void) +{ + return GCV_IMAGE_FILTER_OPTIONS(g_object_new(GCV_TYPE_IMAGE_FILTER_OPTIONS, + NULL)); +} + +/***************************** end *******************/ + G_DEFINE_TYPE(GCVImage, gcv_image, GCV_TYPE_MATRIX) static void @@ -688,6 +973,56 @@ gcv_image_split(GCVImage *image) return g_list_reverse(values); } +/** + * gcv_image_bilateral_filter: + * @image: A #GCVImage. + * @d: Diameter of each pixel neighborhood that is used during filtering. If it is non-positive, it is computed from sigmaSpace. + * @sigma_color: Filter sigma in the color space. A larger value of the parameter means that farther colors within the pixel neighborhood (see sigmaSpace) will be mixed together, resulting in larger areas of semi-equal color. + * @sigma_space: Filter sigma in the coordinate space. A larger value of the parameter means that farther pixels will influence each other as long as their colors are close enough (see sigmaColor ). When d>0, it specifies the neighborhood size regardless of sigmaSpace. Otherwise, d is proportional to sigmaSpace. + * @options: (nullable): A #GCVImageFilterOptions; + * @error: (nullable): Return locatipcn for a #GError or %NULL. + * + * It effects bilateral filter image. The converted image is returned as + * a new image. + * + * Returns: (transfer full): A converted #GCVImage. + * + * Since: 1.0.4 + */ +GCVImage *gcv_image_bilateral_filter(GCVImage *image, + int d, + double sigma_color, + double sigma_space, + GCVImageFilterOptions *options, + GError **error) +{ + auto cv_image = gcv_matrix_get_raw(GCV_MATRIX(image)); + auto cv_converted_image = std::make_shared(); + + try { + if ( options != NULL ) { + auto options_priv = GCV_IMAGE_FILTER_OPTIONS_GET_PRIVATE(options); + int border_type = options_priv->border_type; + + cv::bilateralFilter(*cv_image, *cv_converted_image, + d, sigma_color, sigma_space, border_type); + } else { + cv::bilateralFilter(*cv_image, *cv_converted_image, + d, sigma_color, sigma_space); + } + } catch (const cv::Exception &exception) { + g_set_error(error, + GCV_IMAGE_ERROR, + GCV_IMAGE_ERROR_FILTER, + "Failed to filter image: %s", + exception.what()); + return NULL; + } + + + return gcv_image_new_raw(&cv_converted_image); +} + /** * gcv_image_median_blur: * @image: A #GCVImage. @@ -722,6 +1057,397 @@ GCVImage *gcv_image_median_blur(GCVImage *image, return gcv_image_new_raw(&cv_converted_image); } +/** + * gcv_image_blur: + * @image: A #GCVImage. + * @ksize: A #GCVSize blurring kernel size. + * @options: (nullable): A #GCVImageFilterOptions; + * @error: (nullable): Return locatipcn for a #GError or %NULL. + * + * It effects blur image. The converted image is returned as + * a new image. + * + * Returns: (transfer full): A converted #GCVImage. + * + * Since: 1.0.4 + */ +GCVImage *gcv_image_blur(GCVImage *image, + GCVSize *ksize, + GCVImageFilterOptions *options, + GError **error) +{ + auto cv_image = gcv_matrix_get_raw(GCV_MATRIX(image)); + auto cv_ksize = gcv_size_get_raw(ksize); + auto cv_converted_image = std::make_shared(); + + if ( options != NULL ) { + auto options_priv = GCV_IMAGE_FILTER_OPTIONS_GET_PRIVATE(options); + + auto anchor = cv::Point(-1, -1); + if (options_priv->anchor) { + anchor = *gcv_point_get_raw(options_priv->anchor); + } + cv::blur(*cv_image, *cv_converted_image, *cv_ksize, anchor, options_priv->border_type); + + } else { + cv::blur(*cv_image, *cv_converted_image, *cv_ksize); + } + + return gcv_image_new_raw(&cv_converted_image); +} + +/** + * gcv_image_box_filter: + * @image: A #GCVImage. + * @ddepth: the output image depth + * @ksize: blurring kernel size. + * @options: (nullable): A #GCVImageFilterOptions; + * @error: (nullable): Return locatipcn for a #GError or %NULL. + * + * HOGE + * It effects box filter image. The converted image is returned as + * a new image. + * + * Returns: (transfer full): A converted #GCVImage. + * + * Since: 1.0.4 + */ +GCVImage *gcv_image_box_filter(GCVImage *image, + int ddepth, + GCVSize *ksize, + GCVImageFilterOptions *options, + GError **error) +{ + auto cv_image = gcv_matrix_get_raw(GCV_MATRIX(image)); + auto cv_ksize = gcv_size_get_raw(ksize); + auto cv_converted_image = std::make_shared(); + + try { + if ( options != NULL ) { + auto options_priv = GCV_IMAGE_FILTER_OPTIONS_GET_PRIVATE(options); + bool normalize = true; + int border_type = options_priv->border_type; + auto anchor = cv::Point(-1,-1); + if (options_priv->anchor) { + anchor = *gcv_point_get_raw(options_priv->anchor); + } + cv::boxFilter(*cv_image, *cv_converted_image, ddepth, + *cv_ksize, anchor, normalize, border_type); + } else { + cv::boxFilter(*cv_image, *cv_converted_image, ddepth, *cv_ksize); + } + } catch (const cv::Exception &exception) { + g_set_error(error, + GCV_IMAGE_ERROR, + GCV_IMAGE_ERROR_FILTER, + "Failed to filter image: %s", + exception.what()); + return NULL; + } + + return gcv_image_new_raw(&cv_converted_image); +} + +/** + * gcv_image_build_pyramid: + * @image: A #GCVImage. + * @max_level: 0-based index of the last (the smallest) pyramid layer. It must be non-negative. + * @options: (nullable): A #GCVImageFilterOptions; + * @error: (nullable): Return locatipcn for a #GError or %NULL. + * + * Constructs the Gaussian pyramid for an image + * The converted image is returned as a new image. + * + * Returns: (transfer full): A converted #GCVImage. + * + * Since: 1.0.4 + */ +GCVImage *gcv_image_build_pyramid(GCVImage *image, + int max_level, + GCVImageFilterOptions *options, + GError **error) +{ + auto cv_image = gcv_matrix_get_raw(GCV_MATRIX(image)); + auto cv_converted_image = std::make_shared(); + + try { + if ( options != NULL ) { + auto options_priv = GCV_IMAGE_FILTER_OPTIONS_GET_PRIVATE(options); + int border_type = options_priv->border_type; + + cv::buildPyramid(*cv_image, *cv_converted_image, + max_level, border_type); + } else { + cv::buildPyramid(*cv_image, *cv_converted_image,max_level); + } + } catch (const cv::Exception &exception) { + g_set_error(error, + GCV_IMAGE_ERROR, + GCV_IMAGE_ERROR_FILTER, + "Failed to filter image: %s", + exception.what()); + return NULL; + } + + + return gcv_image_new_raw(&cv_converted_image); +} + + +/** + * gcv_image_dilate: + * @image: A #GCVImage. + * @kernel: structuring element used for dilation. + * @options: (nullable): A #GCVImageFilterOptions; + * @error: (nullable): Return locatipcn for a #GError or %NULL. + * + * Constructs the dilate filter for an image + * The converted image is returned as a new image. + * + * Returns: (transfer full): A converted #GCVImage. + * + * Since: 1.0.4 + */ +/* +GCVImage *gcv_image_dilate(GCVImage *image, + GCVMatrix *kernel, + GCVImageFilterOptions *options, + GError **error) +{ + auto cv_image = gcv_matrix_get_raw(GCV_MATRIX(image)); + auto cv_kernel = gcv_matrix_get_raw(GCV_MATRIX(kernel)); + auto cv_converted_image = std::make_shared(); + + try { + if ( options != NULL ) { + auto options_priv = GCV_IMAGE_FILTER_OPTIONS_GET_PRIVATE(options); + int iteration = options_priv->iteration; + int border_type = options_priv->border_type; + + auto anchor = cv::Point(-1,-1); + if (options_priv->anchor) { + anchor = *gcv_point_get_raw(options_priv->anchor); + } + + cv::dilate(*cv_image, *cv_converted_image, *cv_kernel, + anchor, iteration, border_type); + } else { + cv::dilate(*cv_image, *cv_converted_image, *cv_kernel); + } + } catch (const cv::Exception &exception) { + g_set_error(error, + GCV_IMAGE_ERROR, + GCV_IMAGE_ERROR_FILTER, + "Failed to filter image: %s", + exception.what()); + return NULL; + } + + + return gcv_image_new_raw(&cv_converted_image); +} +*/ + +/** + * gcv_image_filter2d: + * @image: A #GCVImage. + * @ddepth: desired depth of the destination image, see combinations. + * @kernel: convolution kernel (or rather a correlation kernel), a single-channel floating point matrix; if you want to apply different kernels to different channels, split the image into separate color planes using split and process them individually. + * @options: (nullable): A #GCVImageFilterOptions; + * @error: (nullable): Return locatipcn for a #GError or %NULL. + * + * Constructs the dilate filter for an image + * The converted image is returned as a new image. + * + * Returns: (transfer full): A converted #GCVImage. + * + * Since: 1.0.4 + */ +GCVImage *gcv_image_filter2d(GCVImage *image, + int ddepth, + GCVMatrix *kernel, + GCVImageFilterOptions *options, + GError **error) +{ + auto cv_image = gcv_matrix_get_raw(GCV_MATRIX(image)); + auto cv_kernel = gcv_matrix_get_raw(GCV_MATRIX(kernel)); + auto cv_converted_image = std::make_shared(); + + try { + if ( options != NULL ) { + auto options_priv = GCV_IMAGE_FILTER_OPTIONS_GET_PRIVATE(options); + int delta = options_priv->delta; + int border_type = options_priv->border_type; + auto anchor = cv::Point(-1,-1); + + if (options_priv->anchor) { + anchor = *gcv_point_get_raw(options_priv->anchor); + } + + cv::filter2D(*cv_image, *cv_converted_image, ddepth, *cv_kernel, + anchor, delta, border_type); + } else { + cv::filter2D(*cv_image, *cv_converted_image, ddepth, *cv_kernel); + } + } catch (const cv::Exception &exception) { + g_set_error(error, + GCV_IMAGE_ERROR, + GCV_IMAGE_ERROR_FILTER, + "Failed to filter image: %s", + exception.what()); + return NULL; + } + + return gcv_image_new_raw(&cv_converted_image); +} + +/** + * gcv_image_get_deriv_kernels: + * @image: A #GCVImage. + * @dx: TODO + * @dy: TODO + * @ksize: TODO + * @options: (nullable): A #GCVImageFilterOptions; + * @error: (nullable): Return locatipcn for a #GError or %NULL. + * + * TODO + * + * Returns: (transfer full): A converted #GCVImage. + * + * Since: 1.0.4 + */ +GCVImage *gcv_image_get_deriv_kernels(GCVImage *image, + int dx, + int dy, + int ksize, + GCVImageFilterOptions *options, + GError **error) +{ + auto cv_image = gcv_matrix_get_raw(GCV_MATRIX(image)); + auto cv_converted_image = std::make_shared(); + + try { + if ( options != NULL ) { + auto options_priv = GCV_IMAGE_FILTER_OPTIONS_GET_PRIVATE(options); + GCVKType ktype = options_priv->ktype; + gboolean normalize = options_priv->normalize; + + cv::getDerivKernels(*cv_image, *cv_converted_image, dx, dy, ksize, + normalize, ktype); + } else { + cv::getDerivKernels(*cv_image, *cv_converted_image, dx, dy, ksize); + } + } catch (const cv::Exception &exception) { + g_set_error(error, + GCV_IMAGE_ERROR, + GCV_IMAGE_ERROR_FILTER, + "Failed to filter image: %s", + exception.what()); + return NULL; + } + + return gcv_image_new_raw(&cv_converted_image); +} + +/** + * gcv_image_laplacian: + * @image: A #GCVImage. + * @ddepth: Desired depth of the destination image. + * @options: (nullable): A #GCVImageFilterOptions; + * @error: (nullable): Return locatipcn for a #GError or %NULL. + * + * It effects laplacian image. The converted image is returned as + * a new image. + * + * Returns: (transfer full): A converted #GCVImage. + * + * Since: 1.0.4 + */ +GCVImage *gcv_image_laplacian(GCVImage *image, + int ddepth, + GCVImageFilterOptions *options, + GError **error) +{ + auto cv_image = gcv_matrix_get_raw(GCV_MATRIX(image)); + auto cv_converted_image = std::make_shared(); + + try { + if ( options != NULL ) { + auto options_priv = GCV_IMAGE_FILTER_OPTIONS_GET_PRIVATE(options); + int ksize = options_priv->ksize; + double scale = options_priv->scale; + double delta = options_priv->delta; + int border_type = options_priv->border_type; + + cv::Laplacian(*cv_image, *cv_converted_image, + ddepth, ksize, scale, delta, border_type); + } else { + cv::Laplacian(*cv_image, *cv_converted_image, ddepth); + } + } catch (const cv::Exception &exception) { + g_set_error(error, + GCV_IMAGE_ERROR, + GCV_IMAGE_ERROR_FILTER, + "Failed to filter image: %s", + exception.what()); + return NULL; + } + + return gcv_image_new_raw(&cv_converted_image); +} + +/** + * gcv_image_sobel: + * @image: A #GCVImage. + * @ddepth: Desired depth of the destination image. + * @intx: Order of the derivative x + * @inty: Order of the derivative y + * @options: (nullable): A #GCVImageFilterOptions; + * @error: (nullable): Return locatipcn for a #GError or %NULL. + * + * It effects sobel image. The converted image is returned as + * a new image. + * + * Returns: (transfer full): A converted #GCVImage. + * + * Since: 1.0.4 + */ +GCVImage *gcv_image_sobel(GCVImage *image, + int ddepth, + int intx, + int inty, + GCVImageFilterOptions *options, + GError **error) +{ + auto cv_image = gcv_matrix_get_raw(GCV_MATRIX(image)); + auto cv_converted_image = std::make_shared(); + + try { + if ( options != NULL ) { + auto options_priv = GCV_IMAGE_FILTER_OPTIONS_GET_PRIVATE(options); + int ksize = options_priv->ksize; + double scale = options_priv->scale; + double delta = options_priv->delta; + int border_type = options_priv->border_type; + + cv::Sobel(*cv_image, *cv_converted_image, + ddepth, intx, inty, ksize, scale, delta, border_type); + + } else { + cv::Sobel(*cv_image, *cv_converted_image, ddepth, intx, inty); + } + } catch (const cv::Exception &exception) { + g_set_error(error, + GCV_IMAGE_ERROR, + GCV_IMAGE_ERROR_FILTER, + "Failed to filter image: %s", + exception.what()); + return NULL; + } + + return gcv_image_new_raw(&cv_converted_image); +} + G_END_DECLS GCVImage * diff --git a/opencv-glib/image.h b/opencv-glib/image.h index 3bf6957..a1bcd5d 100644 --- a/opencv-glib/image.h +++ b/opencv-glib/image.h @@ -110,6 +110,82 @@ struct _GCVDrawingOptionsClass GCVDrawingOptions *gcv_drawing_options_new(void); +/**********************************************/ + +/** + * GCVBorderTypes: + * @GCV_BORDER_TYPE_BORDER_CONSTANT: See `cv::BorderTypes::BORDER_CONSTANT`. + * @GCV_BORDER_TYPE_BORDER_REPLICATE : See `cv::BorderTypes::BORDER_REPLICATE `. + * @GCV_BORDER_TYPE_BORDER_REFLECT : See `cv::BorderTypes::BORDER_REFLECT `. + * @GCV_BORDER_TYPE_BORDER_WRAP : See `cv::BorderTypes::BORDER_WRAP `. + * @GCV_BORDER_TYPE_BORDER_REFLECT_101 : See `cv::BorderTypes::BORDER_REFLECT_101 `. + * @GCV_BORDER_TYPE_BORDER_TRANSPARENT : See `cv::BorderTypes::BORDER_TRANSPARENT `. + * @GCV_BORDER_TYPE_BORDER_REFLECT101 : See `cv::BorderTypes::BORDER_REFLECT101 `. + * @GCV_BORDER_TYPE_BORDER_DEFAULT : See `cv::BorderTypes::BORDER_DEFAULT `. + * @GCV_BORDER_TYPE_BORDER_ISOLATED : See `cv::BorderTypes::BORDER_ISOLATED `. + * + * Line type for drawing functions corresponding to `cv::BorderTypes`. + * + * See also [OpenCV documents](https://docs.opencv.org/). + * + * We don't have a link to the latest `cv::border_types` document. + * But we can link to a specific version: + * [OpenCV `cv::border_types`](). + * + * Since 1.0.2 + */ +typedef enum { + GCV_BORDER_TYPE_BORDER_CONSTANT = 0, + GCV_BORDER_TYPE_BORDER_REPLICATE = 1, + GCV_BORDER_TYPE_BORDER_REFLECT = 2, + GCV_BORDER_TYPE_BORDER_WRAP = 3, + GCV_BORDER_TYPE_BORDER_REFLECT_101 = 4, + GCV_BORDER_TYPE_BORDER_TRANSPARENT = 5, + GCV_BORDER_TYPE_BORDER_REFLECT101 = GCV_BORDER_TYPE_BORDER_REFLECT_101, + GCV_BORDER_TYPE_BORDER_DEFAULT = GCV_BORDER_TYPE_BORDER_REFLECT_101, + GCV_BORDER_TYPE_BORDER_ISOLATED = 16 +} GCVBorderType; + +#define GCV_TYPE_IMAGE_FILTER_OPTIONS (gcv_image_filter_options_get_type()) +G_DECLARE_DERIVABLE_TYPE(GCVImageFilterOptions, + gcv_image_filter_options, + GCV, + IMAGE_FILTER_OPTIONS, + GObject) + +struct _GCVImageFilterOptionsClass +{ + GObjectClass parent_class; +}; + +GCVImageFilterOptions *gcv_image_filter_options_new(void); + +/** + * GCVKrType: + * @GCV_KTYPE_CV_8U: TODO + * @GCV_KTYPE_CV_8S: TODO + * @GCV_KTYPE_CV_16U: TODO + * @GCV_KTYPE_CV_16S: TODO + * @GCV_KTYPE_CV_32S: TODO + * @GCV_KTYPE_CV_32F: TODO + * @GCV_KTYPE_CV_64F: TODO + * @GCV_KTYPE_CV_16F: TODO + * + */ +typedef enum { + GCV_KTYPE_CV8U = 0, + GCV_KTYPE_CV8S = 1, + GCV_KTYPE_CV16U = 2, + GCV_KTYPE_CV16S = 3, + GCV_KTYPE_CV32S = 4, + GCV_KTYPE_CV32F = 5, + GCV_KTYPE_CV64F = 6, + GCV_KTYPE_CV16F = 7 +} GCVKType; + +/**********************************************/ + + /** * GCVImageReadFlags: * @GCV_IMAGE_READ_FLAG_UNCHANGED: See `cv::IMREAD_UNCHANGED`. @@ -143,7 +219,7 @@ GCVDrawingOptions *gcv_drawing_options_new(void); * But we can link to a specific version: * [OpenCV 3.4.1's `cv::ImreadModes`](https://docs.opencv.org/3.4.1/d4/da8/group__imgcodecs.html#ga61d9b0126a3e57d9277ac48327799c80). * - * Since: 1.0.0 + * Since: 1.0.4 */ typedef enum { /*< flags >*/ GCV_IMAGE_READ_FLAG_UNCHANGED = -1, @@ -231,8 +307,55 @@ gcv_image_abs_diff(GCVImage *image, GList *gcv_image_split(GCVImage *image); +GCVImage *gcv_image_bilateral_filter(GCVImage *image, + int d, + double sigma_color, + double sigma_space, + GCVImageFilterOptions *options, + GError **error); + +GCVImage *gcv_image_box_filter(GCVImage *image, + int ddepth, + GCVSize *ksize, + GCVImageFilterOptions *options, + GError **error); + +GCVImage *gcv_image_filter2d(GCVImage *image, + int ddepth, + GCVMatrix *kernel, + GCVImageFilterOptions *options, + GError **error); + GCVImage *gcv_image_median_blur(GCVImage *image, gint ksize, GError **error); +GCVImage *gcv_image_blur(GCVImage *image, + GCVSize *ksize, + GCVImageFilterOptions *options, + GError **error); + +GCVImage *gcv_image_build_pyramid(GCVImage *image, + int max_level, + GCVImageFilterOptions *options, + GError **error); + +GCVImage *gcv_image_get_deriv_kernels(GCVImage *image, + int dx, + int dy, + int ksize, + GCVImageFilterOptions *options, + GError **error); + +GCVImage *gcv_image_laplacian(GCVImage *image, + int ddepth, + GCVImageFilterOptions *options, + GError **error); + +GCVImage *gcv_image_sobel(GCVImage *image, + int ddepth, + int intx, + int inty, + GCVImageFilterOptions *options, + GError **error); G_END_DECLS diff --git a/test/test-image.rb b/test/test-image.rb index b9e8073..6a5167b 100644 --- a/test/test-image.rb +++ b/test/test-image.rb @@ -353,6 +353,87 @@ def test_median_blur_invalid_argument(data) assert_raise(CV::ImageError::Filter.new(message)) do @image.median_blur(ksize) end + + end + def test_image_filter_options + options = CV::ImageFilterOptions.new + options.delta + options.scale + options.iterations + options.max_level +# options.sigma_y + options.border_type + options.ktype + options.normalize? + end + + def test_blur + size = CV::Size.new(10, 8) + blur_image = @image.blur(size) + blur_image = @image.blur(size,CV::ImageFilterOptions.new) + assert_not_equal(@image.bytes.to_s, + blur_image.bytes.to_s) + end + +=begin + def test_get_deriv_kernels + dx = 2 + dy = 2 + ksize = 3 + filtered_image = @image.get_deriv_kernels(dx,dy,ksize) + assert_not_equal(@image.bytes.to_s, + filtered_image.bytes.to_s) + + options = CV::ImageFilterOptions.new + options.ktype = 6 + options.normalize = true + filtered_image = @image.get_deriv_kernels(dx,dy,ksize,options) + assert_not_equal(@image.bytes.to_s, + filtered_image.bytes.to_s) + end +=end + + def test_laplacian + ddepth = 5 + filtered_image = @image.laplacian(ddepth) + assert_not_equal(@image.bytes.to_s, + filtered_image.bytes.to_s) + + options = CV::ImageFilterOptions.new + options.ksize = 1 +# options.ksize = 0 + filtered_image = @image.laplacian(ddepth,options) + assert_not_equal(@image.bytes.to_s, + filtered_image.bytes.to_s) + end + + def test_filter2d + ddepth = -1 + filtered_image = @image.filter2d(ddepth,@image) + assert_not_equal(@image.bytes.to_s, + filtered_image.bytes.to_s) + + options = CV::ImageFilterOptions.new + options.ksize = 1 +# options.ksize = 0 + filtered_image = @image.filter2d(ddepth,@image,options) + assert_not_equal(@image.bytes.to_s, + filtered_image.bytes.to_s) + end + + def test_sobel + ddepth = 5 + filtered_image = @image.sobel(ddepth,1,1) + assert_not_equal(@image.bytes.to_s, + filtered_image.bytes.to_s) + + options = CV::ImageFilterOptions.new + # + options.ksize = 3 + filtered_image = @image.sobel(ddepth,1,1,options) + assert_not_equal(@image.bytes.to_s, + filtered_image.bytes.to_s) + end end end