#ifndef STIM_IMAGE_H #define STIM_IMAGE_H #ifdef JPEG_FOUND #define cimg_use_jpeg //necessary for JPG files #endif #include "CImg.h" #include #include namespace stim{ //This static class provides the STIM interface for loading images // Use this interface for all image management - that way the actual library can be changed without problems //currently this interface uses CImg // T = data type (usually unsigned char) template class image{ cimg_library::CImg img; public: //default constructor image(){ } //constructor (load an image file) image(std::string filename){ img.load(filename.c_str()); } /// Constructor initializes an image to a given size /*image(unsigned int x, unsigned int y = 1, unsigned int z = 1){ img = cimg_library::CImg(x, y, z); }*/ image(unsigned int x, unsigned int y = 1, unsigned int z = 1, unsigned int c = 1){ img = cimg_library::CImg(x, y, z, c); } //Load an image from a file void load(std::string filename){ img.load(filename.c_str()); } //save a file void save(std::string filename){ img.save(filename.c_str()); } //create an image from an interleaved buffer void set_interleaved(T* buffer, unsigned int width, unsigned int height, unsigned int channels = 1){ unsigned char* non_interleaved = (unsigned char*)malloc(width * height * 3); unsigned int S = width * height; for(unsigned int i = 0; i < S; i++){ for(unsigned int c = 0; c < channels; c++){ non_interleaved[i + c * S] = buffer[i * channels + c]; } } img = cimg_library::CImg(non_interleaved, width, height, 1, channels); } //fills an allocated region of memory with non-interleaved data void data_noninterleaved(T* data){ memcpy(data, img.data(), sizeof(T) * size()); } void data_interleaved(T* data){ unsigned int C = channels(); unsigned int X = width() * height(); T* ptr = img.data(); //for each channel for(unsigned int c = 0; c < C; c++) //convert each pixel for(unsigned int x = 0; x < X; x++) data[x * C + c] = ptr[c * X + x]; } image channel(unsigned int c){ //create a new image image single; single.img = img.get_channel(c); return single; } /// Copy the given data to the specified channel /// @param c is the channel number that the data will be copied to /// @param buffer is a pointer to the image to be copied to channel c void set_channel(unsigned int c, T* buffer){ //calculate the number of pixels in a channel unsigned int channel_size = width() * height(); //retreive a pointer to the raw image data T* ptr = img.data() + channel_size * c; //copy the buffer to the specified channel memcpy(ptr, buffer, sizeof(T) * channel_size); } image getslice(unsigned int c){ //create a new image image slice; slice.img = img.get_slice(c); return slice; } unsigned int channels(){ return (unsigned int)img.spectrum(); } unsigned int width(){ return img.width(); } unsigned int height(){ return img.height(); } T* data(){ return img.data(); } //returns the size (number of values) of the image unsigned long size(){ return img.size(); } /// Returns the number of nonzero values unsigned int nnz(){ unsigned long P = width() * height(); unsigned long C = channels(); T* ptr = img.data(); unsigned long n = 0; for(unsigned long p = 0; p < P; p++){ for(unsigned long c = 0; c < C; c++){ if(ptr[c * P + p] > 0){ n++; break; } } } return n; //return the number of nonzero pixels } //this function returns indices of pixels that have nonzero values std::vector sparse_idx(){ std::vector s; //allocate an array s.resize(nnz()); //allocate space in the array unsigned long P = width() * height(); unsigned long C = channels(); T* ptr = img.data(); //get a pointer to the image data unsigned long i = 0; for(unsigned long p = 0; p < P; p++){ for(unsigned long c = 0; c < C; c++){ if(ptr[c * P + p] > 0){ s[i] = p; i++; break; } } } return s; //return the index list } /// Returns the maximum pixel value in the image T maxv(){ float max = 0; unsigned long N = width() * height(); //get the number of pixels for (unsigned long i=0; i max) { max = img.data()[i]; } } return max; } /// Returns the minimum pixel value in the image T minv(){ float min = 0; unsigned long N = width() * height(); //get the number of pixels for (unsigned long i=0; i srgb2lab(){ image rgb; rgb.img = img.get_sRGBtoRGB(); image lab; lab.img = rgb.img.get_RGBtoLab(); return lab; } image convolve2(image mask){ image result; result.img = img.get_convolve(mask.img); return result; } image rotate(float angle, float cx, float cy){ image result; float zoom = 1; unsigned int interpolation = 1; unsigned int boundary = 1; result.img = img.get_rotate (angle, cx, cy, zoom, interpolation, boundary); //result.save("data_output/test_rotate_neum.bmp"); return result; } }; }; //end namespace stim #endif