pixel* Cartoon(pixel* image, int lines, int colors, int width, int height, pixel* output)
{
	int i, length;
	length = width * height;
	pixel* copy = pixel_copy(image, width, height);
	Sobel_Edges(image, 0, 0, width, height, output);

	// custom threshold for multiplication
	for(i = 0; i < length; i++)
	{
		pixel oldPixel = output[i];
		if(oldPixel.red > lines)
			oldPixel.red = oldPixel.blue = oldPixel.green = 0;
		else
			oldPixel.red = oldPixel.blue = oldPixel.green = 1;
		output[i] = oldPixel;
	}

	Posterize(copy, colors, width, height, copy);

	for(i = 0; i < length;  i++)
	{
		pixel outputPixel = output[i];
		pixel copyPixel = copy[i];
		outputPixel.red *= copyPixel.red;
		outputPixel.blue *= copyPixel.blue;
		outputPixel.green *= copyPixel.green;
		output[i] = outputPixel;
	}

	free(copy);
	return output;
}
示例#2
0
pixel* Fast_Edges(pixel* image, int threshold, int width, int height, pixel* output)
{
    int i, j, a, b, sum;
    int length = width * height;
    short quick_mask[3][3] =  {
        {-1,  0, -1},
        { 0,  4,  0},
        {-1,  0, -1}
    };

    pixel* copy = pixel_copy(image, width, height);
    RGB_to_Gray_PixelArray(image, width, height, copy);

    for(i=1; i<height-1; i++) {
        for(j=1; j<width-1; j++) {
            sum = 0;
            for(a=-1; a<2; a++) {
                for(b=-1; b<2; b++) {
                    sum = sum + copy[(i*width)+(a*width)+j+b].red * quick_mask[a+1][b+1];
                }
            }
            if(sum < 0)   sum = 0;
            if(sum > 255) sum = 255;

            pixel newPixel;
            newPixel.red = newPixel.green = newPixel.blue = sum;
            newPixel.alpha = 255;
            output[i*width + j] = newPixel;

        }
    }

    // threshold
    Threshold(output, threshold, width, height, output);

    free(copy);
    return output;
}
示例#3
0
static void
despeckle_median (guchar   *src,
                  guchar   *dst,
                  gint      width,
                  gint      height,
                  gint      bpp,
                  gint      radius,
                  gboolean  preview)
{
  guint  progress;
  guint  max_progress;
  gint   x, y;
  gint   input_radius = radius;
  gint   pos;
  gint   ymin;
  gint   ymax;
  gint   xmin;
  gint   xmax;

  memset (&histogram, 0, sizeof(histogram));
  progress     = 0;
  max_progress = width * height;

  if (! preview)
    gimp_progress_init(_("Despeckle"));


  for (y = 0; y < height; y++)
    {
      x = 0;
      ymin = MAX (0, y - radius);
      ymax = MIN (height - 1, y + radius);
      xmin = MAX (0, x - radius);
      xmax = MIN (width - 1, x + radius);
      hist0   = 0;
      histrest = 0;
      hist255 = 0;
      histogram_clean (&histogram);
      histogram.xmin = xmin;
      histogram.ymin = ymin;
      histogram.xmax = xmax;
      histogram.ymax = ymax;
      add_vals (&histogram,
                src, width, bpp,
                histogram.xmin, histogram.ymin, histogram.xmax, histogram.ymax);

      for (x = 0; x < width; x++)
        {
          const guchar *pixel;

          ymin = MAX (0, y - radius); /* update ymin, ymax when radius changed (FILTER_ADAPTIVE) */
          ymax = MIN (height - 1, y + radius);
          xmin = MAX (0, x - radius);
          xmax = MIN (width - 1, x + radius);

          update_histogram (&histogram,
                            src, width, bpp, xmin, ymin, xmax, ymax);

          pos = (x + (y * width)) * bpp;
          pixel = histogram_get_median (&histogram, src + pos);

          if (filter_type & FILTER_RECURSIVE)
            {
              del_val (&histogram, src, width, bpp, x, y);
              pixel_copy (src + pos, pixel, bpp);
              add_val (&histogram, src, width, bpp, x, y);
            }

          pixel_copy (dst + pos, pixel, bpp);

          /*
           * Check the histogram and adjust the diameter accordingly...
           */
          if (filter_type & FILTER_ADAPTIVE)
            {
              if (hist0 >= radius || hist255 >= radius)
                {
                  if (radius < input_radius)
                    radius++;
                }
              else if (radius > 1)
                {
                  radius--;
                }
            }
        }

      progress += width;

      if (! preview && y % 32 == 0)
        gimp_progress_update ((gdouble) progress / (gdouble) max_progress);
    }

  if (! preview)
    gimp_progress_update (1.0);
}