ImagePyramid<T> gaussian_pyramid(const ImageView<T>& image, const ImagePyramidParams& params = ImagePyramidParams()) { using Scalar = typename ImagePyramid<T>::scalar_type; // Resize the image with the appropriate factor. auto resize_factor = pow(2.f, -params.first_octave_index()); auto I = enlarge(image, resize_factor); // Deduce the new camera sigma with respect to the dilated image. auto camera_sigma = Scalar(params.scale_camera())*resize_factor; // Blur the image so that its new sigma is equal to the initial sigma. auto init_sigma = Scalar(params.scale_initial()); if (camera_sigma < init_sigma) { Scalar sigma = sqrt(init_sigma*init_sigma - camera_sigma*camera_sigma); I = gaussian(I, sigma); } // Deduce the maximum number of octaves. auto l = std::min(image.width(), image.height()); auto b = params.image_padding_size(); // l/2^k > 2b // 2^k < l/(2b) // k < log(l/(2b))/log(2) auto num_octaves = static_cast<int>(log(l/(2.f*b))/log(2.f)); // Shorten names. auto k = Scalar(params.scale_geometric_factor()); auto num_scales = params.num_scales_per_octave(); auto downscale_index = int( floor( log(Scalar(2))/log(k)) ); // Create the image pyramid auto G = ImagePyramid<T>{}; G.reset(num_octaves, num_scales, init_sigma, k); for (auto o = 0; o < num_octaves; ++o) { // Compute the octave scaling factor G.octave_scaling_factor(o) = (o == 0) ? 1.f/resize_factor : G.octave_scaling_factor(o-1)*2; // Compute the gaussians in octave \f$o\f$ Scalar sigma_s_1 = init_sigma; G(0, o) = o == 0 ? I : downscale(G(downscale_index, o - 1), 2); for (auto s = 1; s < num_scales; ++s) { auto sigma = sqrt(k*k*sigma_s_1*sigma_s_1 - sigma_s_1*sigma_s_1); G(s,o) = gaussian(G(s-1,o), sigma); sigma_s_1 *= k; } } // Done! return G; }
static cv::Mat enhance_image(cv::Mat const& src, Settings const& settings, DebugImageWriter & w) { cv::Mat grey; cv::cvtColor(src, grey, CV_RGB2GRAY); cv::Mat enhanced = remove_background(grey, settings, w); w.write("enhanced", enhanced); double const angle = find_optimal_angle(enhanced, settings, w); printf("Best angle: %.2f\n", angle); cv::Mat rotated = rotate_around_center(enhanced, angle); cv::Mat downscaled = downscale(rotated, settings, w); return downscaled; }
IPTR Prop__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg) { struct TagItem *tags,*tag; struct Prop_DATA *data = INST_DATA(cl, obj); int refresh = 0; int only_trigger = 0; for (tags = msg->ops_AttrList; (tag = NextTagItem((const struct TagItem **)&tags)); ) { switch (tag->ti_Tag) { case MUIA_Prop_Entries: if ((IPTR)data->entries != tag->ti_Data) { data->entries = tag->ti_Data; refresh = 1; } else { tag->ti_Tag = TAG_IGNORE; } break; case MUIA_Prop_First: if ((IPTR)data->first != tag->ti_Data) { data->first = tag->ti_Data; refresh = 1; } else { tag->ti_Tag = TAG_IGNORE; } break; case MUIA_Prop_Slider: break; case MUIA_Prop_Visible: if ((IPTR)data->visible != tag->ti_Data) { data->visible = tag->ti_Data; refresh = 1; } else { tag->ti_Tag = TAG_IGNORE; } break; case MUIA_Prop_OnlyTrigger: only_trigger = tag->ti_Data; break; case MUIA_Prop_DeltaFactor: data->deltafactor = tag->ti_Data; break; } } if (data->first < 0) data->first = 0; if (data->prop_object && refresh && !only_trigger) { calcscale16(data); /* Rendering will happen here!! This could make problems with virtual groups, forward this to MUIM_Draw??? */ SetAttrs(data->prop_object, ICA_TARGET, NULL, TAG_DONE); if (SetGadgetAttrs((struct Gadget*)data->prop_object,_window(obj),NULL, PGA_Top,downscale(data, data->first), PGA_Visible,downscale(data, data->visible), PGA_Total,downscale(data, data->entries), TAG_DONE)) RefreshGList((struct Gadget*)data->prop_object, _window(obj), NULL, 1); SetAttrs(data->prop_object, ICA_TARGET, ICTARGET_IDCMP, TAG_DONE); } return DoSuperMethodA(cl,obj,(Msg)msg); }