unsigned int ImagePyramid::init(unsigned int num_levels, const float* scale_factors) { if (num_levels < 1) throw IuException("num_levels out of range (<1)", __FILE__, __FUNCTION__, __LINE__ ); for( unsigned int i = 0; i < num_levels; ++i ) { if ((scale_factors[i] <= 0) || (scale_factors[i] >1)) { printf("Error: Pyramid::Init() level %d\n", i); throw IuException("scale_factor out of range; must be in interval ]0,1[.", __FILE__, __FUNCTION__, __LINE__); } } if (images_ != 0) this->reset(); adaptive_scale_ = true; max_num_levels_ = num_levels; num_levels_ = max_num_levels_; scale_factors_ = new float[num_levels_]; memcpy( scale_factors_, scale_factors, sizeof(float)*num_levels); return num_levels; }
//--------------------------------------------------------------------------- unsigned int ImagePyramid::setImage(iu::Image* image, IuInterpolationType interp_type, cudaStream_t stream) { if (image == 0) { throw IuException("Input image is NULL.", __FILE__, __FUNCTION__, __LINE__); } if (!image->onDevice()) { throw IuException("Currently only device images supported.", __FILE__, __FUNCTION__, __LINE__); } if ((images_ != 0) && ( (images_[0]->size() != image->size()) || (images_[0]->pixelType() != image->pixelType()) )) { this->reset(); this->init(max_num_levels_, image->size(), scale_factor_, size_bound_); } pixel_type_ = image->pixelType(); switch (pixel_type_) { case IU_32F_C1: { if (!images_) this->alloc(image->size(), IU_32F_C1); // *** needed so that always the same mem is used (if already existent) iu::ImageGpu_32f_C1*** cur_images = reinterpret_cast<iu::ImageGpu_32f_C1***>(&images_); #if FAST_REDUCE iu::ImageGpu_32f_C1*** temp_cimages = reinterpret_cast<iu::ImageGpu_32f_C1***>(&temp_images_); iu::ImageGpu_32f_C1*** temp_filter_cimages = reinterpret_cast<iu::ImageGpu_32f_C1***>(&temp_filter_images_); #endif iuprivate::copy(reinterpret_cast<iu::ImageGpu_32f_C1*>(image), (*cur_images)[0]); for (unsigned int i=1; i<num_levels_; i++) { #if FAST_REDUCE iuprivate::reduce((*cur_images)[i-1], (*cur_images)[i], (*temp_cimages)[i-1], (*temp_filter_cimages)[i-1], stream, interp_type, 1, 0); #else iuprivate::reduce((*cur_images)[i-1], (*cur_images)[i], interp_type, 1, 0); #endif } break; } default: throw IuException("Unsupported pixel type. currently supported: 32f_C1", __FILE__, __FUNCTION__, __LINE__); } return num_levels_; }
//--------------------------------------------------------------------------- unsigned int ImagePyramid::setImage(iu::Image* image, IuInterpolationType interp_type) { if (image == 0) { throw IuException("Input image is NULL.", __FILE__, __FUNCTION__, __LINE__); } if (!image->onDevice()) { throw IuException("Currently only device images supported.", __FILE__, __FUNCTION__, __LINE__); } if ((images_ != 0) && ( (images_[0]->size() != image->size()) || (images_[0]->pixelType() != image->pixelType()) )) { this->reset(); this->init(max_num_levels_, image->size(), scale_factor_, size_bound_); } pixel_type_ = image->pixelType(); switch (pixel_type_) { case IU_32F_C1: { // *** needed so that always the same mem is used (if already existent) iu::ImageGpu_32f_C1*** cur_images = reinterpret_cast<iu::ImageGpu_32f_C1***>(&images_); if (images_ == 0) { (*cur_images) = new iu::ImageGpu_32f_C1*[num_levels_]; for (unsigned int i=0; i<num_levels_; i++) { IuSize sz(static_cast<int>(floor(0.5+static_cast<double>(image->width())*static_cast<double>(scale_factors_[i]))), static_cast<int>(floor(0.5+static_cast<double>(image->height())*static_cast<double>(scale_factors_[i])))); (*cur_images)[i] = new iu::ImageGpu_32f_C1(sz); } } iuprivate::copy(reinterpret_cast<iu::ImageGpu_32f_C1*>(image), (*cur_images)[0]); for (unsigned int i=1; i<num_levels_; i++) { iuprivate::reduce((*cur_images)[i-1], (*cur_images)[i], interp_type, 1, 0); } break; } default: throw IuException("Unsupported pixel type. currently supported: 32f_C1", __FILE__, __FUNCTION__, __LINE__); } return num_levels_; }
//--------------------------------------------------------------------------- unsigned int ImagePyramid::init(unsigned int max_num_levels, const IuSize& size, const float& scale_factor, unsigned int size_bound) { if ((scale_factor <= 0) || (scale_factor >=1)) { throw IuException("scale_factor out of range; must be in interval ]0,1[.", __FILE__, __FUNCTION__, __LINE__); } if (images_ != 0) this->reset(); max_num_levels_ = IUMAX(1u, max_num_levels); num_levels_ = max_num_levels_; size_bound_ = IUMAX(1u, size_bound); // calculate the maximum number of levels unsigned int shorter_side = (size.width<size.height) ? size.width : size.height; float ratio = static_cast<float>(shorter_side)/static_cast<float>(size_bound_); // +1 because the original size is level 0 unsigned int possible_num_levels = static_cast<int>( -logf(ratio)/logf(scale_factor)) + 1; if(num_levels_ > possible_num_levels) num_levels_ = possible_num_levels; // init rate for each level scale_factors_ = new float[num_levels_]; for (unsigned int i=0; i<num_levels_; i++) { scale_factors_[i] = pow(scale_factor, static_cast<float>(i)); } return num_levels_; }
void ImagePyramid::alloc(const IuSize &sz, const IuPixelType &type) { switch(type) { case IU_32F_C1: { iu::ImageGpu_32f_C1*** cur_images = reinterpret_cast<iu::ImageGpu_32f_C1***>(&images_); #if FAST_REDUCE iu::ImageGpu_32f_C1*** temp_cimages = reinterpret_cast<iu::ImageGpu_32f_C1***>(&temp_images_); iu::ImageGpu_32f_C1*** temp_filter_cimages = reinterpret_cast<iu::ImageGpu_32f_C1***>(&temp_filter_images_); (*temp_cimages) = new iu::ImageGpu_32f_C1*[num_levels_]; (*temp_filter_cimages) = new iu::ImageGpu_32f_C1*[num_levels_]; #endif (*cur_images) = new iu::ImageGpu_32f_C1*[num_levels_]; for (unsigned int i=0; i<num_levels_; i++) { (*cur_images)[i] = new iu::ImageGpu_32f_C1( sz * scale_factors_[i] ); #if FAST_REDUCE (*temp_cimages)[i] = new iu::ImageGpu_32f_C1( sz * scale_factors_[i] ); (*temp_filter_cimages)[i] = new iu::ImageGpu_32f_C1( sz * scale_factors_[i] ); #endif } break; } default: throw IuException("Unsupported pixel type. currently supported: 32f_C1", __FILE__, __FUNCTION__, __LINE__); } }
//----------------------------------------------------------------------------- void drawLine(iu::Image *image, int x_start, int y_start, int x_end, int y_end, int line_width, float value) { if (image->onDevice()) CUDAdrawLine(image, x_start, y_start, x_end, y_end, line_width, value); else throw IuException("Only GPU images supported.", __FILE__, __FUNCTION__, __LINE__); }
// edge filter + evaluation; device; 32-bit; 4-channel (RGB) void filterEdge(const iu::ImageGpu_32f_C4* src, iu::ImageGpu_32f_C1* dst, const IuRect& roi, float alpha, float beta, float minval) { IuStatus status = cuFilterEdge(src, dst, roi, alpha, beta, minval); if (status != IU_SUCCESS) throw IuException("function returned with an error", __FILE__, __FUNCTION__, __LINE__); }
// edge filter; device; 32-bit; 1-channel void filterEdge(const iu::ImageGpu_32f_C1* src, iu::ImageGpu_32f_C2* dst, const IuRect& roi) { IuStatus status = cuFilterEdge(src, dst, roi); if (status != IU_SUCCESS) throw IuException("function returned with an error", __FILE__, __FUNCTION__, __LINE__); }
// device; 32-bit; 1-channel void cubicBSplinePrefilter(iu::ImageGpu_32f_C1* srcdst) { IuStatus status = cuCubicBSplinePrefilter_32f_C1I(srcdst); if (status != IU_SUCCESS) throw IuException("function returned with an error", __FILE__, __FUNCTION__, __LINE__); }
// device; 32-bit; 4-channel void filterGauss(const iu::ImageGpu_32f_C4* src, iu::ImageGpu_32f_C4* dst, const IuRect& roi, float sigma, int kernel_size) { IuStatus status = cuFilterGauss(src, dst, roi, sigma, kernel_size); if (status != IU_SUCCESS) throw IuException("function returned with an error", __FILE__, __FUNCTION__, __LINE__); }