Subscribe to this thread
Home - General / All posts - A custom 5x5 Unsharp filter for better sharpening
Dimitri


5,491 post(s)
#11-Feb-19 09:14

Here's an adaptation of the custom example filters project that provides a 5x5 Unsharp filter, which does much better sharpening than the classic Sharpen filter in the Transform panel. This works so well I've sent in a suggestion that Unsharp be added to the Transform panel.

A classic Sharpen filter as implemented in the Transform panel is very sensitive to noise. You can see that when applying it to images, where a radius of 1 ( 3x3 matrix) is noisy and a radius of 2 ( 5x5 matrix) or greater is not very useful.

So called "unsharp" filters first apply a Gaussian filter, effectively blurring the image a bit, to wipe out noise, and then recombined with the original. The two steps can be implemented at the same time using a cleverly-computed set of numbers in the matrix. In the example, I've used a 5x5 matrix that's also been precomputed to avoid using scaling calculations. You can download the attached .mxb to get the full text of the query, which I've also inserted below, slightly reformatted to better fit into the forum.

The query is like those in the Custom Filter Examples project in that it uses a parameter to allow you to specify the filter at the beginning of the query, and it defines a processtile function so you can alter the function used more conveniently and legibly. The Value definition of the filter has been formatted so it is easy to see the 5x5 arrangement of numbers. SQL ignores whitespace so you can format queries as you like for clarity.

Since it uses a 5x5 matrix, the query also adds an @radius parameter that allows specifying the radius, 2 in the case of a 5x5 matrix. @radius is then used throughout the query wherever a radius or a border argument is used. That also required adding an extra argument to the processtile function to allow passing the radius into whatever is done within processtile.

The name of the image is hard-wired in the query to the sample image, st_peters_grayscale. To use a different image, use Ctrl-H to change the name to the image being used, and change the Rect property values to the correct Rect size for the image used (those can be found in the image's Properties dialog).

Examples:

Above is the original image, zoomed in to the nave and forecourt of St Peters.

Above is the result of using the Unsharp query to sharpen the image.

Above is the result of using Sharpen in Transform, with a radius of 1 - much more noise.

Following is the query text:

-- $manifold$

--

-- Template for custom 5x5 filters

-- using parameters for filter and radius, and a function

--

-- Unsharp 5x5

VALUE @filter TILE = StringJsonTile('[

-0.00391, -0.01563, -0.02344, -0.01563, -0.00391,

-0.01563, -0.06250, -0.09375, -0.06250, -0.01563,

-0.02344, -0.09375,  1.85938, -0.09375, -0.02344,

-0.01563, -0.06250, -0.09375, -0.06250, -0.01563,

-0.00391, -0.01563, -0.02344, -0.01563, -0.00391

]', 5, 5, 1, true);

VALUE @radius UINT8 = 2;

CREATE TABLE [Unsharp] (

  [X] INT32,

  [Y] INT32,

  [Tile] TILE,

  [mfd_id] INT64,

  INDEX [mfd_id_x] BTREE ([mfd_id]),

  INDEX [X_Y_Tile_x] RTREE ([X][Y][Tile] TILESIZE (128,128) TILETYPE FLOAT64),

  PROPERTY 'FieldTileSize.Tile' '[ 128, 128 ]',

  PROPERTY 'FieldTileType.Tile' 'float64'

);

-- Do not forget to change the Rect values when using other images

CREATE IMAGE [Unsharp Image] (

  PROPERTY 'Table' '[Unsharp]',

  PROPERTY 'FieldTile' 'Tile',

  PROPERTY 'FieldX' 'X',

  PROPERTY 'FieldY' 'Y',

  PROPERTY 'Rect' '[ 0, 0, 1214, 862 ]'

);

FUNCTION processtile(@t TILE, @r UINT8, @f TILE) TILE AS (

  TileFilter(@t, @r, @f)

END;

PRAGMA ('progress.percentnext' = '100');

INSERT INTO [Unsharp] (

  [X][Y],

  [Tile]

SELECT

  [X][Y],

-- Change the image name in the next two lines to use a different image

  CASTV ((TileRemoveBorder(processtile(TileCutBorder([st_peters_grayscale],

 VectorMakeX2([X][Y]), @radius), @radius, @filter), @radius)) AS FLOAT64)

FROM [st_peters_grayscale]

THREADS SystemCpuCount();

TABLE CALL TileUpdatePyramids([Unsharp Image]);

Enjoy!

Attachments:
5x5_Unsharp_Filter_Example.mxb
unsharp_01.png
unsharp_02.png
unsharp_03.png

Manifold User Community Use Agreement Copyright (C) 2007-2017 Manifold Software Limited. All rights reserved.