X-Git-Url: https://git.sesse.net/?p=movit;a=blobdiff_plain;f=deconvolution_sharpen_effect.h;fp=deconvolution_sharpen_effect.h;h=bc0bbd48ee8e07e896624d08b7deb1a41ce0ea69;hp=0000000000000000000000000000000000000000;hb=42c35394ef92bb5179fc4879cb55b866fd422d28;hpb=c36321a4c199c24a98cf3acef49e986ea65ae3f1 diff --git a/deconvolution_sharpen_effect.h b/deconvolution_sharpen_effect.h new file mode 100644 index 0000000..bc0bbd4 --- /dev/null +++ b/deconvolution_sharpen_effect.h @@ -0,0 +1,56 @@ +#ifndef _DECONVOLUTION_SHARPEN_EFFECT_H +#define _DECONVOLUTION_SHARPEN_EFFECT_H 1 + +// DeconvolutionSharpenEffect is an effect that sharpens by way of deconvolution +// (i.e., trying to reverse the blur kernel, as opposed to just boosting high +// frequencies), more specifically by FIR Wiener filters. It is the same +// algorithm as used by the (now largely abandoned) Refocus plug-in for GIMP, +// and I suspect the same as in Photoshop's “Smart Sharpen” filter. +// The implementation is, however, distinct from either. +// +// The effect gives generally better results than unsharp masking, but can be very +// GPU intensive, and requires a fair bit of tweaking to get good results without +// ringing and/or excessive noise. It should be mentioned that for the larger +// convolutions (e.g. R approaching 10), we should probably move to FFT-based +// convolution algorithms, especially as Mesa's shader compiler starts having +// problems compiling our shader. +// +// We follow the same book as Refocus was implemented from, namely +// +// Jain, Anil K.: “Fundamentals of Digital Image Processing”, Prentice Hall, 1988. + +#include "effect.h" + +class DeconvolutionSharpenEffect : public Effect { +public: + DeconvolutionSharpenEffect(); + virtual std::string effect_type_id() const { return "DeconvolutionSharpenEffect"; } + std::string output_fragment_shader(); + + virtual void inform_input_size(unsigned input_num, unsigned width, unsigned height) + { + this->width = width; + this->height = height; + } + + void set_gl_state(GLuint glsl_program_num, const std::string &prefix, unsigned *sampler_num); + +private: + // Input size. + unsigned width, height; + + // The maximum radius of the (de)convolution kernel. + // Note that since this extends both ways, and we also have a center element, + // the actual convolution matrix will be (2R + 1) x (2R + 1). + // + // Must match the definition in the shader, and as such, cannot be set once + // the chain has been finalized. + int R; + + // The parameters. Typical OK values are circle_radius = 2, gaussian_radius = 0 + // (ie., blur is assumed to be a 2px circle), correlation = 0.95, and noise = 0.01. + // Note that once the radius starts going too far past R, you will get nonsensical results. + float circle_radius, gaussian_radius, correlation, noise; +}; + +#endif // !defined(_DECONVOLUTION_SHARPEN_EFFECT_H)