{"id":26711751,"url":"https://github.com/shermanlo77/modefilter","last_synced_at":"2026-04-28T20:33:45.763Z","repository":{"id":153071921,"uuid":"355699925","full_name":"shermanlo77/modefilter","owner":"shermanlo77","description":"ImageJ plugin, Java and CuPy implementation of the mode filter and empirical null filter. The mode filter is an edge-preserving smoothing filter by taking the mode of the empirical density. ","archived":false,"fork":false,"pushed_at":"2025-06-23T12:06:19.000Z","size":661,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-23T12:26:24.126Z","etag":null,"topics":["cuda","cupy","empirical-null","fiji","filter","image-filter","imagej","jcuda","mode-filter"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shermanlo77.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-04-07T22:38:31.000Z","updated_at":"2024-03-05T14:13:03.000Z","dependencies_parsed_at":"2024-03-04T10:54:58.110Z","dependency_job_id":"bc081f67-a15f-41fc-b248-6fccc38154ad","html_url":"https://github.com/shermanlo77/modefilter","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/shermanlo77/modefilter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shermanlo77%2Fmodefilter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shermanlo77%2Fmodefilter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shermanlo77%2Fmodefilter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shermanlo77%2Fmodefilter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shermanlo77","download_url":"https://codeload.github.com/shermanlo77/modefilter/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shermanlo77%2Fmodefilter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32398742,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-28T19:38:08.556Z","status":"ssl_error","status_checked_at":"2026-04-28T19:37:55.688Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cuda","cupy","empirical-null","fiji","filter","image-filter","imagej","jcuda","mode-filter"],"created_at":"2025-03-27T10:33:43.664Z","updated_at":"2026-04-28T20:33:45.757Z","avatar_url":"https://github.com/shermanlo77.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Mode Filter and Empirical Null Filter\n\n* MIT License - all source code\n* Copyright (c) 2020-2025 Sherman Lo\n\nThe mode filter is an edge-preserving smoothing filter that takes the local mode\nof the empirical density. This may have applications in image processing such as\nimage segmentation. The filter is available:\n\n* As an *ImageJ/Fiji* plugin which uses either the CPU or an *Nvidia* GPU. By\n  extension, developers may use the Java API or the provided CLI\n* As a *Napari* plugin which uses an *Nvidia* GPU only. By extension, developers\n  may integrate it within their Python code\n\nThe *CUDA* bindings to *Java* and *Python* were implemented using *JCuda* and *CuPy*\nrespectively. The use of a GPU speeds up the filtering by a huge margin.\n\nWhere appropriate, please cite the thesis\n\n* Lo, S.E. (2020). *Characterisation of Computed Tomography Noise in Projection\n  Space with Applications to Additive Manufacturing*. PhD thesis, University of\n  Warwick, Department of Statistics.\n\n![images of a Mandrill with a mode filter, of varying radius kernel,\napplied](mandrillExample.jpg)\nThe mode filter was applied to the\n[Mandrill test image](http://sipi.usc.edu/database/database.php?volume=misc).\nTop left to top right, bottom left to bottom right: mandrill test image with\nthe mode filter with a radius of 2, 4, 8, 16, 32, 64, 128 applied.\n\n## Compiling and Installing Instructions\n\nThe instructions for compiling and installing the following are provided:\n\n* *ImageJ/Fiji* plugin using the CPU only\n* *ImageJ/Fiji* plugin using either the CPU or an Nvidia GPU\n* *Napari* plugin using an Nvidia GPU only\n\nIf you wish to use an Nvidia GPU, you will need to identify the architecture of\nyour GPU by looking it up in the\n[CUDA GPU compilation documentation](https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/#gpu-feature-list)\nor other sources such as\n[this](https://arnon.dk/matching-sm-architectures-arch-and-gencode-for-various-nvidia-cards/).\nFor example:\n\n* An *Nvidia V100* has a Volta architecture with code `sm_70`.\n* An *Nvidia GeForce GTX 1660* has a Turing architecture with code `sm_75`.\n* An *Nvidia A100* has an Ampere architecture with code `sm_80`.\n* An *Nvidia H100* has an Ampere architecture with code `sm_90`.\n\nYou will also require the [*Nvidia CUDA Development\nKit*](https://developer.nvidia.com/cuda/toolkit), a version appropriate for your\nGPU, which should include an *nvcc* compiler. Older versions of the *Nvidia CUDA\nDevelopment Kit* can be found in the\n[archive](https://developer.nvidia.com/cuda-toolkit-archive).\n\n### ImageJ (CPU only)\n\n* Download `target.zip` from the\n  [releases](https://github.com/shermanlo77/modefilter/releases) and extract it.\n* Copy `target/Empirical_Null_Filter-*.*.*.jar` into\n  `\u003clocation of ImageJ\u003e/plugins/`\n* Copy the directory (or the contents) `target/libs` to\n  `\u003clocation of ImageJ\u003e/jars`\n\nwhere `\u003clocation of ImageJ\u003e` is the location of your *ImageJ* or *Fiji* software\n\n### ImageJ (CPU and GPU)\n\nCompile the *CUDA* code  into a `.ptx` file by calling `make` and providing your\nGPU architecture. For example, for an *Nvidia A100* with code `sm_80`\n\n```shell\nmake NVCC_ARCH=sm_80\n```\n\nClone this repository and compile the package with\n[*Maven*](https://maven.apache.org/)\n\n```shell\nmvn package\n```\n\nThe compiled files are in the direction `target/`. Copy the following:\n\n* Copy `target/Empirical_Null_Filter-*.*.*.jar` into\n  `\u003clocation of ImageJ\u003e/plugins/`\n* Copy the directory (or the contents) `target/libs` to\n  `\u003clocation of ImageJ\u003e/jars`\n\nwhere `\u003clocation of ImageJ\u003e` is the location of your *ImageJ* or *Fiji* software\n\n### Napari (GPU only)\n\nRequires the latest version of `build`.\n\nCompile the *CUDA* code  into a `.ptx` file by calling `make` and providing your\nGPU architecture. For example, for an *Nvidia A100* with code `sm_80`\n\n```shell\nmake NVCC_ARCH=sm_80\n```\n\nClone this repository and, within a [virtual\nenvironment](https://docs.python.org/3/library/venv.html), install the package\nand *Napari* with *pip* or similarly\n\n```bash\npip install -e .\npip install -e .[cuda12x]\npip install -e .[napari]\n```\n\n#### Troubleshooting *CuPy*\n\nYou may require a version of *CuPy* which uses a specific version of *CUDA*. In\nthat case, for example, you can use `pip install -e .[cuda11x]` to use CUDA 11\ninstead.\n\nPlease refer to `pyproject.toml` and the [CuPy installation\ndocumentation](https://docs.cupy.dev/en/stable/install.html).\n\n## How to Use\n\n### With ImageJ or Napari\n\nThe mode filter should be available under `Plugins`\n\n![Screenshot of the GUI](filter_gui.webp)\n\nThe following options, where available, are:\n\n* Number of (CPU) threads\n  * Number of CPU threads to use when doing mean, median and quantile filtering.\n    These are used as inputs for mode filtering. Defaults to the number of\n    detectable threads.\n  * For the CPU only implementation of the mode filter, this also sets the\n    number of CPU threads when doing mode filtering.\n* Number of initial values\n  * Number of initial values for the Newton-Raphson method. Increase this for\n    more accurate filtering at a price of more computational time. Compared to\n    other options, this has a big effect on the resulting image. The default\n    value is 3 but should be in the order of 50-100 if this filter is to be\n    applied to (non-Gaussian) images.\n* Number of steps\n  * Number of iterations in the Newton-Raphson method. Increase this for more\n    accurate filtering at a price of more computational time.\n* Log tolerance (CPU only)\n  * The tolerance allowed for the Newton-Raphson method to accept the solution.\n    Decrease this for more accurate filtering at a price of more computational\n    time.\n* Block dim x and y (GPU only)\n  * Set the dimensions of the block of threads on the GPU. This affects the\n    performance of the filter. Good suggestions are 16 and 32. It is recommended\n    that the number of threads per block should be a multiple of 32.\n\n### Using the CLI (Java only)\n\nThe mode filter can be used via the terminal by calling the\n`Empirical_Null_Filter-x.x.x.jar` file. To use a GUI for parameter selection\n\n```shell\njava -jar Empirical_Null_Filter-x.x.x.jar gui ['cpu' or 'gpu'] \\\n    \u003cloc of image to filter\u003e\n```\n\nThis will make a GUI appear to select your parameters. Once selected, click OK\nto filter the image. A dialogue box will appear to save the resulting image in\n`.png` format.\n\nTo run the mode filter without a GUI\n\n```shell\njava -jar Empirical_Null_Filter-x.x.x.jar run ['cpu' or 'gpu'] \\\n    \u003cloc of image to filter\u003e \u003cloc to save resulting .png\u003e [options]\n```\n\nwhere the options are\n\n* `-r` radius of the kernel\n* `-n` number of CPU threads\n* `-i` number of initial points for Newton-Raphson\n* `-s` number of steps for Newton-Raphson\n* `-t` stopping condition tolerance for Newton-Raphson (recommend negative\n  number), only for CPU\n* `-x` x block dimension, only for GPU\n* `-y` y block dimension, only for GPU\n\n## Apptainer\n\n[Apptainer](https://apptainer.org/) definition files are provided as a way to\ncompile *CUDA* and *Java* code and install the plugins in *ImageJ* or *Napari*\ninside a container. These may be useful in further troubleshooting.\n\n### Apptainer For ImageJ (CPU)\n\nTo build the container\n\n```shell\napptainer build modefilter-ij-cpu.sif modefilter-ij-cpu.def\n```\n\nTo run *ImageJ*\n\n```shell\napptainer run modefilter-ij-cpu.sif\n```\n\nFor release purposes, the compiled `target/` can be extracted using\n\n```shell\napptainer exec \\\n    modefilter-ij-cpu.sif cp -r /usr/src/modefilter/target \u003cdestination\u003e\n```\n\n### Apptainer For ImageJ (CPU and GPU)\n\nEdit `modefilter-ij-gpu.def` so that `nvcc_arch` has the correct architecture\ncode.\n\nTo build the container\n\n```shell\napptainer build modefilter-ij-gpu.sif modefilter-ij-gpu.def\n```\n\nTo run *ImageJ*\n\n```shell\napptainer run --nv modefilter-ij-gpu.sif\n```\n\n### Apptainer For Napari (GPU only)\n\nEdit `modefilter-napari.def` so that `nvcc_arch` has the correct architecture\ncode and `cupy_version` with the required CuPy version.\n\nOlder versions of CuPy may need an older version of the bootstrapped Ubuntu. For\nexample with `cupy_version=\"cuda11x\"`, you may need to edit to bootstrap to\n`From: ubuntu:22.04`.\n\nTo build the container\n\n```shell\napptainer build modefilter-napari.sif modefilter-napari.def\n```\n\nTo run *Napari*\n\n```shell\napptainer run --nv modefilter-napari.sif\n```\n\n## About the Mode Filter\n\nThe mode filter is an image filter much like the mean filter and the median\nfilter. They process each pixel in an image. For a given pixel, the value of the\npixel is replaced by the mean or median over all pixels within a distance *r*\naway. The mean and median filters can be used in *ImageJ*, resulting in a\nsmoothing of the image.\n\n![Mean, median and mode filter applied to an image of a Mandrill](filters.jpg)\nTop left:\n[Mandrill test image](http://sipi.usc.edu/database/database.php?volume=misc).\nTop right: Mean filter with radius 32. Bottom left: Median filter with\nradius 32. Bottom right: Mode filter with radius 32.\n\nThe mode filter is a by-product of the empirical null filter. Instead of taking\nthe mean or median, the mode is taken, more specifically, the argmax of the\nempirical density. The optimisation problem was solved using the Newton-Raphson\nmethod. Various random initial values were tried to home in on the global\nmaximum. Because the filtered image is expected to be smooth, the different\ninitial values were influenced by neighbouring pixels to aid in the optimisation\nproblem.\n\nThe resulting mode-filtered image gives a smoothed image which has an impasto\neffect and preserved edges. This may have applications in noise removal or image\nsegmentation.\n\nThe mode filter was implemented on the CPU by modifying existing *Java* code\nfrom *ImageJ*. Each thread filters a row of the image in parallel from left to\nright. The solution to one pixel is passed to the pixel to the right. The filter\nwas also implemented on the GPU by writing *CUDA* code which can be compiled and\nread by the *JCuda* package. The image is split into blocks. Within a block,\neach thread filters a pixel and shares its answer with neighbouring pixels\nwithin that block.\n\nOne difficulty is that with the introduction of *CUDA* code, the ability to\n\"compile once, run anywhere\" is difficult to keep hold of. A design choice was\nthat the user is to compile the *CUDA* code into a `.ptx` file. This is then\nfollowed by compiling the *Java* code with the `.ptx` file into a `.jar` file\nwhich can be installed as a Plugin in *ImageJ* or *Fiji*. The compiled `.jar`\nfile can be used by *MATLAB* as well.\n\n## Further Reading and References\n\n* Lo, S.E. (2020). *Characterisation of Computed Tomography Noise in Projection\n  Space with Applications to Additive Manufacturing*. PhD thesis, University of\n  Warwick, Department of Statistics.\n* Efron, B. (2004). Large-scale simultaneous hypothesis testing: The choice of a\n  null hypothesis. *Journal of the American Statistical Association*,\n  99(465):96.\n* Griffin, L. D. (2000). Mean, median and mode filtering of images. *Proceedings\n  of the Royal Society of London A: Mathematical, Physical and Engineering\n  Sciences*, 456(2004):2995–3004.\n* Charles, D. and Davies, E. R. (2003). Properties of the mode filter when\n  applied to colour images. *International Conference on Visual Information\n  Engineering VIE 2003*, pp. 101-104.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshermanlo77%2Fmodefilter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshermanlo77%2Fmodefilter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshermanlo77%2Fmodefilter/lists"}