예제 #1
0
/*
 * @brief Photographic tone-reproduction
 *
 * @param Y input luminance
 * @param L output tonemapped intensities
 * @param use_scales true: local version, false: global version of TMO
 * @param key maps log average luminance to this value (default: 0.18)
 * @param phi sharpening parameter (defaults to 1 - no sharpening)
 * @param num number of scales to use in computation (default: 8)
 * @param low size in pixels of smallest scale (should be kept at 1)
 * @param high size in pixels of largest scale (default 1.6^8 = 43)
 */
void tmo_reinhard02(
  unsigned int width, unsigned int height,
  const float *nY, float *nL, 
  bool use_scales, float key, float phi, 
  int num, int low, int high, bool temporal_coherent )
{
  const pfstmo::Array2D* Y = new pfstmo::Array2D(width, height, const_cast<float*>(nY));
  pfstmo::Array2D* L = new pfstmo::Array2D(width, height, nL);

  int x,y;

  ::key = key;
  ::phi = phi;
  ::range = num;
  ::scale_low = low;
  ::scale_high = high;
  ::use_scales = (use_scales) ? 1 : 0;
  ::temporal_coherent = temporal_coherent;

  cvts.xmax = Y->getCols();
  cvts.ymax = Y->getRows();

  sigma_0      = log (scale_low);
  sigma_1      = log (scale_high);

  compute_bessel();
  allocate_memory ();

  // reading image
  for( y=0 ; y<cvts.ymax ; y++ )
    for( x=0 ; x<cvts.xmax ; x++ )
      image[y][x][0] = (*Y)(x,y);

  copy_luminance();
  scale_to_midtone();

  if( use_scales )
  {
#ifdef APPROXIMATE
    build_pyramid(luminance, cvts.xmax, cvts.ymax);
#else
    compute_fourier_convolution();
#endif
  }

  tonemap_image();

  // saving image
  for( y=0 ; y<cvts.ymax ; y++ )
    for( x=0 ; x<cvts.xmax ; x++ )
      (*L)(x,y) = image[y][x][0];

//  print_parameter_settings();

  deallocate_memory();
  clean_pyramid();

  delete L;
  delete Y;
}
예제 #2
0
Slic::Slic(const vector<unsigned char>& img, int rows_, int cols_, int chan_,
	int K_, int M_, int num_iters_, int max_levels, float scale_factor_) {
#ifdef SLIC_DEBUG
	printf("Slic::constructor\n");
#endif
	// infer *actual* number of superpixels.
	float ar = float(cols_) / float(rows_);
	nx = sqrt(ar*float(K_));
	ny = sqrt(float(K_) / ar);
	K = nx*ny;
	// figure out the size of each superpixel:
	float step_x = float(cols_) / float(nx + 1.0);
	float step_y = float(rows_) / float(ny + 1.0);
	if (scale_factor_ <= 1.0) {
		printf("Invalid scale factor (should be >1). Setting to 2.0\n");
		scale_factor_ = 2.0;
	}
	scale_factor = scale_factor_;
	//-------------------------------------------------------------------------
	// figure out how many levels are needed.
	float mindim = (float)min(step_x, step_y);
	int k = 1;
	while (mindim > 4) {
		mindim /= scale_factor;
		k++;
	}
	if (k < max_levels) {
		printf("Only allowing %d levels\n", k);
	}
	num_levels = min(k, max_levels);
	rows = vector<int>(num_levels);
	cols = vector<int>(num_levels);
	search_region_x = vector<int>(num_levels);
	search_region_y = vector<int>(num_levels);

	rows[0] = rows_;
	cols[0] = cols_;
	search_region_x[0] = round(step_x*2.0);
	search_region_y[0] = round(step_y*2.0);
	for (int i = 1; i < num_levels; ++i) {
		rows[i] = rows[i - 1] / scale_factor;
		cols[i] = cols[i - 1] / scale_factor;
		search_region_x[i] = search_region_x[i - 1] / scale_factor;
		search_region_y[i] = search_region_y[i - 1] / scale_factor;
	}
	chan = chan_; // marshall

	int n = rows_*cols_;
	d = vector<int>(n, INT_MAX); // this can be initialized at the lowest level.
	// will have a vector for this..

	M = M_ * (chan); // change M with number of channels..
	num_iters = num_iters_;
	// initialize data

	// create pyramids for images and assignment vectors
	build_pyramid(img, num_levels);
}
예제 #3
0
// API: open a fancy image
struct fancy_image *fancy_image_open(char *filename, char *options)
{
	// create return struct and its alias
	//struct fancy_image r[1];
	struct fancy_image *r = xmalloc(sizeof*r); // I hate this malloc!
	struct FI *f = (void*)r;

	// process options parameter
	interpret_options(f, options);

	// if "c", do create the file
	if (f->option_creat) {
		if (filename_corresponds_to_tiffo(filename) || f->option_tw > 0)
			create_zero_tiff_file(filename,
					f->option_w, f->option_h,
					f->option_tw, f->option_th,
					f->option_spp, f->option_bps,
					f->option_fmt,
					true, f->option_compressed);
		else
			create_iio_file(filename, f->option_w, f->option_h,
					f->option_spp);
	}

	// read the image
	if (filename_corresponds_to_tiffo(filename)) {
		f->tiffo = true;
		tiff_octaves_init0(f->t, filename, f->megabytes,f->max_octaves);
		if (f->option_write) f->t->option_write = true;
		f->w = f->t->i->w;
		f->h = f->t->i->h;
		f->pd = f->t->i->spp;
		f->no = f->t->noctaves;
	} else {
		f->tiffo = false;
		f->x = iio_read_image_float_vec(filename, &f->w, &f->h, &f->pd);
		f->no = build_pyramid(f, f->max_octaves);
		strncpy(f->x_filename, filename, FILENAME_MAX);
		f->x_changed = false;
	}

	if (f->option_verbose) {
		fprintf(stderr, "FANCY IMAGE \"%s\"\n", filename);
		fprintf(stderr, "\tw = %d\n", f->w);
		fprintf(stderr, "\th = %d\n", f->h);
		fprintf(stderr, "\tpd = %d\n", f->pd);
		fprintf(stderr, "\tno = %d\n", f->no);
		fprintf(stderr, "\n");
		fprintf(stderr, "\tmax_octaves= %d\n", f->max_octaves);
		fprintf(stderr, "\ttiffo = %d\n", f->tiffo);
		fprintf(stderr, "\tmegabytes = %g\n", f->megabytes);
	}

	// return image struct
	return r;
}
예제 #4
0
// API: reload an image (works only for "small", images that can be read whole)
void fancy_image_reload(struct fancy_image *fi)
{
	struct FI *f = (void*)fi;

	if (!f->tiffo && !f->gdal)
	{
		int tmp_w, tmp_h, tmp_pd;
		float *tmp_x = iio_read_image_float_vec(f->x_filename,
				&tmp_w, &tmp_h, &tmp_pd);
		if (!tmp_x)
		{
			fprintf(stderr, "WARNING: could not reload image %s\n",
					f->x_filename);
			return;
		}
		if (tmp_w != f->w || tmp_h != f->h || tmp_pd != f->pd)
		{
			fprintf(stderr, "WARNING: image \"%s\" was resized"
					" from (%d %d %d) to (%d %d %d)\n",
					f->x_filename,
					f->w, f->h, f->pd,
					tmp_w, tmp_h, tmp_pd);
		}
		if (f->no > 1)
			free_pyramid(f);
		else
			free(f->x);
		f->x = tmp_x;
		f->w = tmp_w;
		f->h = tmp_h;
		f->pd = tmp_pd;
		f->no = build_pyramid(f, f->max_octaves);
		f->x_changed = true;

	}

	if (f->tiffo && !f->gdal)
	{
		// TODO: perform some sort of cache invalidation
		fprintf(stderr, "WARNING: tiffo reload not implemented!\n");
	}
}
예제 #5
0
void generic_read(struct FI *f, char *filename)
{
	if (filename_corresponds_to_tiffo(filename)) {
#ifdef FANCY_TIFF
		f->tiffo = true;
		tiff_octaves_init0(f->t, filename, f->megabytes,f->max_octaves);
		if (f->option_write) f->t->option_write = true;
		f->w = f->t->i->w;
		f->h = f->t->i->h;
		f->pd = f->t->i->spp;
		f->no = f->t->noctaves;
#else
		assert(false);
#endif
	} else if (!f->option_write && FORCE_GDAL()) {
#ifdef FANCY_GDAL
		f->gdal = true;
		GDALAllRegister();
		char buf[2*FILENAME_MAX];
		snprintf(buf, 2*FILENAME_MAX, has_prefix(filename, "http://") ||
				has_prefix(filename, "https://") ?
				"/vsicurl/%s" : "%s", filename);
		f->gdal_img = GDALOpen(buf, GA_ReadOnly);
		fprintf(stderr, "gdal_dataset = %p\n", f->gdal_img);
		f->pd = GDALGetRasterCount(f->gdal_img);
		f->w = GDALGetRasterXSize(f->gdal_img);
		f->h = GDALGetRasterYSize(f->gdal_img);
		f->no = 1;
		for (int i = 0; i < f->pd; i++)
			f->gdal_band[i] = GDALGetRasterBand(f->gdal_img, i+1);
#else
		assert(false);
#endif
	} else {
		f->x = iio_read_image_float_vec(filename, &f->w, &f->h, &f->pd);
		f->no = build_pyramid(f, f->max_octaves);
		snprintf(f->x_filename, FILENAME_MAX, "%s", filename);
		f->x_changed = false;
	}
}
예제 #6
0
void Slic::reset_image(const vector<unsigned char>& img) {
	// warning! if the new array has different dimensions (rows/cols/chans)..
	// ..well there are no checks for that.
	build_pyramid(img, num_levels);
}