Skip to main content

JPEG-noise resistant edge density detection tool.

Project description


Python versions: 3.3 and above Build Status PyPI


The goal is to separate high-density information areas from single-color areas and gradients. At the same time, JPEG noises with low luminance dispersion should be perceived as part of these single-color areas and gradients.

I propose a filter based on Flood Fill operation in a local square window with a given width.

The result is a bit like raster methods for edge detection: Sobel, Prewitt, Laplace, Canny operators, but the meaning is different. Let’s give an example.


The Prewitt operator gives the following result. In this picture, I inverted the intensity; it shows white contours in the original.


Basically, there is nothing to prevent selecting a threshold value, such that there were only contours without noise. Then there will be a white space between the close lines.


And the Flood Fill Filter shows the following. The default activation level is 0.45.


It paints with black all areas where it is impossible to fill 45% of the 9x9 window around the pixel. It highlights the noises as well, but most interesting is the following. Let us apply the Flood Fill Filter to the result of the Flood Fill Filter itself, except with an activation level of 0.05 this time. This operation will result in the free-standing points detected in the first step.


Then we exclude all black pixels of the second picture from black pixels of the first picture and obtain the picture which is the solution to the problem as I understand it. This result can be obtained with a single command by adding the --denoise parameter.


The Flood Fill Filter does not provide a recipe for eliminating noise in photos, but I believe that this method of separating simple areas of photos from complex ones will be useful in creating filters that take good care of details in photos. On its basis, a mask can be created that will protect complex noisy fragments of photos from even greater distortion as a result of further processing.

JPEG denoising is a problem for photos only. For illustrations, an effective denoising method — Bilateral filter (it is called “Surface blur” in Adobe Photoshop, “Selective Gaussian Blur” in GIMP) already exists.

Limitations of the method

It will not work automatically if the contrast is increased significantly after JPEG compression. In this case, the --diff parameter should be selected manually (it is 0.08 by default)


pip install flood-fill-filter

# or all user installation:
sudo python3 -m pip install --prefix /usr/local flood-fill-filter


From command line:

flood_fill_filter input.jpg output.png

flood_fill_filter --help

From code:

import flood_fill_filter.flood as flood

input = flood.read_linear(filename)
result = flood.filter(input)            # Two-dimensional NumPy array.
    flood.to_8_bit(result * 255),

Technical details

First, the image is translated to the CIE XYZ color space.

Gamma correction is applied for the luminance component Y. Let’s call the corrected value Yγ.

Yγ above 0.7 is corrected so that the white color becomes equal to 0.75.

Let’s call the resulting value L.

L = Yγ - Yγ * 0.25 * ((Yγ - 0.7) / (1 - 0.7)), Yγ > 0.7
L = Yγ, Yγ ⩽ 0.7

The --diff parameter determines the minimum difference between L₁ и L₂, at which we stop considering the luminance to be the same. That is, with the standard settings, light gray 0.7 and white are considered the same color.

This is a hack that allows ignoring white halos around objects. They can appear in the photo initially or after the Unsharp Mask filter.

The differences of the chromaticity components X and Z are taken into account 4 times weaker than the luminance. This means that at the same luminance, we consider the colors to be the same only if both X and Z components differ by less than 4 * diff.

When luminance is above 0.5, the X and Z sensitivity threshold expands to 8 * diff.

In pixels close to black, the X and Z components are ignored — that is, at the same luminance, we consider the colors to be the same.

Each pixel is filled in four directions: horizontally and vertically, but not diagonally.

Pixels in the fill process are compared to the fill start point, not to the adjacent pixels.

See also


Project details

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flood_fill_filter-1.2.5.tar.gz (32.4 kB view hashes)

Uploaded source

Built Distribution

flood_fill_filter-1.2.5-py3-none-any.whl (35.4 kB view hashes)

Uploaded py3

Supported by

AWS AWS Cloud computing Datadog Datadog Monitoring Facebook / Instagram Facebook / Instagram PSF Sponsor Fastly Fastly CDN Google Google Object Storage and Download Analytics Huawei Huawei PSF Sponsor Microsoft Microsoft PSF Sponsor NVIDIA NVIDIA PSF Sponsor Pingdom Pingdom Monitoring Salesforce Salesforce PSF Sponsor Sentry Sentry Error logging StatusPage StatusPage Status page