#ifndef STIM_IMAGE_H #define STIM_IMAGE_H #include #include #include #include namespace stim{ /// This static class provides the STIM interface for loading, saving, and storing 2D images. /// Data is stored in an interleaved (BIP) format (default for saving and loading is RGB). //currently this interface uses CImg // T = data type (usually unsigned char) template class image{ //cimg_library::CImg img; T* img; //pointer to the image data (assumes RGB for loading/saving) size_t R[3]; size_t X(){ return R[1]; } size_t Y(){ return R[2]; } size_t C(){ return R[0]; } void init(){ //initializes all variables, assumes no memory is allocated memset(R, 0, sizeof(size_t) * 3); //set the resolution and number of channels to zero img = NULL; } void unalloc(){ //frees any resources associated with the image if(img) free(img); //if memory has been allocated, free it } void clear(){ //clears all image data unalloc(); //unallocate previous memory init(); //re-initialize the variables } void allocate(){ img = (T*) malloc( sizeof(T) * R[0] * R[1] * R[2] ); //allocate memory } void allocate(size_t x, size_t y, size_t c){ //allocate memory based on the resolution R[0] = c; R[1] = x; R[2] = y; //set the resolution allocate(); //allocate memory } size_t bytes(){ return size() * sizeof(T); } size_t idx(size_t x, size_t y, size_t c = 0){ return y * C() * X() + x * C() + c; } int cv_type(){ if(std::is_same::value) return CV_MAKETYPE(CV_8U, (int)C()); if(std::is_same::value) return CV_MAKETYPE(CV_8S, (int)C()); if(std::is_same::value) return CV_MAKETYPE(CV_16U, (int)C()); if(std::is_same::value) return CV_MAKETYPE(CV_16S, (int)C()); if(std::is_same::value) return CV_MAKETYPE(CV_32S, (int)C()); if(std::is_same::value) return CV_MAKETYPE(CV_32F, (int)C()); if(std::is_same::value) return CV_MAKETYPE(CV_64F, (int)C()); std::cout<<"ERROR in stim::image::cv_type - no valid data type found"< channel(size_t c){ //create a new image image r(R[0], R[1], 1); for(size_t x = 0; x < X(); x++){ for(size_t y = 0; y < Y(); y++){ r.img[r.idx(x, y, c)] = img[idx(x, y, c)]; } } return r; } T& operator()(size_t x, size_t y, size_t c = 0){ return img[idx(x, y, c)]; } /// Set all elements in the image to a given scalar value /// @param v is the value used to set all values in the image image operator=(T v){ size_t N = size(); for(size_t n = 0; n < N; n++) img[n] = v; return *this; } /// 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(T* buffer, size_t c){ size_t x, y; for(y = 0; y < Y(); y++){ for(x = 0; x < X(); x++){ img[idx(x, y, c)] = buffer[c]; } } } size_t channels(){ return C(); } size_t width(){ return X(); } size_t height(){ return Y(); } T* data(){ return img; } //returns the size (number of values) of the image size_t size(){ return C() * X() * Y(); } /// Returns the number of nonzero values size_t nnz(){ size_t N = X() * Y() * C(); size_t nz = 0; for(size_t n = 0; n < N; n++) if(img[n] != 0) nz++; return nz; //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 size_t N = size(); //size_t C = channels(); //T* ptr = img.data(); //get a pointer to the image data size_t i = 0; for(size_t n = 0; n < N; n++){ if(img[n] != 0){ s[i] = n; i++; } } return s; //return the index list } /// Returns the maximum pixel value in the image T maxv(){ T max_val = img[0]; //initialize the maximum value to the first one size_t N = size(); //get the number of pixels for (size_t n=0; n max_val){ //if the value is higher than the current max max_val = img[n]; } } return max; } /// Returns the maximum pixel value in the image T minv(){ T min_val = img[0]; //initialize the maximum value to the first one size_t N = size(); //get the number of pixels for (size_t n=0; n srgb2lab(){ std::cout<<"ERROR stim::image::srgb2lab - function has been broken, re-implement."< convolve2(image mask){ std::cout<<"ERROR stim::image::convolve2 - function has been broken, and shouldn't really be in here."< rotate(float angle, float cx, float cy){ std::cout<<"ERROR stim::image::rotate - function has been broken, and shouldn't really be in here."<