123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298 |
- /*
- * Copyright (C) 2011-2014 Karlsruhe Institute of Technology
- *
- * This file is part of Ufo.
- *
- * This library is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation, either
- * version 3 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
- #ifdef __APPLE__
- #include <OpenCL/cl.h>
- #else
- #include <CL/cl.h>
- #endif
- #include <math.h>
- #include "ufo-remove-stripes-task.h"
- /**
- * SECTION:ufo-remove-stripes-task
- * @Short_description: Remove stripes from 2D images, requires frequency domain
- * input
- * @Title: remove_stripes
- *
- */
- struct _UfoRemoveStripesTaskPrivate {
- guint last_width;
- /* OpenCL */
- cl_context context;
- cl_kernel kernel;
- cl_mem filter_mem;
- /* properties */
- gfloat strength;
- };
- static void ufo_task_interface_init (UfoTaskIface *iface);
- G_DEFINE_TYPE_WITH_CODE (UfoRemoveStripesTask, ufo_remove_stripes_task, UFO_TYPE_TASK_NODE,
- G_IMPLEMENT_INTERFACE (UFO_TYPE_TASK,
- ufo_task_interface_init))
- #define UFO_REMOVE_STRIPES_TASK_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_REMOVE_STRIPES_TASK, UfoRemoveStripesTaskPrivate))
- enum {
- PROP_0,
- PROP_STRENGTH,
- N_PROPERTIES
- };
- static GParamSpec *properties[N_PROPERTIES] = { NULL, };
- /**
- * create_coefficients:
- * @priv: UfoRemoveStripesTaskPrivate
- * @width: image width (not the interleaved from fft, rather the real width)
- *
- * Compute symmetric filter coefficients.
- */
- static void
- create_coefficients (UfoRemoveStripesTaskPrivate *priv, const guint width)
- {
- gfloat *coefficients = g_malloc0 (sizeof (gfloat) * width);
- gfloat sigma = priv->strength / (2.0 * sqrt (2.0 * log (2.0)));
- /* Divided by 2 because of the symmetry and we need the +1 to correctly handle
- * the frequency at width / 2 */
- const guint real_width = width / 2 + 1;
- cl_int cl_err;
- if (!coefficients) {
- g_warning ("Could not allocate memory for coeefficients");
- }
- if (width % 2) {
- g_warning ("Width must be an even number");
- }
- for (gint x = 0; x < (gint) real_width; x++) {
- coefficients[x] = 1.0f - exp (- x * x / (sigma * sigma * 2.0f));
- }
- if (priv->filter_mem) {
- UFO_RESOURCES_CHECK_CLERR (clReleaseMemObject (priv->filter_mem));
- }
- priv->filter_mem = clCreateBuffer (priv->context,
- CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
- sizeof (cl_float) * real_width,
- coefficients,
- &cl_err);
- UFO_RESOURCES_CHECK_CLERR (cl_err);
- g_free (coefficients);
- priv->last_width = width;
- }
- UfoNode *
- ufo_remove_stripes_task_new (void)
- {
- return UFO_NODE (g_object_new (UFO_TYPE_REMOVE_STRIPES_TASK, NULL));
- }
- static void
- ufo_remove_stripes_task_setup (UfoTask *task,
- UfoResources *resources,
- GError **error)
- {
- UfoRemoveStripesTaskPrivate *priv;
- priv = UFO_REMOVE_STRIPES_TASK_GET_PRIVATE (task);
- priv->context = ufo_resources_get_context (resources);
- priv->kernel = ufo_resources_get_kernel (resources, "ankacomplex.cl", "multiply_frequencies_with_real_sym", error);
- priv->filter_mem = NULL;
- UFO_RESOURCES_CHECK_CLERR (clRetainContext (priv->context));
- if (priv->kernel) {
- UFO_RESOURCES_CHECK_CLERR (clRetainKernel (priv->kernel));
- }
- }
- static void
- ufo_remove_stripes_task_get_requisition (UfoTask *task,
- UfoBuffer **inputs,
- UfoRequisition *requisition)
- {
- UfoRemoveStripesTaskPrivate *priv;
- priv = UFO_REMOVE_STRIPES_TASK_GET_PRIVATE (task);
- ufo_buffer_get_requisition (inputs[0], requisition);
- if (!priv->filter_mem || requisition->dims[0] / 2 != priv->last_width) {
- create_coefficients (priv, requisition->dims[0] / 2);
- }
- }
- static guint
- ufo_remove_stripes_task_get_num_inputs (UfoTask *task)
- {
- return 1;
- }
- static guint
- ufo_remove_stripes_task_get_num_dimensions (UfoTask *task,
- guint input)
- {
- g_return_val_if_fail (input == 0, 0);
- return 2;
- }
- static UfoTaskMode
- ufo_remove_stripes_task_get_mode (UfoTask *task)
- {
- return UFO_TASK_MODE_PROCESSOR | UFO_TASK_MODE_GPU;
- }
- static gboolean
- ufo_remove_stripes_task_process (UfoTask *task,
- UfoBuffer **inputs,
- UfoBuffer *output,
- UfoRequisition *requisition)
- {
- UfoRemoveStripesTaskPrivate *priv;
- UfoGpuNode *node;
- UfoProfiler *profiler;
- cl_command_queue cmd_queue;
- cl_mem in_mem;
- cl_mem out_mem;
- priv = UFO_REMOVE_STRIPES_TASK_GET_PRIVATE (task);
- node = UFO_GPU_NODE (ufo_task_node_get_proc_node (UFO_TASK_NODE (task)));
- cmd_queue = ufo_gpu_node_get_cmd_queue (node);
- out_mem = ufo_buffer_get_device_array (output, cmd_queue);
- in_mem = ufo_buffer_get_device_array (inputs[0], cmd_queue);
- UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (priv->kernel, 0, sizeof (cl_mem), &in_mem));
- UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (priv->kernel, 1, sizeof (cl_mem), &out_mem));
- UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (priv->kernel, 2, sizeof (cl_mem), &priv->filter_mem));
- profiler = ufo_task_node_get_profiler (UFO_TASK_NODE (task));
- ufo_profiler_call (profiler, cmd_queue, priv->kernel, 2, requisition->dims, NULL);
- return TRUE;
- }
- static void
- ufo_remove_stripes_task_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
- {
- UfoRemoveStripesTaskPrivate *priv = UFO_REMOVE_STRIPES_TASK_GET_PRIVATE (object);
- switch (property_id) {
- case PROP_STRENGTH:
- priv->strength = g_value_get_float (value);
- if (priv->last_width) {
- /* Update only if we know how big the data is */
- create_coefficients (priv, priv->last_width);
- }
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
- }
- static void
- ufo_remove_stripes_task_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
- {
- UfoRemoveStripesTaskPrivate *priv = UFO_REMOVE_STRIPES_TASK_GET_PRIVATE (object);
- switch (property_id) {
- case PROP_STRENGTH:
- g_value_set_float (value, priv->strength);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
- }
- static void
- ufo_remove_stripes_task_finalize (GObject *object)
- {
- UfoRemoveStripesTaskPrivate *priv;
- priv = UFO_REMOVE_STRIPES_TASK_GET_PRIVATE (object);
- if (priv->filter_mem) {
- UFO_RESOURCES_CHECK_CLERR (clReleaseMemObject (priv->filter_mem));
- priv->filter_mem = NULL;
- }
- if (priv->kernel) {
- UFO_RESOURCES_CHECK_CLERR (clReleaseKernel (priv->kernel));
- priv->kernel = NULL;
- }
- if (priv->context) {
- UFO_RESOURCES_CHECK_CLERR (clReleaseContext (priv->context));
- priv->context = NULL;
- }
- G_OBJECT_CLASS (ufo_remove_stripes_task_parent_class)->finalize (object);
- }
- static void
- ufo_task_interface_init (UfoTaskIface *iface)
- {
- iface->setup = ufo_remove_stripes_task_setup;
- iface->get_num_inputs = ufo_remove_stripes_task_get_num_inputs;
- iface->get_num_dimensions = ufo_remove_stripes_task_get_num_dimensions;
- iface->get_mode = ufo_remove_stripes_task_get_mode;
- iface->get_requisition = ufo_remove_stripes_task_get_requisition;
- iface->process = ufo_remove_stripes_task_process;
- }
- static void
- ufo_remove_stripes_task_class_init (UfoRemoveStripesTaskClass *klass)
- {
- GObjectClass *oclass = G_OBJECT_CLASS (klass);
- oclass->set_property = ufo_remove_stripes_task_set_property;
- oclass->get_property = ufo_remove_stripes_task_get_property;
- oclass->finalize = ufo_remove_stripes_task_finalize;
- properties[PROP_STRENGTH] =
- g_param_spec_float ("strength",
- "Filter strength",
- "Filter strength, it is the full width at half maximum of a Gaussian "\
- "in the frequency domain. The real filter is then 1 - Gaussian",
- 1e-3f, G_MAXFLOAT, 1.0f,
- G_PARAM_READWRITE);
- for (guint i = PROP_0 + 1; i < N_PROPERTIES; i++)
- g_object_class_install_property (oclass, i, properties[i]);
- g_type_class_add_private (oclass, sizeof(UfoRemoveStripesTaskPrivate));
- }
- static void
- ufo_remove_stripes_task_init(UfoRemoveStripesTask *self)
- {
- self->priv = UFO_REMOVE_STRIPES_TASK_GET_PRIVATE(self);
- self->priv->strength = 1.0f;
- self->priv->last_width = 0;
- }
|