Jump to content

loupasc

Members
  • Posts

    31
  • Joined

  • Last visited

  • Days Won

    1

loupasc last won the day on May 18 2020

loupasc had the most liked content!

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

loupasc's Achievements

Explorer

Explorer (4/14)

  • First Post
  • Collaborator
  • Week One Done
  • One Month Later
  • One Year In

Recent Badges

29

Reputation

  1. Hello Mighty, I understand you need something to apply an inverse dithering on a scanned picture. I wrote a plugin you could use to filter the texture. Hopes this help !
  2. Version 1.6.7489.24864 Minor improvements (kernel matrix accuracy and to8bit clamp function a bit more efficient).
  3. @Foxxey Danke @Seerose It's my pleasure to contribute here !
  4. Slight edge boost Last version 1.6.7489.24864 [ 06 July 2020 ] Download link > > > Download Location: Effects -> Photo Corresponding source is available in the last post. Plugin description This plugin enhances image edges using unsharp mask method. It provides the possibility to apply sharpen only to the image luminosity in order to avoid chromatic noise amplification. Illustration on a stenope (blurry) photography
  5. Version 1.5.7466.17310 Fix crash with small image using mirror border handling. Improve accuracy of the matrix coefficients ( Math.Sin( k * Pi ) = 0). Source
  6. Version 1.4.7461.19568 Optimization in the rendering method. Test if the rectangle boundary is far enough from the border allowing useless limit tests when getting surface color pixels.
  7. Version 1.3.7456.16099 Computation have been optimized. The kernel matrix has symmetries allowing to divide its storage by 4. Convolution has been optimized too the symmetry allows to factorize multiplications which divide the number of multiplication by four.
  8. After checking FFT results I noticed diamond shaped filter was leaking. There were a bug in the coefficient creation. Here the fixed version v1.2. The results show a better retention of unwanted frequencies. Minor upgrade : The filter cutoff parameter has four states corresponding to the number of lobes of the Sinc functions (4-8-12-16). WaveToolBox.zip
  9. Hi Reptillian, I used ImageMagick to make the spectrum images which are created using FFT. My plugin uses convolution method (Sinc filters). FFT with spectrum mask is a powerful tool and versatile but I think it's hard to get into that. My goal is make a toolkit allowing image processing like FFT but lighter in term of computation resources and easier to use. (Goal is today far from filled )
  10. @Djisves New topic created : https://forums.getpaint.net/topic/116512-reconstruction-filter-tool-box/ Shall I destroy the current topic or let a moderator lock it ?
  11. WaveToolBox Last version 1.5.7466.17310 [ 10 June 2020 ] Download link > > > Download Change log summary: Fix crash with small image using mirror border handling Improve matrix coefficient accuracy Location: Effects -> Advanced. Corresponding source is available in the last post. Plugin description The goal of the proposed plugin is to provide advanced settings for processing image using Sinc filters. It offers the following settings: - Kernel shape (square, disc and diamond) (diamond is not a shape really common) - Basic cutoff settings (Will be improved in future version) - Kernel radius, literally the size of the box filter in pixels - Border handling (uniform color, extend, mirror) - Global contrast The processing may be heavy in case of large radius; optimization is in progress... Graphic user interface Plugin usage - Inverse dithering - Anti-aliasing And the corresponding spectrum (originally for validation purpose but I found it is nice to show) Best regards, WaveToolBox.zip
  12. Hello Djisves, Thanks for the feedback ! I called this plugin tool box because it can be used for many things and I think you're right render may not be a good place (I hesitated a lot in fact). I may change the location to advanced it would be more suitable. I test what I deliver so I can say it's ok to be run. I will fix the menu issue and add a parameter to tune the Sinc filter before delivering in Plugins - Publishing ONLY!. Have a nice day,
  13. Hi, I deliver the first version of the WaveToolBox plugin. The goal is to provide advanced settings for processing image using Sinc filters. This is work in progress but this first version already offers the following settings: - Kernel shape (square, disc and diamond) (diamond is not a shape really common) - Kernel radius, literally the size of the box filter in pixels - Border handling (uniform color, extend, mirror) - Global contrast The processing may be heavy in case of large radius; the plugin is practical but lack of optimization. I place the plugin under Effects -> Render. Here an illustration of the tool: - Inverse dithering - Anti-aliasing And the source code: // Name: WaveToolBox // Submenu: Render // Author: Pascal Ollive // Title: Wave tool box // Version: 1.0 // Desc: Reconstruction filter tool box // Keywords: convolution|kernel|filter // URL: // Help: #region UICode RadioButtonControl kernelShape = 0; // Shape|Square|Disc|Diamond IntSliderControl kernelRadius = 8; // [8,100] Radius RadioButtonControl borderHandling = 2; // Border handling|Uniform|Extend|Mirror IntSliderControl contrastSliderIndex = 5; // [0,10] Contrast #endregion private const double SQRT_2 = 1.41421356237309505; private double[] kernelMatrix = null; private double kernelNorm = 1.0; private static byte to8bit(double x) { if (x < 0) { return 0; } if (x > 255) { return 255; } return (byte) Math.Round(x); } private static double lanczos8(double x) { if (x == 0.0) { return 1.0; } double xMultiplyPI = Math.PI * x; return 8.0 * Math.Sin(xMultiplyPI) * Math.Sin(xMultiplyPI / 8.0) / (xMultiplyPI * xMultiplyPI); } private static double computeLanczosCoef(int i, int j, int radius, byte shape) { // center shift double x = (i - radius + 1); double y = (j - radius + 1); if (shape == 0) { // Square // normalize into lanczos8 window return lanczos8(8.0 * x / radius) * lanczos8(8.0 * y / radius); } if (shape == 1) { // Disc double d = Math.Sqrt(x * x + y * y); if (d < radius) { // normalize into lanczos8 window return lanczos8(8.0 * d / radius); } } if (shape == 2) { // Diamond (45 degrees rotated square) double p = (x + y) * SQRT_2 / 2; if (p < radius) { // normalize into lanczos8 window return lanczos8(8.0 * p / radius) * lanczos8(8.0 * (p - SQRT_2 * y) / radius); } } return 0.0; } private static double[] createLanczosKernel(int radius, byte shape) { int dimension = 2 * radius - 1; double[] matrix = new double[dimension * dimension]; for (int j = 0; j < dimension; j++) { for (int i = 0; i < dimension; i++) { matrix[dimension * j + i] = computeLanczosCoef(i, j, radius, shape); } } return matrix; } private static double getCoefficientSum(double[] matrix) { double result = matrix[0]; for (int i = 1; i < matrix.Length; i++) { result = result + matrix[i]; } return result; } private static int surfaceExtend(int x, int maxValue) { if (x < 0) { return 0; } if (x > maxValue) { return maxValue; } return x; } private static int surfaceMirror(int x, int maxValue) { if (x < 0) { return - x; } if (x > maxValue) { return 2 * maxValue - x; } return x; } private ColorBgra getSafeSurfacePixel(Surface s, int x, int y) { if ((x >= 0) && (y >= 0) && (x < s.Width) && (y < s.Height)) { return s[x, y]; } if (borderHandling > 0) { if (borderHandling == 1) { // Extend return s[surfaceExtend(x, s.Width - 1), surfaceExtend(y, s.Height - 1)]; } // Mirror return s[surfaceMirror(x, s.Width - 1), surfaceMirror(y, s.Height - 1)]; } // Background color return ColorBgra.Black; } private double[] convolve(Surface s, int x, int y, double[] m, int radius) { double[] bgr = new double[3]; int dimension = 2 * radius - 1; int offset = 0; for (int j = 0; j < dimension; j++) { for (int i = 0; i < dimension; i++) { ColorBgra c = getSafeSurfacePixel(s, x + i - radius + 1, y + j - radius + 1); bgr[0] = bgr[0] + c.B * m[offset]; bgr[1] = bgr[1] + c.G * m[offset]; bgr[2] = bgr[2] + c.R * m[offset]; offset = offset + 1; } } return bgr; } private double applyContrast(double x) { return (256 + 10 * (contrastSliderIndex - 5)) * x / 256 - (5 * (contrastSliderIndex - 5)); } void PreRender(Surface dst, Surface src) { kernelMatrix = createLanczosKernel(kernelRadius, kernelShape); kernelNorm = getCoefficientSum(kernelMatrix); } void Render(Surface dst, Surface src, Rectangle rect) { for (int y = rect.Top; y < rect.Bottom; y++) { if (IsCancelRequested) return; for (int x = rect.Left; x < rect.Right; x++) { double[] bgr = convolve(src, x, y, kernelMatrix, kernelRadius); dst[x,y] = ColorBgra.FromBgr(to8bit(applyContrast(bgr[0] / kernelNorm)), to8bit(applyContrast(bgr[1] / kernelNorm)), to8bit(applyContrast(bgr[2] / kernelNorm))); } } } WaveToolBox.zip
×
×
  • Create New...