CLIPOL: a command line interface to IPOL ======================================== This project has two separate goals: 1) provide a command line interface to ipol articles 2) provide a unified IPOL interface for many languages (numpy, octave, lua, ...) The idea is that each IPOL article can described by a single text file, written in IDL (Ipol Description Language). This file specifies the URL of the source code of the article; the compilation instructions; the names, types and default values of the input and output parameters; and the way to call the downloaded code of the article. EXAMPLE USAGE (in bash) ----------------------- cp lena.png x.png ipol lsd x.png y.asc # line segment detector ipol nlm sigma=20 x.png z.png # non-local means denoiser ipol phs x.png z.png f.tiff # pyramidal horn-schunk optical flow ipol tvl1 x.png z.png g.tiff # TVL1 optical flow EXAMPLE USAGE (in python) ------------------------- import ipol # ipol module import iio # image input/output x = iio.read("lena.png") # x is an array of size 256x256 y = ipol.lsd(x) # y is an array of size 351x7 z = ipol.nlm(x, sigma=20) # z is like x, but denoised f = ipol.phs(x, z) # f is the horn-schunck flow from x to z g = ipol.tvl1(x, z) # f is the TVL1 flow from x to z EXAMPLE IDL ----------- NAME nlm TITLE Non-Local Means Denoising AUTHORS Antoni Buades, Bartomeu Coll, Jean-Michel Morel SRC http://www.ipol.im/pub/art/2011/bcm_nlm/revisions/2021-08-22/nlmeansC.tar.gz BUILD make BUILD cp nlmeans_ipol $BIN/nlm INPUT in image INPUT sigma number 10 # sigma for the denoiser OUTPUT out image RUN nlm $in $sigma 0 $out dummy INSTALLATION ------------ The whole implementation is contained on a single file "ipol.py", which is an executable and importable python script. bash: copy or link the file ipol.py to your path with name "ipol" python: copy the file ipol.py to your python import path also: pip install ipol # does both things FILES ----- The IDL files of each IPOL algorithm are stored on the directory "~/.config/ipol/idl/". This can be created and filled-in manually, and the files can be edited by hand using a text editor. It can also be filled-in automatically by running "ipol download_idls". The downloaded and compiled sources, and the binaries, of an algorithm X are stored on the directory "~/.cache/ipol/X" according to the following hierarchy: ~/.cache/ipol/X/dl/src.tar.gz (original source code of the article) ~/.cache/ipol/X/src/ (decompressed source code tree) ~/.cache/ipol/X/bin/ (binary files associated to the article) ~/.cache/ipol/X/tmp/ (temporary files created on each execution) Each time that we want to run an algorithm "X", the file ~/.config/ipol/idl/X is parsed and the tree under "~/.cache/ipol/X" is created if it didn't already exist. The original source code is downloaded and compiled locally. Then the algorithm is run to create the requested files. Thus, for example, if on a new installation we run $ ipol ace lena.png out1.png $ ipol ace lena.png out2.png The files out1.png and out2.png will be identical (a color-corrected version of the lena image) but the first run will be much slower because the whole source code of the ACE algorithm will be downloaded and compiled. The second run will be very fast. Thus, to try the ACE algorithm with several values of alpha we can do for i in {1..8}; do ipol ace lena.png lena_ace_$i.png alpha=$i done You can delete and edit all the cached and config files by hand. To remove the cache and start anew simply delete the folder ~/.cache/ipol DESIGN PRINCIPLES (in decreasing order of importance) ----------------------------------------------------- 0. the bash and python full interfaces are on the same, single file 1. adding a new ipol wrapper consists in writing a single text file 2. this text file must be language-agnostic 3. all functionalities exposed by the downloaded code can be accessed 4. it must be easy to write wrappers for many languages using exactly the same wrapper text files 5. important targets (in decreasing order): numpy, shell, octave, C, lua, C++ 6. the interface must be as efficient as possible 7. it must be possible to call the original program in "raw" form 8. input parameters are raw strings, their verification is left to the backend 9. no dependency management: the system works only if the user has all the requirements already installed. Otherwise, it fails at build or at run time. X. hacks to compile and run the code are necessary and encouraged in the BUILD and RUN sections of the idl files. This produces a unified database of simple modifications that can be pused upstream to increase the overall portability/reproducibility of the universe. GENERIC INTERFACES ------------------ Each IPOL article exposes a single interface, in the form of a single function with a well-defined signature. The function receives an array of n objects and returns an array of m objects, the numbers n and m are constant and fixed for each article. There are only THREE possible types of objects: - a multidimensional array of floats - a float - a string If you need integer values or booleans, you put them inside floats. Strings are to be avoided unless really necessary (e.g., if your program deals with text).