示例#1
0
static void
median (GeglBuffer *src,
        GeglBuffer *dst,
        gint        radius,
        gdouble     rank)
{
  RankList list = {0};

  gint x,y;
  gint offset;
  gfloat *src_buf;
  gfloat *dst_buf;


  src_buf = g_new0 (gfloat, gegl_buffer_get_pixel_count (src) * 4);
  dst_buf = g_new0 (gfloat, gegl_buffer_get_pixel_count (dst) * 4);

  gegl_buffer_get (src, NULL, 1.0, babl_format ("RGBA float"), src_buf,
                   GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);

  offset = 0;
  for (y=0; y<gegl_buffer_get_height (dst); y++)
    for (x=0; x<gegl_buffer_get_width (dst); x++)
      {
        gint u,v;
        gfloat *median_pix;

        list_clear (&list);

        for (v=y-radius;v<=y+radius;v++)
          for (u=x-radius;u<=x+radius;u++)
            {
              gint ru, rv;

              ru = (x-u)*(x-u);
              rv = (y-v)*(y-v);

              if (u >= 0 && u < gegl_buffer_get_width (dst) &&
                  v >= 0 && v < gegl_buffer_get_height (dst) &&
                  (ru+rv) < radius* radius
                  )
                {
                  gfloat *src_pix = src_buf + (u+(v * gegl_buffer_get_width (src))) * 4;
                  gfloat luma = (src_pix[0] * 0.212671 +
                                 src_pix[1] * 0.715160 +
                                 src_pix[2] * 0.072169);
                  list_add (&list, luma, src_pix);
                }
            }

        median_pix = list_percentile (&list, rank);
        for (u=0; u<4;u++)
          dst_buf[offset*4+u] = median_pix[u];
        offset++;
      }
  gegl_buffer_set (dst, NULL, 0, babl_format ("RGBA float"), dst_buf, GEGL_AUTO_ROWSTRIDE);
  g_free (src_buf);
  g_free (dst_buf);
}
示例#2
0
static void
snn_percentile (GeglBuffer *src,
                GeglBuffer *dst,
                gdouble     radius,
                gdouble     percentile,
                gint        pairs)
{
    gint    x, y;
    gint    offset;
    gfloat *src_buf;
    gfloat *dst_buf;
    RankList list = {0};

    src_buf = g_new0 (gfloat, gegl_buffer_get_pixel_count (src) * 4);
    dst_buf = g_new0 (gfloat, gegl_buffer_get_pixel_count (dst) * 4);

    gegl_buffer_get (src, 1.0, NULL, babl_format ("RGBA float"), src_buf, GEGL_AUTO_ROWSTRIDE);

    offset = 0;
    percentile/= 100.0;

    for (y=0; y<gegl_buffer_get_height (dst); y++)
        for (x=0; x<gegl_buffer_get_width (dst); x++)
        {
            gint u,v;
            gfloat *center_pix = src_buf + offset * 4;

            list_clear (&list);

            /* iterate through the upper left quater of pixels */
            for (v=-radius; v<=0; v++)
                for (u=-radius; u<= (pairs==1?radius:0); u++)
                {
                    gfloat *selected_pix = center_pix;
                    gfloat  best_diff = 1000.0;
                    gint    i;

                    /* skip computations for the center pixel */
                    if (u != 0 &&
                            v != 0)
                    {
                        /* compute the coordinates of the symmetric pairs for
                         * this locaiton in the quadrant
                         */
                        gint xs[4] = {x+u, x-u, x-u, x+u};
                        gint ys[4] = {y+v, y-v, y+v, y-v};

                        /* check which member of the symmetric quadruple to use */
                        for (i=0; i<pairs*2; i++)
                        {
                            if (xs[i] >= 0 && xs[i] < gegl_buffer_get_width (src) &&
                                    ys[i] >= 0 && ys[i] < gegl_buffer_get_height (src))
                            {
                                gfloat *tpix = src_buf + (xs[i]+ys[i]*gegl_buffer_get_width (src))*4;
                                gfloat diff = colordiff (tpix, center_pix);
                                if (diff < best_diff)
                                {
                                    best_diff = diff;
                                    selected_pix = tpix;
                                }
                            }
                        }
                    }

                    list_add (&list, rgb2luminance(selected_pix), selected_pix);

                    if (u==0 && v==0)
                        break; /* to avoid doubly processing when using only 1 pair */
                }
            {
                gfloat *result = list_percentile (&list, percentile);
                for (u=0; u<4; u++)
                    dst_buf[offset*4+u] = result[u];
            }
            offset++;
        }
    gegl_buffer_set (dst, NULL, babl_format ("RGBA float"), dst_buf, GEGL_AUTO_ROWSTRIDE);
    g_free (src_buf);
    g_free (dst_buf);
}