Esempio n. 1
0
void rgbTween (float r1, float g1, float b1, float r2, float g2, float b2, float tween, int direction, float &outr, float &outg, float &outb)
{
	float h1, s1, l1, h2, s2, l2, outh, outs, outl;

	rgb2hsl (r1, g1, b1, h1, s1, l1);
	rgb2hsl (r2, g2, b2, h2, s2, l2);
	hslTween (h1, s1, l1, h2, s2, l2, tween, direction, outh, outs, outl);
	hsl2rgb (outh, outs, outl, outr, outg, outb);
}
Esempio n. 2
0
void rgbTween(double r1, double g1, double b1,
					 double r2, double g2, double b2, double tween, int direction,
					 double &outr, double &outg, double &outb){
	double h1, s1, l1, h2, s2, l2, outh, outs, outl;

	rgb2hsl(r1, g1, b1, h1, s1, l1);
	rgb2hsl(r2, g2, b2, h2, s2, l2);
	hslTween(h1, s1, l1, h2, s2, l2, tween, direction, outh, outs, outl);
	hsl2rgb(outh, outs, outl, outr, outg, outb);
}
Esempio n. 3
0
mat3f dcolor(const vec3f &rgb, const vec3f &amp)
{
    vec3f hsl = rgb2hsl(rgb);
    vec3f RGB;
    mat3f m;
    RGB = hsl2rgb(hsl + vec3f(0.01f, 0, 0));
    m.setColumn(0, (RGB - rgb) / 0.01f * amp.x);
    RGB = hsl2rgb(hsl + vec3f(0, 0.01f, 0));
    m.setColumn(1, (RGB - rgb) / 0.01f * amp.y);
    RGB = hsl2rgb(hsl + vec3f(0, 0, 0.01f));
    m.setColumn(2, (RGB - rgb) / 0.01f * amp.z);
    return m;
}
Esempio n. 4
0
static void
colorpick_callback (GtkDarktableButton *button, gpointer user_data)
{
  dt_iop_module_t *self = (dt_iop_module_t *)user_data;
  dt_iop_splittoning_gui_data_t *g = (dt_iop_splittoning_gui_data_t *)self->gui_data;
  if(self->dt->gui->reset) return;
  dt_iop_splittoning_params_t *p = (dt_iop_splittoning_params_t *)self->params;

  GtkColorSelectionDialog  *csd = GTK_COLOR_SELECTION_DIALOG(gtk_color_selection_dialog_new(_("select tone color")));
  gtk_window_set_transient_for(GTK_WINDOW(csd), GTK_WINDOW(dt_ui_main_window(darktable.gui->ui)));

  GtkWidget *okButton, *cancelButton = 0;
  g_object_get(G_OBJECT(csd), "ok-button", &okButton, NULL);
  g_object_get(G_OBJECT(csd), "cancel-button", &cancelButton, NULL);

  g_signal_connect (G_OBJECT (okButton), "clicked",
                    G_CALLBACK (colorpick_button_callback), csd);
  g_signal_connect (G_OBJECT (cancelButton), "clicked",
                    G_CALLBACK (colorpick_button_callback), csd);
  
  GtkColorSelection *cs = GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(csd));
  GdkColor c;
  float color[3],h,s,l;
  h=(button==g->colorpick1)?p->shadow_hue:p->highlight_hue;
  s=(button==g->colorpick1)?p->shadow_saturation:p->highlight_saturation;
  l=0.5;
  hsl2rgb(color,h,s,l);

  c.red= 65535 * color[0];
  c.green= 65535 * color[1];
  c.blue= 65535 * color[2];
  gtk_color_selection_set_current_color(cs,&c);
  if(gtk_dialog_run(GTK_DIALOG(csd))==GTK_RESPONSE_ACCEPT)
  {
    gtk_color_selection_get_current_color(cs,&c);
    color[0]=c.red/65535.0;
    color[1]=c.green/65535.0;
    color[2]=c.blue/65535.0;
    rgb2hsl(color,&h,&s,&l);
    l=0.5;
    hsl2rgb(color,h,s,l);

    dt_bauhaus_slider_set( (button==g->colorpick1)? g->gslider1: g->gslider3 ,h );
    dt_bauhaus_slider_set( (button==g->colorpick1)? g->gslider2: g->gslider4 ,s );
  }
  gtk_widget_destroy(GTK_WIDGET(csd));
  dt_dev_add_history_item(darktable.develop, self, TRUE);
}
Esempio n. 5
0
void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, void *ivoid, void *ovoid,
             const dt_iop_roi_t *roi_in, const dt_iop_roi_t *roi_out)
{
  dt_iop_splittoning_data_t *data = (dt_iop_splittoning_data_t *)piece->data;
  float *in;
  float *out;
  const int ch = piece->colors;

  const float compress = (data->compress / 110.0) / 2.0; // Dont allow 100% compression..
#ifdef _OPENMP
#pragma omp parallel for default(none) shared(ivoid, ovoid, roi_out, data) private(in, out) schedule(static)
#endif
  for(int k = 0; k < roi_out->height; k++)
  {
    in = ((float *)ivoid) + (size_t)ch * k * roi_out->width;
    out = ((float *)ovoid) + (size_t)ch * k * roi_out->width;
    for(int j = 0; j < roi_out->width; j++, in += ch, out += ch)
    {
      double ra, la;
      float mixrgb[3];
      float h, s, l;
      rgb2hsl(in, &h, &s, &l);
      if(l < data->balance - compress || l > data->balance + compress)
      {
        h = l < data->balance ? data->shadow_hue : data->highlight_hue;
        s = l < data->balance ? data->shadow_saturation : data->highlight_saturation;
        ra = l < data->balance ? CLIP((fabs(-data->balance + compress + l) * 2.0))
                               : CLIP((fabs(-data->balance - compress + l) * 2.0));
        la = (1.0 - ra);

        hsl2rgb(mixrgb, h, s, l);

        out[0] = CLIP(in[0] * la + mixrgb[0] * ra);
        out[1] = CLIP(in[1] * la + mixrgb[1] * ra);
        out[2] = CLIP(in[2] * la + mixrgb[2] * ra);
      }
      else
      {
        out[0] = in[0];
        out[1] = in[1];
        out[2] = in[2];
      }

      out[3] = in[3];
    }
  }
}
Esempio n. 6
0
static void
colorpick_callback (GtkDarktableButton *button, gpointer user_data)
{
  dt_iop_module_t *self = (dt_iop_module_t *)user_data;
  dt_iop_colorize_gui_data_t *g = (dt_iop_colorize_gui_data_t *)self->gui_data;
  if(self->dt->gui->reset) return;
  dt_iop_colorize_params_t *p = (dt_iop_colorize_params_t *)self->params;

  GtkColorSelectionDialog  *csd = GTK_COLOR_SELECTION_DIALOG(gtk_color_selection_dialog_new(_("select tone color")));
  g_signal_connect (G_OBJECT (csd->ok_button), "clicked",
                    G_CALLBACK (colorpick_button_callback), csd);
  g_signal_connect (G_OBJECT (csd->cancel_button), "clicked",
                    G_CALLBACK (colorpick_button_callback), csd);

  GtkColorSelection *cs = GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(csd));
  GdkColor c;
  float color[3],h,s,l;

  h = p->hue;
  s = p->saturation;
  l=0.5;
  hsl2rgb(color,h,s,l);

  c.red= 65535 * color[0];
  c.green= 65535 * color[1];
  c.blue= 65535 * color[2];

  gtk_color_selection_set_current_color(cs,&c);

  if(gtk_dialog_run(GTK_DIALOG(csd))==GTK_RESPONSE_ACCEPT)
  {
    gtk_color_selection_get_current_color(cs,&c);
    color[0]=c.red/65535.0;
    color[1]=c.green/65535.0;
    color[2]=c.blue/65535.0;
    rgb2hsl(color,&h,&s,&l);
    l=0.5;
    hsl2rgb(color,h,s,l);

    dtgtk_gradient_slider_set_value(g->gslider1, h);
    dtgtk_gradient_slider_set_value(g->gslider2, s);
  }

  gtk_widget_destroy(GTK_WIDGET(csd));
  dt_dev_add_history_item(darktable.develop, self, TRUE);
}
Esempio n. 7
0
static void colorpick_callback(GtkColorButton *widget, dt_iop_module_t *self)
{
  if(self->dt->gui->reset) return;

  dt_iop_splittoning_gui_data_t *g = (dt_iop_splittoning_gui_data_t *)self->gui_data;

  float color[3], h, s, l;

  GdkRGBA c;
  gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(widget), &c);
  color[0] = c.red;
  color[1] = c.green;
  color[2] = c.blue;
  rgb2hsl(color, &h, &s, &l);

  dt_bauhaus_slider_set((GTK_WIDGET(widget) == g->colorpick1) ? g->gslider1 : g->gslider3, h);
  dt_bauhaus_slider_set((GTK_WIDGET(widget) == g->colorpick1) ? g->gslider2 : g->gslider4, s);

  dt_dev_add_history_item(darktable.develop, self, TRUE);
}
Esempio n. 8
0
// BANG - calculate and output
void cs_bang(t_cs *x)
{
	if(x->attr_mode == ps_rgb2hsl) rgb2hsl(x, x->val1, x->val2, x->val3); // first for speed
	else if(x->attr_mode == ps_hsl2rgb) hsl2rgb(x, x->val1, x->val2, x->val3);
	
	else if(x->attr_mode == ps_no_transform) no_transform(x);
	else if(x->attr_mode == ps_rgb2cmy) rgb2cmy(x, x->val1, x->val2, x->val3);
	else if(x->attr_mode == ps_cmy2rgb) cmy2rgb(x, x->val1, x->val2, x->val3);
	else if(x->attr_mode == ps_rgb2hsv) rgb2hsv(x, x->val1, x->val2, x->val3);
	else if(x->attr_mode == ps_hsv2rgb) hsv2rgb(x, x->val1, x->val2, x->val3);
	else if(x->attr_mode == ps_rgb2xyz) rgb2xyz(x, x->val1, x->val2, x->val3);
	else if(x->attr_mode == ps_xyz2rgb) xyz2rgb(x, x->val1, x->val2, x->val3);
	else if(x->attr_mode == ps_rgb2uvw) rgb2uvw(x, x->val1, x->val2, x->val3);
	else if(x->attr_mode == ps_uvw2rgb) uvw2rgb(x, x->val1, x->val2, x->val3);
	else if(x->attr_mode == ps_rgb2retinalcone) rgb2cone(x, x->val1, x->val2, x->val3);
	else if(x->attr_mode == ps_retinalcone2rgb) cone2rgb(x, x->val1, x->val2, x->val3);
	else if(x->attr_mode == ps_rgb2lab) rgb2lab(x, x->val1, x->val2, x->val3);
	else if(x->attr_mode == ps_lab2rgb) lab2rgb(x, x->val1, x->val2, x->val3);
	else if(x->attr_mode == ps_rgb2yiq) rgb2yiq(x, x->val1, x->val2, x->val3);
	else if(x->attr_mode == ps_yiq2rgb) yiq2rgb(x, x->val1, x->val2, x->val3);
	else if(x->attr_mode == ps_rgb2hls) rgb2hls(x, x->val1, x->val2, x->val3);
	else if(x->attr_mode == ps_hls2rgb) hls2rgb(x, x->val1, x->val2, x->val3);
	else if(x->attr_mode == ps_rgb2rgbcie) rgb2rgbcie(x, x->val1, x->val2, x->val3);
	else if(x->attr_mode == ps_rgbcie2rgb) rgbcie2rgb(x, x->val1, x->val2, x->val3);
	else if(x->attr_mode == ps_rgb2rgbsmpte) rgb2rgbsmpte(x, x->val1, x->val2, x->val3);
	else if(x->attr_mode == ps_rgbsmpte2rgb) rgbsmpte2rgb(x, x->val1, x->val2, x->val3);

	if(x->attr_outputtype == ps_packed){
		Atom temp_list[3];
		atom_setlong(temp_list+0, x->calc1);
		atom_setlong(temp_list+1, x->calc2);
		atom_setlong(temp_list+2, x->calc3);
		outlet_list(x->out1, 0L, 3, temp_list);	// output the result
	}	
	else{
		outlet_int(x->out3, x->calc3);	// output the result	
		outlet_int(x->out2, x->calc2);	// output the result	
		outlet_int(x->out1, x->calc1);	// output the result
	}	
}
Esempio n. 9
0
int main(int argc, char** argv) {

    int i, j, count;    
    //char** filenames;
	char id[50] = {0};
	char filename[50];
    //char seg_file_name[50] = {'s', 'e', 'g', '/', 's', 'e', 'g', '\0'};
    //char suffix[5] = {'.', 't', 'x', 't', '\0'};
    //FILE* fpout;

    if (argc != 2) {
        printf("Please input the path to the pictures.\n");// & the output file name!\n");
		exit(1);
    }
	
	// define those features
	fbrightness brightness;
	fsaturation saturation;
	float colorfulness;
	float naturalness;
	float contrast;
	float sharpness;
	fgray_simplicity gray_simplicity;
	frgb_simplicity rgb_simplicity;
	fhsv_simplicity hsv_simplicity;
	fhue_hist hue_hist;
	fcolor_harmony color_harmony;
	fcolor_coherence color_coherence;
	fsegment_lightness segment_lightness;
	fSegment_size segment_size;
	fSegment_hues segment_hues;
    fcolor_harmony segment_color_harmony;
	fsaliency_map saliency_map;
	int n_sift;
	int n_faces;	
	
	// point to images
	IplImage* opencv_img;
	image_rgb* rgb;
	image_hsl* hsl;
	image_hsv* hsv;
	image_gray* gray;
    //filenames = get_files_list(argv[1], &count);
    //fpout = fopen(argv[2], "w");
	
	CvHaarClassifierCascade* classifier = (CvHaarClassifierCascade*)cvLoad("haarcascade_frontalface_alt_tree.xml", 0, 0, 0);

	strcpy(filename, argv[1]);
	opencv_img = cvLoadImage(/*filenames[i]*/filename, 1);
	rgb = load_cv_image(opencv_img);
	hsl = rgb2hsl(rgb);
	hsv = rgb2hsv(rgb);
	gray = rgb2gray(rgb);

	// tune the filename
	int loc_beg = -1, loc_end = 0;
	for (i = 0; i < strlen(filename); ++i) {
		if (filename[i] == '/')
			loc_beg = i;
		if (filename[i] == '.') 
			loc_end = i;
	}
	strncpy(id, filename+loc_beg+1, loc_end-loc_beg-1);
	id[loc_end-loc_beg] = '\0';
	/*
	strncpy(seg_file_name+7, id, strlen(id));
	strcpy(seg_file_name+7+strlen(id), suffix);
	//printf("%s\n", seg_file_name);
	*/
	// compute those features
	brightness = get_brightness_feature(hsl);
	saturation = get_saturation_feature(hsl);
	colorfulness = get_colorfulness_feature(rgb);
	naturalness = get_naturalness_feature(hsl);
	contrast = get_contrast_feature(hsl);
	sharpness = get_sharpness_feature(hsl);
	gray_simplicity = get_grayscale_simplicity_feature(gray);
	rgb_simplicity = get_rgb_simplicity_feature(rgb);
	hsv_simplicity = get_hsv_simplicity_feature(hsv);
	hue_hist = get_hue_histogram_feature(hsv);
	color_harmony = get_color_harmony_feature(hsl);
	color_coherence = get_color_coherence_feature(hsv);

	// KGL
	//ncut_seg seg_arg = ncut_main_seg_from_file(seg_file_name, rgb->height, rgb->width);

	int height = rgb->height, width = rgb->width;
	double double_gray[height * width];
	for (i = 0; i < height; ++i) {
		for (j = 0; j < width; ++j) {
		// 矩阵存储是按列存储的
			double_gray[j*height+i] = 0.299*rgb->r[i*width+j] + 0.587*rgb->g[i*width+j] + 0.114*rgb->b[i*width+j];
		}
	}
	Map<MatrixXd> imageX(double_gray, height, width);
	SparseMatrix<double> W = ICgraph(imageX);
	int* asgn = ncutW(W, 5);	

	int seglable[height * width];
	for (j = 0; j < width; ++j) {
		for (i = 0; i < height; ++i) {
			seglable[i*width+j] = asgn[j*height+i];
		}
	}	
	free(asgn);
	ncut_seg seg_arg = ncut_main_seg_from_memory(seglable, height, width);
	segment_size = get_segsize_feature(seg_arg.seglable, seg_arg.nr, seg_arg.nc, seg_arg.lablenum);
	segment_hues = get_seghues_feature(seg_arg.seglable, hsv, seg_arg.nr, seg_arg.nc, seg_arg.lablenum);
	segment_color_harmony = get_segcolor_harmony_feature(hsl, seg_arg.seglable, seg_arg.lablenum);
	segment_lightness = get_seglightness_feature(hsl, seg_arg.seglable, seg_arg.lablenum);
	//free(seg_arg.seglable);
	// - KGL

	float* saliency = get_saliency_map(rgb);
	saliency_map = get_saliency_map_feature(saliency, rgb->width, rgb->height);
	n_sift = get_sift_number(opencv_img);	
	n_faces = get_face_feature(opencv_img, classifier, cvSize(10, 20));

	// free those space
	cvReleaseImage(&opencv_img);
	image_rgb_delete(rgb);
	image_hsl_delete(hsl);
	image_hsv_delete(hsv);
	image_gray_delete(gray);
	free(saliency);

	// output
	printf("%s,", id); // the filename of the image without suffix
	printf("%f,%f,%f,%f,", brightness.mean, brightness.stdev, brightness.max, brightness.min); // brightness
	printf("%f,%f,%f,%f,", saturation.mean, saturation.stdev, saturation.max, saturation.min); // saturation
	printf("%f,%f,%f,%f,", colorfulness, naturalness, contrast, sharpness);	
	printf("%d,%d,%f,", gray_simplicity.contrast, gray_simplicity.sig_pixels_num, gray_simplicity.stdev); // gray simplicity
	printf("%d,%f,", rgb_simplicity.sig_pixels_num, rgb_simplicity.ratio); // RGB simplicity
	printf("%d,%f,", hsv_simplicity.sig_pixels_num, hsv_simplicity.ratio); // HSV simplicity
	printf("%d,%f,%f,", hue_hist.sig_pixels_num, hue_hist.contrast, hue_hist.stdev); // Hue histogram
	printf("%f,%f,%f,", color_harmony.bestfit, color_harmony.first_two_dev, color_harmony.avg_dev); // color harmony
	printf("%d,%f,%f,%d,%d,", color_coherence.n_ccc, color_coherence.r_lc, color_coherence.r_slc, color_coherence.rank, color_coherence.s_rank); // color coherence

	// KGL
	printf("%f,%f,", segment_size.rmaxsize, segment_size.rcontrast); // Segment size
	printf("%d,%d,%d,%d,%f,%f,", segment_hues.fhues1, segment_hues.fhues2, segment_hues.fhues3, segment_hues.fhues4, segment_hues.fhues5, segment_hues.fhues6); // Segment hues
	printf("%f,%f,%f,", segment_color_harmony.bestfit, segment_color_harmony.first_two_dev, segment_color_harmony.avg_dev); // Segment color harmony
	printf("%f,%f,%f,", segment_lightness.mseg_ave, segment_lightness.seg_ave_std, segment_lightness.seg_ave_contrast); // Segment lightness
	// - KGL

	printf("%f,%d,%f,%f,%d,%f,%f,%f,%f,", saliency_map.r_bg, saliency_map.n_cc, saliency_map.r_lc, saliency_map.asv_lc, saliency_map.n_cc_bg, saliency_map.r_lc_bg, saliency_map.d_cc, saliency_map.d_rtp, saliency_map.d_ci);
	printf("%d,", n_sift);	
	printf("%d", n_faces);
	
    //fclose(fpout);
    cvReleaseHaarClassifierCascade( &classifier );
    //free(filenames);
    
    //printf(" - progress: 100.00%%\n");
    
    return (EXIT_SUCCESS);
}
Esempio n. 10
0
void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const void *const ivoid,
             void *const ovoid, const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out)
{
  dt_iop_rlce_data_t *data = (dt_iop_rlce_data_t *)piece->data;
  const int ch = piece->colors;

  // PASS1: Get a luminance map of image...
  float *luminance = (float *)malloc(((size_t)roi_out->width * roi_out->height) * sizeof(float));
// double lsmax=0.0,lsmin=1.0;
#ifdef _OPENMP
#pragma omp parallel for default(none) schedule(static) shared(luminance)
#endif
  for(int j = 0; j < roi_out->height; j++)
  {
    float *in = (float *)ivoid + (size_t)j * roi_out->width * ch;
    float *lm = luminance + (size_t)j * roi_out->width;
    for(int i = 0; i < roi_out->width; i++)
    {
      double pmax = CLIP(fmax(in[0], fmax(in[1], in[2]))); // Max value in RGB set
      double pmin = CLIP(fmin(in[0], fmin(in[1], in[2]))); // Min value in RGB set
      *lm = (pmax + pmin) / 2.0;                           // Pixel luminocity
      in += ch;
      lm++;
    }
  }


  // Params
  const int rad = data->radius * roi_in->scale / piece->iscale;

  const int bins = 256;
  const float slope = data->slope;

// CLAHE
#ifdef _OPENMP
#pragma omp parallel for default(none) schedule(static) shared(luminance)
#endif
  for(int j = 0; j < roi_out->height; j++)
  {
    int yMin = fmax(0, j - rad);
    int yMax = fmin(roi_in->height, j + rad + 1);
    int h = yMax - yMin;

    int xMin0 = fmax(0, 0 - rad);
    int xMax0 = fmin(roi_in->width - 1, rad);

    int hist[bins + 1];
    int clippedhist[bins + 1];
    float dest[roi_out->width];

    /* initially fill histogram */
    memset(hist, 0, (bins + 1) * sizeof(int));
    for(int yi = yMin; yi < yMax; ++yi)
      for(int xi = xMin0; xi < xMax0; ++xi)
        ++hist[ROUND_POSISTIVE(luminance[(size_t)yi * roi_in->width + xi] * (float)bins)];

    // Destination row
    memset(dest, 0, roi_out->width * sizeof(float));
    float *ld = dest;

    for(int i = 0; i < roi_out->width; i++)
    {

      int v = ROUND_POSISTIVE(luminance[(size_t)j * roi_in->width + i] * (float)bins);

      int xMin = fmax(0, i - rad);
      int xMax = i + rad + 1;
      int w = fmin(roi_in->width, xMax) - xMin;
      int n = h * w;

      int limit = (int)(slope * n / bins + 0.5f);

      /* remove left behind values from histogram */
      if(xMin > 0)
      {
        int xMin1 = xMin - 1;
        for(int yi = yMin; yi < yMax; ++yi)
          --hist[ROUND_POSISTIVE(luminance[(size_t)yi * roi_in->width + xMin1] * (float)bins)];
      }

      /* add newly included values to histogram */
      if(xMax <= roi_in->width)
      {
        int xMax1 = xMax - 1;
        for(int yi = yMin; yi < yMax; ++yi)
          ++hist[ROUND_POSISTIVE(luminance[(size_t)yi * roi_in->width + xMax1] * (float)bins)];
      }

      /* clip histogram and redistribute clipped entries */
      memcpy(clippedhist, hist, (bins + 1) * sizeof(int));
      int ce = 0, ceb = 0;
      do
      {
        ceb = ce;
        ce = 0;
        for(int b = 0; b <= bins; b++)
        {
          int d = clippedhist[b] - limit;
          if(d > 0)
          {
            ce += d;
            clippedhist[b] = limit;
          }
        }

        int d = (ce / (float)(bins + 1));
        int m = ce % (bins + 1);
        for(int h = 0; h <= bins; h++) clippedhist[h] += d;

        if(m != 0)
        {
          int s = bins / (float)m;
          for(int h = 0; h <= bins; h += s) ++clippedhist[h];
        }
      } while(ce != ceb);

      /* build cdf of clipped histogram */
      int hMin = bins;
      for(int h = 0; h < hMin; h++)
        if(clippedhist[h] != 0) hMin = h;

      int cdf = 0;
      for(int h = hMin; h <= v; h++) cdf += clippedhist[h];

      int cdfMax = cdf;
      for(int h = v + 1; h <= bins; h++) cdfMax += clippedhist[h];

      int cdfMin = clippedhist[hMin];

      *ld = (cdf - cdfMin) / (float)(cdfMax - cdfMin);

      ld++;
    }

    // Apply row
    float *in = ((float *)ivoid) + (size_t)j * roi_out->width * ch;
    float *out = ((float *)ovoid) + (size_t)j * roi_out->width * ch;
    for(int r = 0; r < roi_out->width; r++)
    {
      float H, S, L;
      rgb2hsl(in, &H, &S, &L);
      // hsl2rgb(out,H,S,( L / dest[r] ) * (L-lsmin) + lsmin );
      hsl2rgb(out, H, S, dest[r]);
      out += ch;
      in += ch;
      ld++;
    }
  }

  // Cleanup
  free(luminance);
}
Esempio n. 11
0
void process (struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, void *ivoid, void *ovoid, const dt_iop_roi_t *roi_in, const dt_iop_roi_t *roi_out)
{
  dt_iop_soften_data_t *data = (dt_iop_soften_data_t *)piece->data;
  float *in  = (float *)ivoid;
  float *out = (float *)ovoid;
  const int ch = piece->colors;

  const float brightness = 1.0 / exp2f ( -data->brightness );
  const float saturation = data->saturation/100.0;
  /* create overexpose image and then blur */
#ifdef _OPENMP
  #pragma omp parallel for default(none) shared(in,out,roi_out) schedule(static)
#endif
  for(int k=0; k<roi_out->width*roi_out->height; k++)
  {
    int index = ch*k;
    float h,s,l;
    rgb2hsl(&in[index],&h,&s,&l);
    s*=saturation;
    l*=brightness;
    hsl2rgb(&out[index],h,CLIP(s),CLIP(l));
  }

  const float w = piece->iwidth*piece->iscale;
  const float h = piece->iheight*piece->iscale;
  int mrad = sqrt( w*w + h*h) * 0.01;
  int rad = mrad*(fmin(100.0,data->size+1)/100.0);
  const int radius = MIN(mrad, ceilf(rad * roi_in->scale / piece->iscale));

  /* horizontal blur out into out */
  const int range = 2*radius+1;
  const int hr = range/2;

  const int size = roi_out->width > roi_out->height ? roi_out->width : roi_out->height;
  float *scanline[3]= {0};
  scanline[0]  = malloc((size*sizeof(float))*ch);
  scanline[1]  = malloc((size*sizeof(float))*ch);
  scanline[2]  = malloc((size*sizeof(float))*ch);

  for(int iteration=0; iteration<BOX_ITERATIONS; iteration++)
  {
    int index=0;
    for(int y=0; y<roi_out->height; y++)
    {
      for(int k=0; k<3; k++)
      {
        float L=0;
        int hits = 0;
        for(int x=-hr; x<roi_out->width; x++)
        {
          int op = x - hr-1;
          int np = x+hr;
          if(op>=0)
          {
            L-=out[(index+op)*ch+k];
            hits--;
          }
          if(np < roi_out->width)
          {
            L+=out[(index+np)*ch+k];
            hits++;
          }
          if(x>=0)
            scanline[k][x] = L/hits;
        }
      }

      for (int k=0; k<3; k++)
        for (int x=0; x<roi_out->width; x++)
          out[(index+x)*ch+k] = scanline[k][x];

      index+=roi_out->width;
    }

    /* vertical pass on blurlightness */
    const int opoffs = -(hr+1)*roi_out->width;
    const int npoffs = (hr)*roi_out->width;
    for(int x=0; x < roi_out->width; x++)
    {
      for(int k=0; k<3; k++)
      {
        float L=0;
        int hits=0;
        int index = -hr*roi_out->width+x;
        for(int y=-hr; y<roi_out->height; y++)
        {
          int op=y-hr-1;
          int np= y + hr;

          if(op>=0)
          {
            L-=out[(index+opoffs)*ch+k];
            hits--;
          }
          if(np < roi_out->height)
          {
            L+=out[(index+npoffs)*ch+k];
            hits++;
          }
          if(y>=0)
            scanline[k][y] = L/hits;
          index += roi_out->width;
        }
      }

      for(int k=0; k<3; k++)
        for (int y=0; y<roi_out->height; y++)
          out[(y*roi_out->width+x)*ch+k] = scanline[k][y];

    }
  }


  const float amount = data->amount/100.0;
#ifdef _OPENMP
  #pragma omp parallel for default(none) shared(roi_out, in, out, data) schedule(static)
#endif
  for(int k=0; k<roi_out->width*roi_out->height; k++)
  {
    int index = ch*k;
    out[index+0] = in[index+0]*(1-amount) + CLIP(out[index+0])*amount;
    out[index+1] = in[index+1]*(1-amount) + CLIP(out[index+1])*amount;
    out[index+2] = in[index+2]*(1-amount) + CLIP(out[index+2])*amount;
    out[index+3] = in[index+3];
  }

  for(int i=0; i<3; ++i)
    if(scanline[i])
      free(scanline[i]);
}
Esempio n. 12
0
void process (struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, void *ivoid, void *ovoid, const dt_iop_roi_t *roi_in, const dt_iop_roi_t *roi_out)
{
  const dt_iop_channelmixer_data_t *data = (dt_iop_channelmixer_data_t *)piece->data;
  const gboolean gray_mix_mode = ( data->red[CHANNEL_GRAY] !=0.0 ||  data->green[CHANNEL_GRAY] !=0.0 ||  data->blue[CHANNEL_GRAY] !=0.0)?TRUE:FALSE;
  const int ch = piece->colors;

#ifdef _OPENMP
  #pragma omp parallel for default(none) shared(ivoid, ovoid, roi_in, roi_out, data) schedule(static)
#endif
  for(int j=0; j<roi_out->height; j++)
  {
    const float *in = ((float *)ivoid) + (size_t)ch*j*roi_out->width;
    float *out = ((float *)ovoid) + (size_t)ch*j*roi_out->width;
    for(int i=0; i<roi_out->width; i++)
    {
      float h,s,l, hmix,smix,lmix,rmix,gmix,bmix,graymix;
      // Calculate the HSL mix
      hmix = CLIP( in[0] * data->red[CHANNEL_HUE] )+( in[1] * data->green[CHANNEL_HUE])+( in[2] * data->blue[CHANNEL_HUE] );
      smix = CLIP( in[0] * data->red[CHANNEL_SATURATION] )+( in[1] * data->green[CHANNEL_SATURATION])+( in[2] * data->blue[CHANNEL_SATURATION] );
      lmix = CLIP( in[0] * data->red[CHANNEL_LIGHTNESS] )+( in[1] * data->green[CHANNEL_LIGHTNESS])+( in[2] * data->blue[CHANNEL_LIGHTNESS] );

      // If HSL mix is used apply to out[]
      if( hmix != 0.0 || smix != 0.0 || lmix != 0.0 )
      {
        // mix into HSL output channels
        rgb2hsl(in,&h,&s,&l);
        h = (hmix != 0.0 )  ? hmix : h;
        s = (smix != 0.0 )  ? smix : s;
        l = (lmix != 0.0 )  ? lmix : l;
        hsl2rgb(out,h,s,l);
      }
      else   // no HSL copt in[] to out[]
        for(int i=0; i<3; i++) out[i]=in[i];

      // Calculate graymix and RGB mix
      graymix = CLIP(( out[0] * data->red[CHANNEL_GRAY] )+( out[1] * data->green[CHANNEL_GRAY])+( out[2] * data->blue[CHANNEL_GRAY] ));

      rmix = CLIP(( out[0] * data->red[CHANNEL_RED] )+( out[1] * data->green[CHANNEL_RED])+( out[2] * data->blue[CHANNEL_RED] ));
      gmix = CLIP(( out[0] * data->red[CHANNEL_GREEN] )+( out[1] * data->green[CHANNEL_GREEN])+( out[2] * data->blue[CHANNEL_GREEN] ));
      bmix = CLIP(( out[0] * data->red[CHANNEL_BLUE] )+( out[1] * data->green[CHANNEL_BLUE])+( out[2] * data->blue[CHANNEL_BLUE] ));


      if (gray_mix_mode)  // Graymix is used...
        out[0] = out[1] = out[2] = graymix;
      else   // RGB mix is used...
      {
        out[0] = rmix;
        out[1] = gmix;
        out[2] = bmix;
      }

      /*mix = CLIP( in[0] * data->red)+( in[1] * data->green)+( in[2] * data->blue );

      if( data->output_channel <= CHANNEL_LIGHTNESS ) {
        // mix into HSL output channels
        rgb2hsl(in,&h,&s,&l);
        h = ( data->output_channel == CHANNEL_HUE )              ? mix : h;
        s = ( data->output_channel == CHANNEL_SATURATION )   ? mix : s;
        l = ( data->output_channel == CHANNEL_LIGHTNESS )     ?  mix : l;
        hsl2rgb(out,h,s,l);
      } else  if( data->output_channel > CHANNEL_LIGHTNESS && data->output_channel  < CHANNEL_GRAY) {
        // mix into rgb output channels
        out[0] = ( data->output_channel == CHANNEL_RED )      ? mix : in[0];
        out[1] = ( data->output_channel == CHANNEL_GREEN )  ? mix : in[1];
        out[2] = ( data->output_channel == CHANNEL_BLUE )     ? mix : in[2];
      } else   if( data->output_channel <= CHANNEL_GRAY ) {
        out[0]=out[1]=out[2] = mix;
      }
      */
      out += ch;
      in += ch;
    }
  }

  if(piece->pipe->mask_display)
    dt_iop_alpha_copy(ivoid, ovoid, roi_out->width, roi_out->height);
}
Esempio n. 13
0
void process (struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, void *ivoid, void *ovoid, const dt_iop_roi_t *roi_in, const dt_iop_roi_t *roi_out)
{
  dt_iop_soften_data_t *data = (dt_iop_soften_data_t *)piece->data;
  float *in  = (float *)ivoid;
  float *out = (float *)ovoid;
  const int ch = piece->colors;

  const float brightness = 1.0 / exp2f ( -data->brightness );
  const float saturation = data->saturation/100.0;
  /* create overexpose image and then blur */
#ifdef _OPENMP
  #pragma omp parallel for default(none) shared(in,out,roi_out) schedule(static)
#endif
  for(size_t k=0; k<(size_t)roi_out->width*roi_out->height; k++)
  {
    size_t index = ch*k;
    float h,s,l;
    rgb2hsl(&in[index],&h,&s,&l);
    s*=saturation;
    l*=brightness;
    hsl2rgb(&out[index],h,CLIP(s),CLIP(l));
  }

  const float w = piece->iwidth*piece->iscale;
  const float h = piece->iheight*piece->iscale;
  int mrad = sqrt( w*w + h*h) * 0.01;
  int rad = mrad*(fmin(100.0,data->size+1)/100.0);
  const int radius = MIN(mrad, ceilf(rad * roi_in->scale / piece->iscale));

  const int size = roi_out->width > roi_out->height ? roi_out->width : roi_out->height;

  for(int iteration=0; iteration<BOX_ITERATIONS; iteration++)
  {
#ifdef _OPENMP
  #pragma omp parallel for default(none) shared(out,roi_out) schedule(static)
#endif
    /* horizontal blur out into out */
    for(int y=0; y<roi_out->height; y++)
    {
      __m128 scanline[size];
      size_t index = (size_t)y * roi_out->width;
      __m128 L = _mm_setzero_ps();
      int hits = 0;
      for(int x=-radius; x<roi_out->width; x++)
      {
        int op = x - radius-1;
        int np = x+radius;
        if(op>=0)
        {
          L = _mm_sub_ps(L, _mm_load_ps(&out[(index+op)*ch]));
          hits--;
        }
        if(np < roi_out->width)
        {
          L =  _mm_add_ps(L, _mm_load_ps(&out[(index+np)*ch]));
          hits++;
        }
        if(x>=0)
          scanline[x] = _mm_div_ps(L, _mm_set_ps1(hits));
      }

      for (int x=0; x<roi_out->width; x++)
        _mm_store_ps(&out[(index+x)*ch], scanline[x]);
    }

    /* vertical pass on blurlightness */
    const int opoffs = -(radius+1)*roi_out->width;
    const int npoffs = (radius)*roi_out->width;
#ifdef _OPENMP
  #pragma omp parallel for default(none) shared(out,roi_out) schedule(static)
#endif
    for(int x=0; x < roi_out->width; x++)
    {
      __m128 scanline[size];
      __m128 L = _mm_setzero_ps();
      int hits=0;
      size_t index = (size_t)x - radius*roi_out->width;
      for(int y=-radius; y<roi_out->height; y++)
      {
        int op=y-radius-1;
        int np= y + radius;

        if(op>=0)
        {
          L = _mm_sub_ps(L, _mm_load_ps(&out[(index+opoffs)*ch]));
          hits--;
        }
        if(np < roi_out->height)
        {
          L = _mm_add_ps(L, _mm_load_ps(&out[(index+npoffs)*ch]));
          hits++;
        }
        if(y>=0)
          scanline[y] = _mm_div_ps(L, _mm_set_ps1(hits));
        index += roi_out->width;
      }

      for (int y=0; y<roi_out->height; y++)
        _mm_store_ps(&out[((size_t)y*roi_out->width+x)*ch], scanline[y]);
    }
  }


  const __m128 amount = _mm_set1_ps(data->amount/100.0);
  const __m128 amount_1 = _mm_set1_ps(1-(data->amount)/100.0);
#ifdef _OPENMP
  #pragma omp parallel for default(none) shared(roi_out, in, out, data) schedule(static)
#endif
  for(size_t k=0; k<(size_t)roi_out->width*roi_out->height; k++)
  {
    int index = ch*k;
    _mm_store_ps(&out[index],
                 _mm_add_ps(_mm_mul_ps(_mm_load_ps(&in[index]), amount_1),
                            _mm_mul_ps(MM_CLIP_PS(_mm_load_ps(&out[index])), amount)));
  }
}
Esempio n. 14
0
//recursive function to handle higher dimension matrices, by processing 2D sections at a time
void jit_colortrack_calculate_ndim(t_max_jit_colortrack *x, long dimcount, long *dim, t_jit_matrix_info *in_minfo, char *bip)
{
    t_atom	my_val[6];				// for output
    float	normalized_bounds[4];
    long	i, j, n;
    long	min_x[4], min_y[4], max_x[4], max_y[4];
    char	inrange_flag_x[4], inrange_flag_y[4];
    int		tracker;
    uchar	*ip;
    char	red, green, blue;
    short	hue, saturation, lightness;
    bool	no_match;

    n = dim[0];

    min_x[TRACKER_1] = min_x[TRACKER_2] = min_x[TRACKER_3] = min_x[TRACKER_4] = min_y[TRACKER_1] = min_y[TRACKER_2] = min_y[TRACKER_3] = min_y[TRACKER_4] = 0x7FFFFFFF;	// a really high number, because we're looking to see if a pixel is less than the one stored
    max_x[TRACKER_1] = max_x[TRACKER_2] = max_x[TRACKER_3] = max_x[TRACKER_4] = max_y[TRACKER_1] = max_y[TRACKER_2] = max_y[TRACKER_3] = max_y[TRACKER_4] = -1;

//object_post((t_object *)x, "1 is looking for this: %i %i - %i %i - %i %i", x->min[TRACKER_1][HUE], x->max[TRACKER_1][HUE], x->min[TRACKER_1][SATURATION], x->max[TRACKER_1][SATURATION], x->min[TRACKER_1][BRIGHTNESS], x->max[TRACKER_1][BRIGHTNESS]);
//object_post((t_object *)x, "2 is looking for this: %i %i - %i %i - %i %i", x->min[TRACKER_2][HUE], x->max[TRACKER_2][HUE], x->min[TRACKER_2][SATURATION], x->max[TRACKER_2][SATURATION], x->min[TRACKER_2][BRIGHTNESS], x->max[TRACKER_2][BRIGHTNESS]);

    for(i=0; i<dim[1]; i++) {								// ITERATE THROUGH THE Y-AXIS
        ip = (uchar *)(bip + i * in_minfo->dimstride[1]);
//		ip = bip + i * in_minfo->dimstride[1];
        inrange_flag_y[TRACKER_1] = inrange_flag_y[TRACKER_2] = inrange_flag_y[TRACKER_3] = inrange_flag_y[TRACKER_4] = FALSE;

        for(j=0; j<n; j++) {								// ITERATE THROUGH THE X-AXIS
            ip++;										// skip the alpha channel
            red = *ip++;
            green = *ip++;
            blue = *ip++;

            rgb2hsl(red, green, blue, &hue, &saturation, &lightness);
//object_post((t_object *)x, "The incoming HSL is: %i %i %i", hue, saturation, lightness);

// ********* UNROLLING THIS FOR-LOOP FOR SPEED ********************
//			for(tracker = TRACKER_1; tracker < NUM_TRACKERS; tracker++){
//				if(x->use[tracker]){							// ** NOTE: MAY WANT TO REPLACE SOME BRANCHING WITH FUNCTION POINTERS
            if(x->use[TRACKER_1]) {
                tracker = TRACKER_1;
                inrange_flag_x[tracker] = TRUE;

                if(x->hue_check[tracker]) {
                    if(hue > x->min[tracker][HUE]) 				// HUE - range to match crosses 0 on the color wheel
                        inrange_flag_x[tracker] = FALSE;
                    else if(hue < x->max[tracker][HUE])
                        inrange_flag_x[tracker] = FALSE;
                }
                else {
                    if(hue < x->min[tracker][HUE]) 				// HUE - normal
                        inrange_flag_x[tracker] = FALSE;
                    else if(hue > x->max[tracker][HUE])
                        inrange_flag_x[tracker] = FALSE;
                }

                if(saturation < x->min[tracker][SATURATION]) 			// SATURATION
                    inrange_flag_x[tracker] = FALSE;
                else if(saturation > x->max[tracker][SATURATION])
                    inrange_flag_x[tracker] = FALSE;

                if(lightness < x->min[tracker][LIGHTNESS]) 				// LIGHTNESS
                    inrange_flag_x[tracker] = FALSE;
                else if(lightness > x->max[tracker][LIGHTNESS])
                    inrange_flag_x[tracker] = FALSE;

                if(inrange_flag_x[tracker]) {			// ANY TIME A PIXEL IS TRUE
                    inrange_flag_y[tracker] = TRUE;		// set the Y-axis flag to true
                    if(j < min_x[tracker]) 			// min_x or max_x = is updated with the X-axis pixel location
                        min_x[tracker] = j;
                    else if(j > max_x[tracker])
                        max_x[tracker] = j;
                }
            }
            if(x->use[TRACKER_2]) {
                tracker = TRACKER_2;
                inrange_flag_x[tracker] = TRUE;

                if(x->hue_check[tracker]) {
                    if(hue > x->min[tracker][HUE]) 				// HUE - range to match crosses 0 on the color wheel
                        inrange_flag_x[tracker] = FALSE;
                    else if(hue < x->max[tracker][HUE])
                        inrange_flag_x[tracker] = FALSE;
                }
                else {
                    if(hue < x->min[tracker][HUE]) 				// HUE - normal
                        inrange_flag_x[tracker] = FALSE;
                    else if(hue > x->max[tracker][HUE])
                        inrange_flag_x[tracker] = FALSE;
                }

                if(saturation < x->min[tracker][SATURATION]) 			// SATURATION
                    inrange_flag_x[tracker] = FALSE;
                else if(saturation > x->max[tracker][SATURATION])
                    inrange_flag_x[tracker] = FALSE;

                if(lightness < x->min[tracker][LIGHTNESS]) 				// LIGHTNESS
                    inrange_flag_x[tracker] = FALSE;
                else if(lightness > x->max[tracker][LIGHTNESS])
                    inrange_flag_x[tracker] = FALSE;

                if(inrange_flag_x[tracker]) {			// ANY TIME A PIXEL IS TRUE
                    inrange_flag_y[tracker] = TRUE;		// set the Y-axis flag to true
                    if(j < min_x[tracker]) 			// min_x or max_x = is updated with the X-axis pixel location
                        min_x[tracker] = j;
                    else if(j > max_x[tracker])
                        max_x[tracker] = j;
                }
            }
            if(x->use[TRACKER_3]) {
                tracker = TRACKER_3;
                inrange_flag_x[tracker] = TRUE;

                if(x->hue_check[tracker]) {
                    if(hue > x->min[tracker][HUE]) 				// HUE - range to match crosses 0 on the color wheel
                        inrange_flag_x[tracker] = FALSE;
                    else if(hue < x->max[tracker][HUE])
                        inrange_flag_x[tracker] = FALSE;
                }
                else {
                    if(hue < x->min[tracker][HUE]) 				// HUE - normal
                        inrange_flag_x[tracker] = FALSE;
                    else if(hue > x->max[tracker][HUE])
                        inrange_flag_x[tracker] = FALSE;
                }

                if(saturation < x->min[tracker][SATURATION]) 			// SATURATION
                    inrange_flag_x[tracker] = FALSE;
                else if(saturation > x->max[tracker][SATURATION])
                    inrange_flag_x[tracker] = FALSE;

                if(lightness < x->min[tracker][LIGHTNESS]) 				// LIGHTNESS
                    inrange_flag_x[tracker] = FALSE;
                else if(lightness > x->max[tracker][LIGHTNESS])
                    inrange_flag_x[tracker] = FALSE;

                if(inrange_flag_x[tracker]) {			// ANY TIME A PIXEL IS TRUE
                    inrange_flag_y[tracker] = TRUE;		// set the Y-axis flag to true
                    if(j < min_x[tracker]) 			// min_x or max_x = is updated with the X-axis pixel location
                        min_x[tracker] = j;
                    else if(j > max_x[tracker])
                        max_x[tracker] = j;
                }
            }
            if(x->use[TRACKER_4]) {
                tracker = TRACKER_4;
                inrange_flag_x[tracker] = TRUE;

                if(x->hue_check[tracker]) {
                    if(hue > x->min[tracker][HUE]) 				// HUE - range to match crosses 0 on the color wheel
                        inrange_flag_x[tracker] = FALSE;
                    else if(hue < x->max[tracker][HUE])
                        inrange_flag_x[tracker] = FALSE;
                }
                else {
                    if(hue < x->min[tracker][HUE]) 				// HUE - normal
                        inrange_flag_x[tracker] = FALSE;
                    else if(hue > x->max[tracker][HUE])
                        inrange_flag_x[tracker] = FALSE;
                }

                if(saturation < x->min[tracker][SATURATION]) 			// SATURATION
                    inrange_flag_x[tracker] = FALSE;
                else if(saturation > x->max[tracker][SATURATION])
                    inrange_flag_x[tracker] = FALSE;

                if(lightness < x->min[tracker][LIGHTNESS]) 				// LIGHTNESS
                    inrange_flag_x[tracker] = FALSE;
                else if(lightness > x->max[tracker][LIGHTNESS])
                    inrange_flag_x[tracker] = FALSE;

                if(inrange_flag_x[tracker]) {			// ANY TIME A PIXEL IS TRUE
                    inrange_flag_y[tracker] = TRUE;		// set the Y-axis flag to true
                    if(j < min_x[tracker]) 			// min_x or max_x = is updated with the X-axis pixel location
                        min_x[tracker] = j;
                    else if(j > max_x[tracker])
                        max_x[tracker] = j;
                }
            }
//			}
        }

        /*		for(tracker = TRACKER_1; tracker < NUM_TRACKERS; tracker++){
        			if(x->use[tracker] && inrange_flag_y[tracker]){		// ANY TIME A PIXEL IS TRUE (the y-axis flag was set in the x-axis loop)
        				if(i < min_y[tracker]) 				// min_y or max_y = is updated with the Y-axis pixel location
        					min_y[tracker] = i;
        				else if(i > max_y[tracker])
        					max_y[tracker] = i;
        			}
        		}
        */
// *********** UNROLLED VERSION OF THE ABOVE FOR-LOOP FOR SPEED ************
        if(x->use[TRACKER_1] && inrange_flag_y[TRACKER_1]) {		// ANY TIME A PIXEL IS TRUE (the y-axis flag was set in the x-axis loop)
            if(i < min_y[TRACKER_1]) 				// min_y or max_y = is updated with the Y-axis pixel location
                min_y[TRACKER_1] = i;
            else if(i > max_y[TRACKER_1])
                max_y[TRACKER_1] = i;
        }
        if(x->use[TRACKER_2] && inrange_flag_y[TRACKER_2]) {		// ANY TIME A PIXEL IS TRUE (the y-axis flag was set in the x-axis loop)
            if(i < min_y[TRACKER_2]) 				// min_y or max_y = is updated with the Y-axis pixel location
                min_y[TRACKER_2] = i;
            else if(i > max_y[TRACKER_2])
                max_y[TRACKER_2] = i;
        }
        if(x->use[TRACKER_3] && inrange_flag_y[TRACKER_3]) {		// ANY TIME A PIXEL IS TRUE (the y-axis flag was set in the x-axis loop)
            if(i < min_y[TRACKER_3]) 				// min_y or max_y = is updated with the Y-axis pixel location
                min_y[TRACKER_3] = i;
            else if(i > max_y[TRACKER_3])
                max_y[TRACKER_3] = i;
        }
        if(x->use[TRACKER_4] && inrange_flag_y[TRACKER_4]) {		// ANY TIME A PIXEL IS TRUE (the y-axis flag was set in the x-axis loop)
            if(i < min_y[TRACKER_4]) 				// min_y or max_y = is updated with the Y-axis pixel location
                min_y[TRACKER_4] = i;
            else if(i > max_y[TRACKER_4])
                max_y[TRACKER_4] = i;
        }






    }

    // ***************
    // POST PROCESSING
    for(tracker = TRACKER_1; tracker < NUM_TRACKERS; tracker++) {
        if(x->use[tracker]) {
            no_match = true;
            if(min_x[tracker] == 0x7FFFFFFF) {
                min_x[tracker] = -1;
//				goto nomatch;		// This is bad because if tracker1 doesn't match, but tracker 2 does it still skips tracker2!
            }
            else no_match = false;

            if(min_y[tracker] == 0x7FFFFFFF) {
                min_y[tracker] = -1;
//				goto nomatch;
            }
            else no_match = false;

            if(max_x[tracker] == -1) {
                max_x[tracker] = min_x[tracker];
//				goto nomatch;
            }
            else no_match = false;

            if(max_y[tracker] == -1) {
                max_y[tracker] = min_y[tracker];
//				goto nomatch;
            }
            else no_match = false;

            if(no_match) goto nomatch;

            // Normalize
            normalized_bounds[0] = (float)min_x[tracker] / dim[0];
            normalized_bounds[1] = (float)min_y[tracker] / dim[1];
            normalized_bounds[2] = (float)max_x[tracker] / dim[0];
            normalized_bounds[3] = (float)max_y[tracker] / dim[1];

            if(x->output_bounds[tracker]) {
                atom_setlong(&(my_val[0]), tracker+1);
                atom_setsym(&(my_val[1]), gensym("bounds"));
                atom_setfloat(&(my_val[2]), normalized_bounds[0]);
                atom_setfloat(&(my_val[3]), normalized_bounds[1]);
                atom_setfloat(&(my_val[4]), normalized_bounds[2]);
                atom_setfloat(&(my_val[5]), normalized_bounds[3]);
//				outlet_list(x->valout, 0L, 6, &my_val);
                outlet_list(x->valout, 0L, 6, &my_val[0]);
            }
            if(x->output_center[tracker]) {
                atom_setlong(&(my_val[0]), tracker+1);
                atom_setsym(&(my_val[1]),gensym("center"));
                atom_setfloat(&(my_val[2]), (normalized_bounds[2] + normalized_bounds[0]) * 0.5);
                atom_setfloat(&(my_val[3]), (normalized_bounds[3] + normalized_bounds[1]) * 0.5);
//				outlet_list(x->valout, 0L, 4, &my_val);
                outlet_list(x->valout, 0L, 4, &my_val[0]);
            }
            if(x->output_size[tracker]) {
                atom_setlong(&(my_val[0]), tracker+1);
                atom_setsym(&(my_val[1]),gensym("size"));
                atom_setfloat(&(my_val[2]), (normalized_bounds[2] - normalized_bounds[0]) * (normalized_bounds[3] - normalized_bounds[1]));
//				outlet_list(x->valout, 0L, 3, &my_val);
                outlet_list(x->valout, 0L, 3, &my_val[0]);
            }
nomatch:
            ;
        }
    }
    return;
}
Esempio n. 15
0
void testRgb2hsl() {
    image_rgb* rgb = load_image("tests/test.jpg", 1);
    image_hsl* hsl = rgb2hsl(rgb);
    image_rgb* rgb2 = image_rgb_new(2, 2);
    image_rgb* rgb3 = load_image("tests/test.bmp", 1);
    int i, j;
    for (i = 0; i < 3; ++i) {
        for (j = 0; j < 3; ++j) {
            CU_ASSERT_EQUAL(rgb->r[i*3+j], rgb3->r[i*3+j]);
            CU_ASSERT_EQUAL(rgb->g[i*3+j], rgb3->g[i*3+j]);
            CU_ASSERT_EQUAL(rgb->b[i*3+j], rgb3->b[i*3+j]);
        }
    }
    rgb2->r[0] = 255;
    rgb2->r[1] = 220;
    rgb2->r[2] = 100;
    rgb2->r[3] = 3;
    rgb2->g[0] = 245;
    rgb2->g[1] = 200;
    rgb2->g[2] = 155;
    rgb2->g[3] = 3;
    rgb2->b[0] = 2;
    rgb2->b[1] = 200;
    rgb2->b[2] = 100;
    rgb2->b[3] = 3;
    image_hsl* hsl2 = rgb2hsl(rgb2);
    
    CU_ASSERT_DOUBLE_EQUAL(hsl->h[0], 0.1111, 0.0001);
    CU_ASSERT_DOUBLE_EQUAL(hsl->h[1], 0.1111, 0.0001);
    CU_ASSERT_DOUBLE_EQUAL(hsl->h[2], 0.1111, 0.0001);
    CU_ASSERT_DOUBLE_EQUAL(hsl->h[3], 0.1111, 0.0001);
    CU_ASSERT_DOUBLE_EQUAL(hsl->h[4], 0.1111, 0.0001);
    CU_ASSERT_DOUBLE_EQUAL(hsl->h[5], 0.1111, 0.0001);
    CU_ASSERT_DOUBLE_EQUAL(hsl->h[6], 0.1111, 0.0001);
    CU_ASSERT_DOUBLE_EQUAL(hsl->h[7], 0.1111, 0.0001);
    CU_ASSERT_DOUBLE_EQUAL(hsl->h[8], 0.1111, 0.0001);
    CU_ASSERT_DOUBLE_EQUAL(hsl->l[4], 0.01765, 0.0001);
    CU_ASSERT_DOUBLE_EQUAL(hsl->l[5], 0.02549, 0.0001);
    CU_ASSERT_DOUBLE_EQUAL(hsl->s[6], 0.60000, 0.0001);
    CU_ASSERT_DOUBLE_EQUAL(hsl->s[7], 0.33333, 0.0001);
    
    
    CU_ASSERT_DOUBLE_EQUAL(hsl2->h[0], 0.16008, 0.0001);
    CU_ASSERT_DOUBLE_EQUAL(hsl2->h[1], 0.00000, 0.0001);
    CU_ASSERT_DOUBLE_EQUAL(hsl2->h[2], 0.33333, 0.0001);
    CU_ASSERT_DOUBLE_EQUAL(hsl2->h[3], 0.00000, 0.0001);
    CU_ASSERT_DOUBLE_EQUAL(hsl2->s[0], 1.00000, 0.0001);
    CU_ASSERT_DOUBLE_EQUAL(hsl2->s[1], 0.22222, 0.0001);
    CU_ASSERT_DOUBLE_EQUAL(hsl2->s[2], 0.21569, 0.0001);
    CU_ASSERT_DOUBLE_EQUAL(hsl2->s[3], 0.00000, 0.0001);
    CU_ASSERT_DOUBLE_EQUAL(hsl2->l[0], 0.50392, 0.0001);
    CU_ASSERT_DOUBLE_EQUAL(hsl2->l[1], 0.82353, 0.0001);
    CU_ASSERT_DOUBLE_EQUAL(hsl2->l[2], 0.50000, 0.0001);
    CU_ASSERT_DOUBLE_EQUAL(hsl2->l[3], 0.01176, 0.0001);
    
    image_rgb_delete(rgb);
    image_rgb_delete(rgb2);
    image_rgb_delete(rgb3);
    image_hsl_delete(hsl);
    image_hsl_delete(hsl2);
}