// calculate gradients for the pyramid
// lum_temp gets overwritten!
static void pyramid_calculate_gradient(pyramid_t* pyramid, float* lum_temp)
{
  float* temp = matrix_alloc((pyramid->rows/2)*(pyramid->cols/2));
  float* const temp_saved = temp;

  calculate_gradient(pyramid->cols, pyramid->rows, lum_temp, pyramid->Gx, pyramid->Gy);	

  pyramid = pyramid->next;

  //  int l = 1;
  while(pyramid)
    {
      matrix_downsample(pyramid->prev->cols, pyramid->prev->rows, lum_temp, temp);
		
//     fprintf( stderr, "%d x %d -> %d x %d\n", pyramid->cols, pyramid->rows,
//       prev_pp->cols, prev_pp->rows );
    
//      char name[40];
//      sprintf( name, "ds_%d.pfs", l++ );
//      dump_matrix_to_file( pyramid->cols, pyramid->rows, temp, name );    
		
      calculate_gradient(pyramid->cols, pyramid->rows, temp, pyramid->Gx, pyramid->Gy);
		
      float* const dummy = lum_temp;
      lum_temp = temp;	
      temp = dummy;
			
      pyramid = pyramid->next;
  }

  matrix_free(temp_saved);
}
示例#2
0
PerformanceTerm::FirstOrderPerformance
MeanSquaredError::calculate_first_order_performance(void) const {
// Control sentence

#ifndef NDEBUG

  check();

#endif

  FirstOrderPerformance first_order_performance;

  first_order_performance.performance = calculate_performance();
  first_order_performance.gradient = calculate_gradient();

  return (first_order_performance);
}
示例#3
0
PerformanceTerm::SecondOrderPerformance
MeanSquaredError::calculate_second_order_performance(void) const {
// Control sentence

#ifndef NDEBUG

  check();

#endif

  SecondOrderPerformance second_order_performance;

  second_order_performance.performance = calculate_performance();
  second_order_performance.gradient = calculate_gradient();
  second_order_performance.Hessian = calculate_Hessian();

  return (second_order_performance);
}
示例#4
0
static int read_png(const char *fname, image *image, gradient *g)
{
	int result = 0;
	memset(&image->image, 0, sizeof image->image);
	image->image.version = PNG_IMAGE_VERSION;

	if (png_image_begin_read_from_file(&image->image, image->file_name))
	{
		image->image.format = PNG_FORMAT_RGBA;
		image->stride = PNG_IMAGE_ROW_STRIDE(image->image);
		image->buffer = malloc(PNG_IMAGE_SIZE(image->image));
		image->pixel_bytes = PNG_IMAGE_PIXEL_SIZE(image->image.format);

		if (image->buffer != NULL) {
			if(png_image_finish_read(&image->image, NULL /*background*/,
									 image->buffer, (png_int_32)image->stride,
									 image->colormap)) {

				if(calculate_gradient(image, g))
					result = 1;
				else
					printf("pngtocss: Gradient type not supported\n");
			}
			else {
				fprintf(stderr, "pngtocss: read %s: %s\n", fname,
						image->image.message);

				png_image_free(&image->image);
			}
		}
		else
			fprintf(stderr, "pngtocss: out of memory: %lu bytes\n",
					(unsigned long)PNG_IMAGE_SIZE(image->image));
	}
	else
		/* Failed to read the argument: */
		fprintf(stderr, "pngtocss: %s: %s\n", fname, image->image.message);

	return result;
}
示例#5
0
int main(int argc, char** argv) {
    if (argc < 2) {
        std::cout << "Not enough arguments, Usage: ./seamcarver <path_to_image> <number_of_seams_to_carve>" << "\n";
        std::cout << "If number of seams to carve is left out, the necessary size for object removal will be used instead" << "\n";
        return 1;
    }

    std::cout << "Loading image" << "\n";
    std::string fname = argv[1];
    cimg_library::CImg<unsigned char> image(fname.c_str());
    cimg_library::CImg<unsigned char> draw_image(fname.c_str()); //TODO figure out if i can undo the draw without having second copy

    std::cout << "Calculating luminosity" << "\n";
    std::vector<std::vector<double> > luminosity_map = calculate_luminosity(image);

    std::cout << "Setting energy of image" << "\n";
    std::vector<std::vector<int> > energy_map(luminosity_map.size(), std::vector<int>(luminosity_map[0].size(), 0));
    cimg_library::CImgDisplay energy(draw_image, "Manually set special energy");

    char red[3] = { 255, 0, 0 };
    char green[3] = { 0, 255, 0 };
    int cursor_size = 1;
    while (!energy.is_closed()) {
        energy.wait();
        if (energy.button()) {
            std::vector<char> current_color;
            int energy_val = 0;
            if (energy.button() & 1) { // left click
                if (energy.is_keySPACE()) {
                    flood(draw_image, energy_map, red, -1, energy.mouse_y(), energy.mouse_x());
                    energy_val = -2;
                } else {
                    current_color = std::vector<char>(red, red + 3);
                    energy_val = -1;
                }
            } else if (energy.button() & 2) { // right click
                if (energy.is_keySPACE()) {
                    flood(draw_image, energy_map, green, 1, energy.mouse_y(), energy.mouse_x());
                    energy_val = -2;
                } else {
                    current_color = std::vector<char>(green, green + 3);
                    energy_val = 1;
                }
            }
            if (energy_val != -2) {
                for (int i = -cursor_size; i <= cursor_size; i++) {
                    for (int j = -cursor_size; j <= cursor_size; j++) {
                        if (valid_coord(std::pair<int, int>(energy.mouse_y() + i, energy.mouse_x() + j), energy_map[0].size(), energy_map.size())) {
                            energy_map[energy.mouse_y() + i][energy.mouse_x() + j] = energy_val;
                            draw_image.draw_point(energy.mouse_x() + j, energy.mouse_y() + i, &current_color[0]);
                        }
                    }
                }
            }
        }
        draw_image.display(energy);
    } 

    //TODO
    //change so im_vec stores only pairs of coords, then we copy directly from image to new image?
    std::vector<std::vector<std::vector<char> > > im_vec;
    for (int i = 0; i < image.height(); i++) {
        std::vector<std::vector<char> > row;
        for (int j = 0; j < image.width(); j++) {
            std::vector<char> color;
            color.push_back(image.atXY(j, i, 0, 0));
            color.push_back(image.atXY(j, i, 0, 1));
            color.push_back(image.atXY(j, i, 0, 2));
            row.push_back(color);
        }
        im_vec.push_back(row);
    }

    int numseam = 0;

    if (argc < 3) { // calculate max of max range of x on all y coordinates
        int maxseam = -1;
        for (int i = 0; i < energy_map.size(); i++) {
            int left = 0;
            int right = energy_map[i].size() - 1;
            while (right > 0 && left < energy_map[i].size() && (energy_map[i][left] != -1 || energy_map[i][right] != -1)) {
                if (energy_map[i][left] != -1) left++;
                if (energy_map[i][right] != -1) right--;
            }
            int diff = right - left + 1;
            if (maxseam < diff) {
                maxseam = diff;
            }
        }
        numseam = maxseam;
    } else {
        numseam = atoi(argv[2]);
    }

    for (int master = 0; master < numseam; master++) {
        std::cout << "Computing and removing seam #" << master + 1 << "\r" << std::flush;

        std::vector<std::vector<std::pair<double, double> > > gradient_map = calculate_gradient(luminosity_map);

        //set all energies specified in energy_map to negative/positive on the gradient map
        for (int i = 0; i < energy_map.size(); i++) {
            for (int j = 0; j < energy_map[0].size(); j++) {
                if (energy_map[i][j] != 0) {
                    gradient_map[i][j].second = energy_map[i][j] * 1000;
                }
            }
        }

        double min_seam = DBL_MAX;
        int loc = -1;
        for (int i = 0; i < gradient_map.back().size(); i++) {
            calculate_seam(gradient_map, gradient_map.size() - 1, i);
            if (gradient_map.back()[i].first < min_seam) {
                min_seam = gradient_map.back()[i].first;
                loc = i;
            }
        }

        //remove seams and the object manipulation map coordinates
        std::vector<std::pair<int, int> > toremove = trace_seam(gradient_map, loc);
        for (int i = 0; i < toremove.size(); i++) {
            int row = toremove[i].first;
            int col = toremove[i].second;
            im_vec[row].erase(im_vec[row].begin() + col);
            luminosity_map[row].erase(luminosity_map[row].begin() + col);
            energy_map[row].erase(energy_map[row].begin() + col);
        }
    }

    cimg_library::CImg<unsigned char> newimage(im_vec[0].size(), im_vec.size(), 1, 3);
    for (int i = 0; i < im_vec.size(); i++) {
        for (int j = 0; j < im_vec[i].size(); j++) {
            char color[3] = { im_vec[i][j][0], im_vec[i][j][1], im_vec[i][j][2] };
            newimage.draw_point(j, i, color);
        }
    }

    std::cout << "\n" << "Computation finished, displaying image" << "\n"; 

    cimg_library::CImgDisplay display(newimage, "Seam Carved Image");

    while (!display.is_closed()) {
        display.wait();
        
        newimage.display(display);
    }
}