Guile-CV Reference Manual ************************* This manual documents Guile-CV version 0.4.0. Copyright (C) 2016 - 2023 Free Software Foundation, Inc. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled “GNU Free Documentation License.” Guile-CV Reference Manual Preface Contributors to this Manual Join the GNU Project The Guile-CV License I. Introduction About Guile-CV Obtaining and Installing Guile-CV Contact Information Reporting Bugs II. Using Guile-CV Configuring Guile for Guile-CV Configuring Guile’s repl-print procedure Configuring Guile’s raised exception system Images used in Guile-CV’s documentation Starting Guile-CV III. Guile-CV Core Reference Overview Naming Conventions Abreviations Image Processing Image Structure and Accessors Kernel Structure and Accessors Import Export Histogram Texture Features Particles Filter Process Transform Morphology Segmentation Compose Utilities Support Modules Goops Pi Utils Appendix A GNU Free Documentation License Concept Index Procedure Index Variable Index Type Index Preface ******* This manual describes how to use Guile-CV. It relates particularly to Guile-CV version 0.4.0. Contributors to this Manual =========================== Like Guile-CV itself, the Guile-CV reference manual is a living entity. Right now, the contributor to this manual is: • David Pirotte who is also the author and maintainer of Guile-CV. You are most welcome to join and help. Visit Guile-CV (http://www.gnu.org/software/guile-cv) web site to find out how to get involved. Join the GNU Project ==================== GNU Guile-CV is part of the GNU Operating System, developed by the GNU Project. If you are the author of an awesome program and want to join us in writing Free (libre) Software, please consider making it an official GNU program and become a GNU Maintainer. You can find instructions on how to do this here (https://www.gnu.org/help/evaluation.html). You don’t have a program to contribute? Look at all the other ways you may help (https://www.gnu.org/help/help.html). To learn more about Free (libre) Software, you can read and please share this page (https://gnu.org/philosophy/free-sw.html). The Guile-CV License ==================== Guile-CV is Free Software. Guile-CV is copyrighted, not public domain, and there are restrictions on its distribution or redistribution: • Guile-CV and supporting files are published under the terms of the GNU General Public License version 3 or later. See the file ‘LICENSE’. • This manual is published under the terms of the GNU Free Documentation License (*note GNU Free Documentation License::). You must be aware there is no warranty whatsoever for Guile-CV. This is described in full in the license. I. Introduction *************** About Guile-CV ============== *GNU Guile-CV* Image Processing and Analysis in Guile (http://www.gnu.org/software/guile) a Computer Vision functional programming library Guile-CV (http://www.gnu.org/software/guile-cv) - Image Processing and Analysis in Guile (http://www.gnu.org/software/guile) - is a Computer Vision functional programming library for the Guile (http://www.gnu.org/software/guile) Scheme language. Guile-CV (http://www.gnu.org/software/guile-cv) is based on Vigra (http://ukoethe.github.io/vigra/) (Vision with Generic Algorithms), enhanced with additional algorithms (‘Image Textures’, ‘Delineate’, ‘Reconstruction’ and many more), all accessible through a ‘nice’, ‘clean’ and ‘easy to use’ high level ‘API’. Guile-CV (http://www.gnu.org/software/guile-cv) is natively ‘multi-threaded’, and takes advantage of ‘multiple cores’, using high-level and fine grained application-level ‘parallelism constructs’ available in Guile (http://www.gnu.org/software/guile), based on its support to ‘POSIX threads’. Objective --------- Guile-CV (http://www.gnu.org/software/guile-cv) objective is to be a ‘robust’, ‘reliable’ and ‘fast’ - Image Processing and Analysis - Computer Vision functional programming library for the Guile (http://www.gnu.org/software/guile) Scheme language. Guile-CV (http://www.gnu.org/software/guile-cv) also wants to be ‘easy to use’, ‘study’, ‘modify’ and ‘extend’. Guile-CV (http://www.gnu.org/software/guile-cv) can be used as an ‘educational sofware’, a ‘research toolbox’ but it can also be used ‘'in production'’: Guile-CV (http://www.gnu.org/software/guile-cv) is ‘robust’, ‘reliable’ and ‘fast’, and we will make sure Guile-CV (http://www.gnu.org/software/guile-cv) remains ‘robust’, ‘reliable’ and ‘fast’ as it grows. Savannah -------- Guile-CV (http://www.gnu.org/software/guile-cv) also has a Savannah project page (http://savannah.gnu.org/projects/guile-cv). Obtaining and Installing Guile-CV ================================= Guile-CV (http://www.gnu.org/software/guile-cv) can be obtained from the following archive site (http://ftp.gnu.org/gnu/guile-cv). The file will be named guile-cv-version.tar.gz. The current version is 0.4.0, so the file you should grab is: Dependencies ------------ Guile-CV (http://www.gnu.org/software/guile-cv) needs the following software to run: • Autoconf >= 2.69 • Automake >= 1.14 • Makeinfo >= 6.6 • Guile (http://www.gnu.org/software/guile) >= 2.0.14 [allows 2.2, 3.0 (>= 3.0.7)] • Guile-Lib (http://www.nongnu.org/guile-lib) >= 0.2.5 • Vigra (http://ukoethe.github.io/vigra/) >= 1.11.0 *Note:* If you manually install Vigra (http://ukoethe.github.io/vigra/), make sure you pass the cmake ‑DCMAKE_BUILD_TYPE=RELEASE option, which triggers absolutely essential adequate runtime optimization flags. • Vigra C (https://github.com/BSeppke/vigra_c) >= commit 0af647d08 - Oct 28, 2018 The local minima and maxima interfaces have been improved, and now support the full set of options provided by Vigra, to our request (thank you Benjamin!). In addition there has been a few bugs fixed, including one we detected while working on Guile-CV local minima bindigs. Vigra C - a C wrapper [to some of] the Vigra functionality - is currently only available by cloning its source code git (https://git-scm.com/) repository: there is no release and no versioning scheme either(1). But no big deal, its home page has an ’Installation’ section which guides you step by step. *Notes:* 1. Make sure you pass the cmake ‑DCMAKE_BUILD_TYPE=RELEASE option, which triggers absolutely essential adequate runtime optimization flags; 2. Vigra C says it depends on ‘cmake >= 3.1’, but this is only true if you want to build its documentation, probably not the case. Most distribution still have cmake 2.8, if that is your case, you may safely edit ‘/your/path/vigra_c/CMakeLists.txt’ and downgrade this requirement to the cmake version installed on your machine; 3. Make sure the directory where ‘libvigra_c.so’ has been installed is ’known’, either because it is defined in ‘/etc/ld.so.conf.d’, or you set the environment variable ‘LD_LIBRARY_PATH’, otherwise Guile won’t find it and ‘configure’ will report an error. • LaTex (http://www.latex-project.org/) Any modern latex distribution will do, we use TexLive (https://tug.org/texlive/). Guile-CV will check that it can find the ‘standalone’ documentclass, as well as the following packages: ‘inputenc’, ‘fontenc’, ‘lmodern’, ‘xcolor’, ‘booktabs’, ‘siunitx’, ‘iwona’. Iwona (http://www.tug.dk/FontCatalogue/iwona/): this is the font used to create *note im-histogram:: headers, legend indices and footers. Note that it could be that it is not part of your ’basic’ LaTex distro, on debian for example, iwona is part of the texlive-fonts-extra package. Install from the tarball ------------------------ Assuming you have satisfied the dependencies, open a terminal and proceed with the following steps: cd tar zxf guile-cv-0.4.0.tar.gz cd guile-cv-0.4.0 ./configure [--prefix=/your/prefix] [--with-guile-site=yes] make make install *Special note:* Before you start to use Guile-CV (http://www.gnu.org/software/guile-cv), make sure you read and implement the recommendation made in the manual, section *Note Configuring Guile for Guile-CV::. Happy Guile-CV (http://www.gnu.org/software/guile-cv)! Install from the source ----------------------- Guile-CV (http://www.gnu.org/software/guile-cv) uses Git (https://git-scm.com/) for revision control, hosted on Savannah (http://savannah.gnu.org/projects/guile-cv), you may browse the sources repository here (http://git.savannah.gnu.org/cgit/guile-cv.git). There are currently 2 [important] branches: ‘master’ and ‘devel’. Guile-CV (http://www.gnu.org/software/guile-cv) stable branch is master, developments occur on the devel branch. So, to grab, compile and install from the source, open a terminal and: git clone git://git.savannah.gnu.org/guile-cv.git cd guile-cv ./autogen.sh ./configure [--prefix=/your/prefix] [--with-guile-site=yes] make make install *Special note:* Before you start to use Guile-CV (http://www.gnu.org/software/guile-cv), make sure you read and implement the recommendation made in the manual, section *Note Configuring Guile for Guile-CV::. The above steps ensure you’re using Guile-CV (http://www.gnu.org/software/guile-cv) bleeding edge ‘stable’ version. If you wish to participate to developments, checkout the ‘devel’ branch: git checkout devel Happy ‘hacking!’ *Notes:* 1. The ‘default’ and ‘--prefix’ installation locations for source modules and compiled files (in the absence of ‘--with-guile-site=yes’) are: $(datadir)/guile-cv $(libdir)/guile-cv/guile/$(GUILE_EFFECTIVE_VERSION)/site-ccache If you pass ‘--with-guile-site=yes’, these locations become the Guile global site and site-ccache directories, respectively. The configure step reports these locations as the content of the ‘sitedir’ and ‘siteccachedir’ variables, respectivelly the source modules and compiled files install locations. After installation, you may consult these variables using pkg-config: pkg-config guile-cv-1.0 --variable=sitedir pkg-config guile-cv-1.0 --variable=siteccachedir You will need - unless you have used ‘--with-guile-site=yes’, or unless these locations are already ’known’ by Guile - to define or augment your ‘GUILE_LOAD_PATH’ and ‘GUILE_COMPILED_PATH’ environment variables with these locations, respectively (or ‘%load-path’ and ‘%load-compiled-path’ at run time if you prefer(2) (See Environment Variables (https://www.gnu.org/software/guile/manual/guile.html#Environment-Variables) and Load Path (https://www.gnu.org/software/guile/manual/guile.html#Load-Paths) in the Guile Reference Manual). 2. Guile-CV also installs its ‘libguile-cv.*’ library files, in ‘$(libdir)’. The configure step reports its location as the content of the ‘libdir’ variable, which depends on on the content of the ‘prefix’ and ‘exec_prefix’ variables (also reported). After nstallation, you may consult these variables using pkg-config: pkg-config guile-cv-1.0 --variable=prefix pkg-config guile-cv-1.0 --variable=exec_prefix pkg-config guile-cv-1.0 --variable=libdir You will need - unless the ‘$(libdir)’ location is already ’known’ by your system - to either define or augment your ‘$LD_LIBRARY_PATH’ environment variable, or alter the ‘/etc/ld.so.conf’ (or add a file in ‘/etc/ld.so.conf.d’) and run (as root) ‘ldconfig’, so that Guile-CV finds its ‘libguile-cv.*’ library files(3). 3. To install Guile-CV, you must have write permissions to the default or ‘$(prefix)’ directory and its subdirs, as well as to both Guile’s site and site-ccache directories if ‘--with-guile-site=yes’ was passed. 4. Like for any other GNU Tool Chain compatible software, you may install the documentation locally using ‘make install-info’, ‘make install-html’ and/or ‘make install-pdf’. 5. Last but not least :), Guile-CV comes with a ‘test-suite’, which we recommend you to run (especially before *note Reporting Bugs::): make check ---------- Footnotes ---------- (1) We do our best to check that the libvigra_c installed library does contain the required Guile-CV functionalty though, and these checks are listed as part of our ‘configure’ steps (2) In this case, you may as well decide to either alter your ‘$HOME/.guile’ personal file, or, if you are working in a mult-user environmet, you may also opt for a global configuration. In this case, the file must be named ‘init.scm’ and placed it here (evaluate the following expression in a terminal): ‘guile -c "(display (%global-site-dir))(newline)"’. (3) Contact your administrator if you opt for the second solution but don’t have ‘write’ priviledges on your system. Contact Information =================== Mailing lists ------------- Guile-CV uses the following mailing list: • is for general user help and discussion. • is used to discuss most aspects of Guile-CV, including development and enhancement requests. Please use ‘Guile-CV - ’ to preceed the subject line of Guile-CV related emails, thanks! You can (un)subscribe to the one or both of these mailing lists by following instructions on their respective list information page (https://lists.gnu.org/mailman/listinfo/). IRC --- Most of the time you can find me on irc, channel _#guile_, _#guix_ and _#scheme_ on _irc.libera.chat_, _#introspection_, _#gtk_ and _#clutter_ on _irc.gnome.org_, under the nickname _daviid_. Reporting Bugs ============== Guile-CV uses the following bug reports mailing list: • You can (un)subscribe to the bugs report list by following instructions on the list information page (https://lists.gnu.org/mailman/listinfo/bug-guile-cv). Further information and a list of available commands are available here (https://debbugs.gnu.org/server-control.html). II. Using Guile-CV ****************** Configuring Guile for Guile-CV ============================== Guile must be modified, with respect to two ‘core’ functionalities, before to start to use Guile-CV: (a) its ‘repl-print’ procedure and (b) its ‘raised exception system’. Configuring Guile’s repl-print procedure ---------------------------------------- Guile’s ‘repl-print’ procedure calls ‘(write val)’, which is inadequate for Guile-CV images - or for that matter, for any work that involves very large data structure manipulations - even very small images(1). Fortunately, Guile provides both a simple mechanism to alter the default repl printer and the alternate repl printer procedure we need: ‘truncated-print’. To modify the default repl printer, you may alter (or add if it doesn’t exist) your ‘$HOME/.guile’ file or, if you are working in a multi-user environmet, you may alther (or add if it doesn’t exist) the file named ‘init.scm’ in the Guile global site directory(2).. Which ever solution you choose, add the following lines: (use-modules (ice-9 pretty-print) (system repl common)) (repl-default-option-set! 'print (lambda (repl obj) (truncated-print obj) (newline))) ---------- Footnotes ---------- (1) Even for very small images, using write is inadequate, in a terminal, and will definitely kill your Emacs/Geiser session. Not to mention it will raise your electricity bill :) - till you succeed to delete its process, Emacs will use one core at more then 100%, desperately trying to display hundreds of thousands of floating point values, heating your laptop (if you have a laptop) up to the point you’ll be able to cook an egg on it, and get its fans crasy... You’ve been warned :). (2) The Guile global site directory location may be obtained by evaluating the following expression in a terminal): ‘guile -c "(display (%global-site-dir))(newline)"’. You need write privileges to add or modify this file, contact your system administrator if you’re not in charge of the system you are working on. Configuring Guile’s raised exception system ------------------------------------------- Guile’s core raised exception printers call ‘simple-format’, which is inadequate for Guile-CV images - or for that matter, for any work that involves very large data structure manipulations - even very small images (see the related footnote of the previous section, it explains how ‘inadequate’ this default is for Guile-CV images). Unfortunately, Guile does not provide an easy mechanism to alter its core raised exception printers. This leaves us with no other option but making some changes to the module where those are defined, namely the ‘(ice-9 boot-9)’ Guile’s core module, which then needs to be (re)compiled and (re)installed(1). As the ‘(ice-9 boot-9)’ Guile’s core module has changed from 2.0, 2.2 to 3.0, and still is subject to change any time in the future, we can’t provide a ‘one patch for all’ solution. Instead, we describe the steps to manually update your local version. However if you think it is ‘too much’ for you, get in touch with us, and we will guide you or provide a ‘ready to use module’, depending on your version of Guile. So, let’s first figure out where the ‘(ice-9 boot-9)’ resides on your system(2), in a guile session, enter the following: (string-append (%package-data-dir) "/" (effective-version)) ⇒ $2 = "/opt3/share/guile/3.0" The above returned value is an example of course, just proceed with the value returned by your system. So, the file we need to edit, in our example, is here: /opt3/share/guile/3.0/ice-9/boot-9.scm Edit the above file and: 1. Search for the line ‘(define format simple-format)’, and below, add a line containing ‘(define exception-format simple-format)’, so now your version of the file looks like this: (define format simple-format) (define exception-format simple-format) 2. Replace all occurences of ‘'(format '’ using ‘'(exception-format '’ [note and meticulously respect the presence of the leading open paren ’(’ and the trailing space ’ ’ in both the search and replace expressions]. Save the file. 3. Compile the file - in the following lines, substitute ‘/opt3’ by your ‘$prefix’ value, ‘3.0’ by your guile (effective-version) as well as ‘$HOME’: cd /opt3/share/guile/3.0/ice-9 guild compile boot-9.scm ⊣ ;;; note: source file /opt3/share/guile/3.0/ice-9/boot-9.scm ;;; newer than compiled /opt3/lib/guile/3.0/ccache/ice-9/boot-9.go wrote `$HOME/.cache/guile/ccache/3.0-LE-8-3.A/opt3/share/guile/3.0/ice-9/boot-9.scm.go' Note that the target (compiled) filename is ‘boot-9.scm.go’ - not ‘boot-9.go’. 4. Install the compiled file: cp $HOME/.cache/guile/ccache/3.0-LE-8-3.A/opt3/share/guile/3.0/ice-9/boot-9.scm.go \ /opt3/lib/guile/3.0/ccache/ice-9/boot-9.go Finally, once the above is completed, add the following lines(3) to your ‘$HOME/.guile’ or, if you are working in a multi-user environmet, to the file named ‘init.scm’ in the so-called Guile global site directory (the previous subsection lists the terminal command you need to run to see where that directory is on your system): (define %n-char-limit 400) (define %n-char-limit-fmt-expr (simple-format #f "~~~a@y" %n-char-limit)) (define (rewrite-fmt fmt tell) (let loop ((f "") (b 0)) (let ((next (string-contains-ci fmt tell b))) (if next (loop (if (or (zero? next) (not (char=? #\~ (string-ref fmt (- next 1))))) (string-append f (substring fmt b next) %n-char-limit-fmt-expr) f) (+ next 2)) (string-append f (substring fmt b)))))) (when (defined? 'exception-format) (set! exception-format (lambda (port fmt0 . args) (apply (@ (ice-9 format) format) port (rewrite-fmt (rewrite-fmt fmt0 "~s") "~a") args)))) Feel free to adapt the ‘%n-char-limit’ value to your own taste. You are now ready to use Guile-CV! ---------- Footnotes ---------- (1) Special thanks to Daniel Llorens, who proposed these changes, without which it would just be impossible to work with Guile-CV - or for that matter, any work that involves very large data structure manipulations. (2) You need write privileges to modify this module, contact your admin if you’re not in charge of the system you are working on. (3) Early versions of Guile-CV used to recommend an ‘exception-format’ setting based on ‘truncated-print’, which works as expected if you are using Guile 2.0 or 2.2, but using Guile 3.0, a raised exception would lead to a series of ‘Unwind-only stack overflow exception’ and exit Guile abruptly. Images used in Guile-CV’s documentation ======================================= Images used in Guile-CV’s documentation are distributed with the source and installed here: $prefix/share/doc/guile-cv/images Examples using ‘im-load’ and ‘im-save’ given in this manual, unless a full pathname is specified, assume that these images are available from the guile current working directory, see ‘getcwd’ and ‘chdir’ in Guile’s manual Our best recommendation, at least to start with, is to create a working directory, such as ‘mkdir $HOME/guile-cv/images’, for example, and as you need them, copy the distributed images you are interested in. Starting Guile-CV ================= ^{_} SPECIAL NOTE ^{_} Before you start to use Guile-CV, make sure you read and implement the recommendation made in *note Configuring Guile for Guile-CV:: With the previous *note Images used in Guile-CV's documentation:: recommendations in mind, open a terminal and: cd ~/guile-cv/images guile scheme@(guile-user)> ,use (cv) scheme@(guile-user)> (im-load "sand.tif") ⇒ $2 = (512 512 1 (#f32(125.0 128.0 124.0 118.0 108.0 75.0 76.0 # …))) Or if you use Emacs (https://www.gnu.org/software/emacs) which, coupled with Geiser (http://www.nongnu.org/geiser) absolutely rocks ‘:-)’, then a typical session becomes: fire Emacs M-x cd ⊣ Change default directory: ~/guile-cv/images M-x run-guile scheme@(guile-user)> ,use (cv) scheme@(guile-user)> (im-load "sand.tif") ⇒ $2 = (512 512 1 (#f32(125.0 128.0 124.0 118.0 108.0 75.0 76.0 # …))) Note that to benefit from Emacs’s Tab completion mechanism, while typing image filenames, Emacs itself must be in that directory, hence the above first step ‘M-x cd ...’ III. Guile-CV Core Reference **************************** Overview ======== FIXME - The overview section and its subsections is a mock-up, all need to be actually ’filled’. Naming Conventions ------------------ Vigra Funtions -------------- Guile-CV low level CR procedure names that bind a Vigra functions always start with ‘vigra-’ ... vigra-local-minima vigra-crop-channel ... Abreviations ------------ FIXME. Needs to be ’filled’. Image Processing ================ Image Structure and Accessors ----------------------------- The Guile-CV procedures and methods related to image data structure, creating, accessing and copying images. Procedures ---------- Description ----------- A Guile-CV image is represented by a list containing the following elements: (WIDTH HEIGHT N-CHANNEL IDATA) where IDATA is a list of N-CHANNEL elements, each element being a vector of ‘(* WIDTH HEIGHT)’ cells. More precisely, each element is an ‘srfi-4’ homogeneous numeric vector of 32 bit floats, called ‘f32vector’, knowing that ‘f32’ is the C type ‘float’. The external representation (ie. read syntax) for IDATA vectors is ‘#f32(...)’. As an example, a gray scale image of width 3 and height 2, initialized to 0.0 is represented by the following expression: (3 2 1 (#f32(0.0 0.0 0.0 0.0 0.0 0.0))) The N-CHANNEL is an integer ‘>= 1’, with no limit but the memory size. This said, most Guile-CV procedures and methods expect either GRAY scale (N-CHANNEL=1), or RGB (N-CHANNEL=3) images. For the later, the channels are ‘Red’, ‘Green’ and ‘Blue’ in that order. Guile-CV provides usefull accessors for all these fields. However, very often, you will need them all, in which case your best friend is ‘(ice-9 match)’, here is an example: ,use (cv) (define image (im-make 4 3 3)) (match image ((width height n-chan idata) (match idata ((r g b) ... your code here ...)))) You will find many examples of such a ‘pattern’ in Guile-CV’s source code itself of course, along with some other ‘techniques’ that might be useful, so we invite you to read it, and if you do so: feedback, design and code review is more then welcome! This section describes what is in the module ‘(cv idata)’. Note that the ‘(cv)’ module imports and re-exports, among may others, the public interface of ‘(ice-9 match)’. Procedures ---------- -- Procedure: im-make width height n [value] -- Procedure: im-make-channel width height [value] -- Procedure: im-make-channels width height n [value] Returns a new image, list of channels or channel. Each channel is an srfi-4 homogeneous vector of 32 bit floats (f32vector), of WIDTH by HEIGHT initialized to VALUE. The default VALUE is 0.0 -- Procedure: im-copy image -- Procedure: im-copy-channel channel width height Returns a new fresh copy of IMAGE or CHANNEL. -- Method: im-size image Returns the list of ‘(WIDTH HEIGHT N-CHANNEL)for IMAGE’. -- Method: im-width image -- Method: im-height image -- Method: im-n-channel image -- Method: im-channels image -- Procedure: im-channel image n Returns, respectively the WIDTH, the HEIGHT, N-CHANNEL, CHANNELS or the Nth channel for IMAGE. -- Procedure: im-image? image -- Method: im-gray? image -- Method: im-rgb? image Returns ‘#t’ if IMAGE is respectively a Guile-CV image, a GRAY scale or an RGB image. -- Procedure: im-binary? i1 i2 i3 ... -- Procedure: im-binary-channel? width height c1 c2 c3 ... Returns ‘#t’ if I1 I2 I3 ... or C1 C2 C3 ... respectively are BINARY (Black and White) images or channels respectively. Note that when more then one image or channel is passed, they must all be of the same size. -- Procedure: im-=? [precision] i1 i2 i3 ... -- Procedure: im-=-channel? width height [precision] c1 c2 c3 ... Returns ‘#t’ if I1 I2 I3 ... or C1 C2 C3 ... respectively are of the same size, have the same number of channels that all respectively contain the same values. If the first argument is a number, it is used as the precision to compare pixel values. The default precision value is ‘1.0e-4’. Note that if you are certain your images or channels contain ’discrete’ float values, you may pass ‘0.0’ as the precision to be used, i which case values will be compared using ‘=’ (instead of ‘float=?’, which is faster. -- Procedure: im-ref image i j [k] -- Procedure: im-fast-ref image i j [k] Returns the pixel value stored at position I and J of the IMAGE channel K. The default value for K is 0. IM-FAST-REF does not check the validity of its arguments: use it at your own risk. -- Procedure: im-set! image i j [k] value -- Procedure: im-fast-set! image i j [k] value Returns nothing. Sets the pixel value stored at position I and J of the IMAGE channel K to VALUE. The default value for K is 0. IM-FAST-SET! does not check the validity of its arguments: use it at your own risk. -- Procedure: im-channel-offset i j width height -- Procedure: im-fast-channel-offset i j width Returns the channel offset for the I and J indices, based on the WIDTH and HEIGHT of the channel. This procedure converts the matrix indices I and J to a vector offset for a channel of size WIDTH and HEIGHT. IM-FAST-CHANNEL-OFFSET does not check the validity of its arguments: use it at your own risk. -- Procedure: im-channel-ref channel i j width height -- Procedure: im-fast-channel-ref channel i j width Returns the pixel value stored at position I and J of the channel of size WIDTH and HEIGHT. IM-FAST-CHANNEL-REF does not check the validity of its arguments: use it at your own risk. -- Procedure: im-channel-set! channel i j width height value -- Procedure: im-fast-channel-set! channel i j width value Returns nothing. Sets the pixel at position I and J of CHANNEL of size WIDTH and HEIGHT to VALUE. IM-FAST-CHANNEL-SET! does not check the validity of its arguments: use it at your own risk. -- Procedure: im-collect what i1 i2 i3 ... Returns a list of WHAT collected from I1 I2 I3 ... The valid WHAT synbols are: ‘size’ ‘width’ ‘height’ ‘n-channel’ ‘channels’ ‘chan-0, gray, red’ ‘chan-1, green’ ‘chan-2, blue’ ‘chan-k (*)’ (*): whith k being a valid channel indice, [0 (- n 1)]. Kernel Structure and Accessors ------------------------------ The Guile-CV procedures and methods related to kernel data structure, creating and accessing kernels. Procedures ---------- Description ----------- A Guile-CV kernel (https://en.wikipedia.org/wiki/Kernel_(image_processing)) is represented by a list containing the following elements: (WIDTH HEIGHT KDATA) where KDATA is a vector of ‘(* WIDTH HEIGHT)’ cells. More precisely, KDATA is an ‘srfi-4’ homogeneous numeric vector of 64 bit floats, called ‘f64vector’, knowing that ‘f64’ is the C type ‘double’. The external representation (ie. read syntax) for KDATA vectors is ‘#f64(...)’. As an example, the ‘identity’ kernel of width 3 and height 3, initialized to 0.0 is represented by the following expression: (3 3 #f64(0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0)) The kernel WIDTH and HEIGHT can be different (kernels can be rectangular), but both WIDTH and HEIGHT must be odd values. Guile-CV provides useful accessors for kernel fields, however, if you need them all, just like for accessing image fields, your best friend is ‘(ice-9 match)’, here is an example: ,use (cv) (match kernel ((width height kdata) ... your code here ...)) Note that the ‘(cv)’ module imports and re-exports, among may others, the public interface of ‘(ice-9 match)’. Guile-CV defines a few useful kernels, see *note kernel variables:: at the end of this section, that you both may want to use and reuse: it will be easier, if you need to do so, to define your own kernels reusing an existing one, see the ‘(cv kdata)’ module. Procedures ---------- -- Procedure: k-make width height [values #f] [norm #f] Returns a new kernel. The ‘kdata’ value of this new kernel is an srfi-4 homogeneous numeric vector of 64 bit floats, ‘f64vector’, composed of WIDTH by HEIGHT cells. The optional VALUES argument can be: ‘#f’ ‘kdata’ is initialized to the ‘identity’ kernel (all zeros except the center of the kernel, initialzed to 1) ‘a single value’ all ‘kdata’ cells are initialized using that single value ‘a list of values’ a list of WIDTH by HEIGHT values, used to initialzed ‘kdata’, in the order they are given The optional NORM argument can be: ‘#f’ in this case, ‘kdata’ is not normalized ‘#t’ unless VALUES would be ‘#f’, ‘kdata’ is normalized using ‘(reduce + 0 values)’ ‘a single value’ all ‘kdata’ cells are normalized using that value, which must be a number different from ‘0’ When both VALUES and NORM are passed - which is mandatory if you want to pass NORM (since these are optional arguments, as opposed to keyword arguments) - VALUES must precede NORM on the arguments list. As an example, here is how to define a ‘3 x 3’ normalized mean kernel: ,use (cv) (k-make 3 3 1 #t) ⊣ $2 = (3 3 #f64(0.1111111111111111 0.1111111111111111 # # # # …)) (k-display $2) ⊣ 0.11111 0.11111 0.11111 0.11111 0.11111 0.11111 0.11111 0.11111 0.11111 -- Procedure: k-make-circular-mask radius [value 1] [norm #f] Returns a new ‘circular mask’ kernel. The ‘kdata’ value of this new kernel is an srfi-4 homogeneous numeric vector of 64 bit floats, ‘f64vector’, composed of WIDTH by HEIGHT cells where WIDTH and HEIGHT are ‘equal’ and ‘odd’ values determined by the procedure. The mandatory ‘radius’ argument must be a floating point number satisfying the following predicate: ‘(float>=? radius 0.5)’. The optional NORM argument can be: ‘#f’ in this case, ‘kdata’ is not normalized ‘#t’ ‘kdata’ values are normalized using ‘(* n value)’, where ‘n’ is the number of non zero elements of the circular kernel mask being defined. When both VALUE and NORM are passed - which is mandatory if you want to pass NORM (since these are optional arguments, as opposed to optional keyword arguments) - VALUE must precede NORM on the arguments list. To illustrate, here are the circular kernel masks of RADIUS 0.5, ‘1’, ‘1.5’ respectively: ... (for-each (lambda (i) (k-display (k-make-circular-mask i) #:proc float->int)) '(0.5 1.0 1.5)) ⊣ 0 1 0 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 0 1 1 1 1 1 0 1 1 1 0 0 0 1 0 0 To better illustrate, let’s define a bigger circular kernel mask, transform it to an image and *note im-show:: it: ... (match (k-make-circular-mask 49) ((w h kdata) (list w h 1 (list (f64vector->f32vector kdata))))) ⊣ $6 = (99 99 1 (#f32(0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 # …))) (im-show $6 'scale) And you should see the following image(1) [circular-kernel-mask-49] -- Procedure: k-width kernel -- Procedure: k-height kernel -- Procedure: k-size kernel -- Procedure: k-channel kernel Returns, respectively, the WIDTH, the HEIGHT, the list of WIDTH and HEIGHT or the KDATA for KERNEL. -- Procedure: kernel? kernel Returns ‘#t’ if KERNEL is a Guile-CV kernel. -- Procedure: k-ref kernel i j -- Procedure: k-fast-ref kernel i j Returns the value stored at position I and J of the KERNEL. K-FAST-REF does not check the validity of its arguments: use it at your own risk. -- Procedure: k-set! kernel i j value -- Procedure: k-fast-set! kernel i j value Returns nothing. Sets the value stored at position I and J of the KERNEL to VALUE. K-FAST-SET! does not check the validity of its arguments: use it at your own risk. -- Procedure: k-offset i j width height -- Procedure: k-fast-offset i j width Returns the kernel offset for the I and J indices, based on the WIDTH and HEIGHT of the kernel. This procedure converts the matrix indices I and J to a vector offset for a kernel of size WIDTH and HEIGHT. K-FAST-OFFSET does not check the validity of its arguments: use it at your own risk. -- Procedure: k-display image [#:proc #f] [#:port (current-output-port)] Returns nothing. Displays the content of KERNEL on PORT, applying PROC to each kernel value. ,use (cv) (k-display %k-laplacian) ⊣ 0.37500 0.25000 0.37500 0.25000 -2.50000 0.25000 0.37500 0.25000 0.37500 Variables --------- Notes: (a) the following kernels are merely offered as ‘didactic’ examples, some of these were used ‘in the old days’, but in most cases, you will find and prefer to use a ‘specific’ and ‘modern’ procedure that will give (much) better results, such as, *note im-gaussian-blur::, *note im-gaussian-sharp::, *note im-sharpen:: (a simple sharpening procedure), *note im-canny:: (edge detection) ... and (b) in order to make these definitions easier to read, we’ve added some spaces and newlines. -- Variable: %k-identity (k-display %k-identity #:proc float->int) ⊣ 0 0 0 0 1 0 0 0 0 -- Variable: %k-edge0 (k-make 3 3 '( 1 0 -1 0 0 0 -1 0 1 )) -- Variable: %k-edge1 (k-make 3 3 '( 0 1 0 1 -4 1 0 1 0 )) -- Variable: %k-sharpen (k-make 3 3 '( -1 -1 -1 -1 9 -1 -1 -1 -1 )) -- Variable: %k-mean (k-make 3 3 '( 1 1 1 1 1 1 1 1 1 ) 9) -- Variable: %k-gaussian-blur0 (k-make 3 3 '( 1 2 1 2 4 2 1 2 1 ) 16) -- Variable: %k-gaussian-blur1 (k-make 5 5 '( 1 4 6 4 1 4 16 24 16 4 6 24 36 24 6 4 16 24 16 4 1 4 6 4 1 ) 256) -- Variable: %k-unsharp (k-make 5 5 '( 1 4 6 4 1 4 16 24 16 4 6 24 -476 24 6 4 16 24 16 4 1 4 6 4 1 ) -256) -- Variable: %k-emboss Also called ‘%k-compass’ or ‘%k-directional’, this kind of filter is useful to enhance edges in given directions. With a ‘3 x 3’ kernel, one normally uses filters for ‘0’, ‘45’, ‘90’ and ‘135’ degrees. The various angles are obtained ‘rotating’ the positive and negative values to ‘align’ with the various directions. (k-make 3 3 '( -2 -2 0 -2 6 0 0 0 0 )) -- Variable: %k-laplacian This is a variation of the more traditional Laplacian kernels, that are meant to enhance edges, in this case in an isotropic fashion (non-directional). This the implementation in the Vigra code and it atributes large weights to the diagonal pixels of the kernel. Nevertheless, the total weight is zero. (k-make 3 3 '( 0.375 0.25 0.375 0.25 -2.5 0.25 0.375 0.25 0.375 )) Prewitt filtering ----------------- -- Variable: %k-prewitt-y A 3 x 3 kernel which emphasizes horizontal edges by approximating a vertical gradient. (k-make 3 3 '( 1 1 1 0 0 0 -1 -1 -1 )) -- Variable: %k-prewitt-x A 3 x 3 kernel which emphasizes vertical edges by approximating an horizontal gradient. (k-make 3 3 '( 1 0 -1 1 0 -1 1 0 -1 )) Sobel filtering --------------- Filtering an image using a ‘Sobel filter’ requires a three steps approach: (1) filtering the image using the ‘Sobel y filter’, (2) dito using the ‘Sobel x filter’, and (3) combining the results to obtain ‘Sobel magnitude’: ‘(sqrt (+ (sqrt sobel-y) (sqrt sobel-x))’. -- Variable: %k-sobel-y (k-make 3 3 '( 1 2 1 0 0 0 -1 -2 -1 )) -- Variable: %k-sobel-x (k-make 3 3 '( 1 0 -1 2 0 -2 1 0 -1 )) ---------- Footnotes ---------- (1) The ‘'scale’ optional argument passed to *note im-show::, as its name indicate, is so that kernel values will be scaled, which in this case means that ‘1.0’ values will become ‘255.0’ - otherwise, it would be almost impossible for a human eye to actually see the shape of the circle ... Import Export ------------- The Guile-CV procedures and methods to load, save and query file system images. Procedures ---------- -- Procedure: im-load filename Returns a Guile-CV image. Loads the image pointed by FILENAME and returns a Guile-CV image. FILENAME can either be a GRAY or an RGB image. At this point, Guile-CV supports the following file formats: GIF, TIFF, JPEG, BMP, EXR, HDR, PNM (PBM, PGM, PPM), PNG, SunRaster, KHOROS-VIFF. -- Procedure: im-save image filename [scale #f] Returns #t. Saves IMAGE in FILENAME. The optional SCALE argument can take the following values: ‘#f’ pixel values are ‘clipped’: values ‘< 0’ are saved as ‘0’, values ‘> 255’ are saved as ‘255’, and otherwise are saved unchanged ‘#t’ all pixel values are scaled(1) to the ‘[0 255]’ range The type in which IMAGE is saved is determined by the FILENAME extension, as in the folowing example: (im-load "edx.png") ... (im-save $4 "/tmp/edx.jpg") -- Method: im-size filename Returns the list of ‘(WIDTH HEIGHT N-CHANNEL)for FILENAME’. -- Method: im-width filename -- Method: im-height filename -- Method: im-n-channel filename Returns, respectively the WIDTH, the HEIGHT and the N-CHANNEL for FILENAME. -- Method: im-gray? filename -- Method: im-rgb? filename Returns ‘#t’ if FILENAME is respectively a GRAY scale or an RGB image. ---------- Footnotes ---------- (1) Note that in this particular context, ‘scale’ does not mean a change in dimension, but rather bringing pixel values from the range they occupy in memory to the ‘[0 255]’ range Histogram --------- Other Guile-CV histogram procedures and methods. Procedures ---------- -- Procedure: im-histogram image [#:subtitle “Untitled”] Returns two values: (1) an image; (2) a list (or a list of list) of significant values for IMAGE: one list if IMAGE is GRAY, a list of list of values per channel if IMAGE is RGB. The returned image is composed of a header (title, #:SUBTITLE), either the GRAY or the RGB channel histogram(s) for IMAGE and a footer, which is a table containg, for each channel, the following values: ‘mean’, ‘standard deviation’, ‘minimum’, ‘maximum’, the ‘mode’(1) followed by its ‘value’. Here below, the call sequence and the histogram for the GRAY image ‘sinter.png’ given along with Guile-CV documentation and examples: scheme@(guile-user)> (im-load "sinter.png") $32 = (212 128 1 (#f32(25.0 39.0 50.0 52.0 51.0 45.0 # …))) scheme@(guile-user)> (im-histogram $32 #:subtitle "sinter.png") $34 = (282 271 1 (#f32(255.0 255.0 255.0 255.0 255.0 # …))) $35 = (27136 163.346 75.081 0 243 215 727) [sinter-histogram] Note that histogram images returned by ‘im-histogram’ have no borders, the above histogram has been padded - using ‘(im-padd $34 1 1 1 1 #:color '(96 96 96))’ - for better readability, otherwise the title above and the table below would look as if they were not centered. ---------- Footnotes ---------- (1) The mode is the integer corresponding to the histogram entry that received the maximum of hits, and the value displayed in parens precisely is the number of hits. Texture ------- The Guile-CV procedures and methods related to image texture measures. Procedures ---------- Description ----------- Although introduced a long time ago(1), image texture measures are still very actual, with new research and practicle applications in many areas, as described in this (highly recommended) document(2). Image texture measures are ‘descriptive statistics’, derived from the ‘Gray Level Co-occurrence Matrices (GLCM)’ and its associated set of ‘Gray Level Co-occurrence Probability (GLCP)’ matrices. Guile-CV ‘GLCM’ and ‘GLCP’ data structures are identical to the one used for Guile-CV images (*Note Image Structure and Accessors::). Although they are not images ‘per se’, they are composed of four square matrices (four channels), of size ‘n-gl’ (the number of gray levels to consider), and upon which we (and users) need to run linear algebra procedures, already defined and available in Guile-CV. Guile-CV offers the 11th first ‘texture measures’, out of the 14th originally proposed by Haralick et al., which are the most commonly used and adopted ones. This reference manual assumes you are familiar with the concepts, terminology and mathematic formulas involved in the calculations of ‘GLCM’s, ‘GLCP’s and ‘image texture measures’. If that is not the case, consider carefully reading one or both of the documents cited above (or any other tutorial or reference material of your choice of course). Procedures ---------- -- Procedure: im-texture image n-gl [#:dist 1] [#:p-max 255] [#:use-log2 #f] [#:no-px-y0 #f] Returns a list. The procedure calls *note im-glcp::, passing IMAGE, N-GL (the number of gray levels to consider), DIST (the distance between the ‘reference’ and the ‘neighbour’ pixels) and P-MAX (the IMAGE (pixel) maximum value), then computes and returns a list of the 11th first texture measures proposed by Haralick et al., which are: ‘(h1) uniformity (angular second moment)’ ‘(h2) contrast’ ‘(h3) correlation’ ‘(h4) variance (sum of squares)’ ‘(h5) homogeneity (inverse difference moment)’ ‘(h6) sum average’ ‘(h7) sum variance’ ‘(h8) sum entropy’ ‘(h9) entropy’ ‘(h10) difference variance’ ‘(h11) difference entropy’ The #:USE-LOG2 optional keyword argument, which defaults to ‘#f’, is passed to the internal procedures that calculate the parameters ‘h8’, ‘h9’ and ‘h11’. The original formulas proposed by Haralck and al. use ‘log’, but I have seen a couple of implementations using ‘log2’(3). The #:NO-PX-Y0 optional keyword argument, which defaults to ‘#f’, is passed to the internal procedure that calculate the parameter ‘h10’. For some obscure reason, and only with respect to this parameter, I have seen some implementations eliminating the first element of the so-called ‘Px-y’, an internediate ‘f32vector’ result, which holds, as its first element, the sum of the elements of the main diagnal of the ‘GLCP’(4). -- Procedure: im-glcp image n-gl [#:dist 1] [#:p-max 255] Returns the ‘GLCP’ for IMAGE. The procedure calls *note im-glcm::, passing IMAGE, N-GL (the number of gray levels to consider), DIST (the distance between the ‘reference’ and the ‘neighbour’ pixels) and P-MAX (the IMAGE (pixel) maximum value), adds ‘GLCM'’ (the transposed version of ‘GLCM’, so the result is symmetrical around the diagonal), then computes and returns the ‘GLCP’. The returned ‘GLCP’ is an ‘image’ composed four channels (four square matrices of size N-GL), corresponding to the (symmetrical) Gray Level Co-occurrences expressed as propabibilities, each calculated at a specific ‘angle’, respectively ‘0º’, ‘45º’, ‘90º’, and ‘135º’. -- Procedure: im-glcm image n-gl [#:dist 1] [#:p-max 255] Returns the ‘GLCM’ for IMAGE. The procedure scales the original IMAGE (it brings its values in the range ‘[0 (- n-gl 1)]’), then computes and returns the ‘GLCM’. The returned ‘GLCM’ is an ‘image’ composed four channels (four square matrices of size N-GL), corresponding to the Gray Level Co-occurrences, each calculated at a specific ‘angle’, respectively ‘0º’, ‘45º’, ‘90º’, and ‘135º’. ---------- Footnotes ---------- (1) R. M. Haralick, K. Shanmugam, and I. Dinstein, Textural Features of Image Classification, IEEE Transactions on Systems, Man and Cybernetics, vol. SMC-3, no. 6, Nov. 1973. (2) M. Hall-Beyer, GLCM Texture: A Tutorial v. 3.0 March 2017 (3) Since it is used as a ‘factor’ in all three formulas, the final result obtained using ‘log2’ is equivalent to the result obtained using ‘log’ multiplied by ‘1.4426950408889634’ (4) Guile-CV computes the ‘difference average’ using all elements of the ‘Px-y’, by default, but offers this option as a courtesy, for users who would want to use Guile-CV as an immediate substitute to compute image texture measures for a (large) image set for which they would already have trained a classifier. It is not recommended to use it otherwise. Features -------- The Guile-CV procedures and methods related to image features. Procedures ---------- -- Procedure: im-features image l-image [#:n-label #f] Returns a list of features, one list for each labeled object - including the backgroud - in ascending order. Notes: (a) IMAGE can either be an RGB or a GRAY image; (b) L-IMAGE is the ‘corresponding’ labeled image; (c) when used, the #:N-LABEL optional keyword argument must be total number of label values used in L-IMAGE, as returned by *note im-label:: and *note im-label-all::. The GRAY feature list values are: ‘area’ The labeled object area in pixel ‘left top right bottom’ The coordinates of the ‘bounding box’ labeled object(1) ‘mean-x mean-y’ Also sometimes called the ‘centroid’, these are the average of the x and y coordinates of all of the pixels in the labeled object. These two coordinate values are floating points, representing the ‘mathematical position’ of the mean x and y values of the labeled object ‘min max mean std-dev’ The minimum, maximum, mean and standard gray deviaton labeled object values ‘major-ev-x major-ev-y minor-ev-x minor-ev-y’ Respectively the major and minor eigen vectors (https://en.wikipedia.org/wiki/Eigenvalues_and_eigenvectors) ‘x’ and ‘y’ normalized coordinates(2): ‘(= (sqrt (+ (expt x 2) (expt y 2))) 1)’ ‘major-axis minor-axis’ Respectively the major and minor eigen values (https://en.wikipedia.org/wiki/Eigenvalues_and_eigenvectors), optimized so that they actually correspond to major and minor ‘radius’ of the ellipse covering the same ‘area’ as the particle itself ‘angle’ The angle of the major eigen vector axis, in ‘degrees’ in the trigonometirc circle reference system ‘center-mass-x center-mass-y’ The center of mass ‘x’ and ‘y’ coordinates ‘perimeter’ The labeled object perimeter in pixels ‘skewness kurtosis’ Respectively the skewness (https://en.wikipedia.org/wiki/Skewness) and the kurtosis (https://en.wikipedia.org/wiki/Kurtosis) of the labeled object ‘circularity aspect-ratio roundness’ Respectively the circularity ‘(/ (* 4 %pi area) (expt perimeter 2))’, the aspect ratio ‘(/ major-axis minor-axis)’ and the roundness ‘(/ minor-axis major-axis)’ of the labeled object The RGB feature list values are: ‘area’ The labeled object area in pixel ‘left top right bottom’ The coordinates of the labeled object (the corresponding GRAY feature footnote applies here too of course) ‘mean-x mean-y’ Also sometimes called the ‘centroid’, these are the average of the x and y coordinates of all of the (red green blue) pixels in the labeled object. These two coordinate values are floating points, representing the ‘mathematical position’ of the mean x and y values of tha labeled object ‘min-r min-g min-b max-r max-g max-b mean-r mean-g mean-b std-dev-r std-dev-g std-dev-b’ The minimum, maximum, mean and standard deviaton labeled object values of the red, green and blue channels ‘major-axis minor-axis’ Respectively the major and minor eigen values (https://en.wikipedia.org/wiki/Eigenvalues_and_eigenvectors), optimized so that they actually correspond to major and minor ‘radius’ of the ellipse covering the same ‘area’ as the particle itself ‘angle’ The angle of the major eigen vector axis, in ‘degrees’ in the trigonometirc circle reference system ‘center-mass-x center-mass-y’ The center of mass ‘x’ and ‘y’ coordinates ‘perimeter’ The labeled object perimeter in pixels ‘skewness-r skewness-g skewness-b kurtosis-r kurtosis-g kurtosis-b’ Respectively the skewness (https://en.wikipedia.org/wiki/Skewness) and the kurtosis (https://en.wikipedia.org/wiki/Kurtosis) labeled object values of the red, green and blue channels ‘circularity aspect-ratio roundness’ Respectively the circularity ‘(/ (* 4 %pi area) (expt perimeter 2))’, the aspect ratio ‘(/ major-axis minor-axis)’ and the roundness ‘(/ minor-axis major-axis)’ of the labeled object Though we did not make it public, Guile-CV has an internal feature display procedure that you might be interested to (re)use, so here is an example of a GRAY feature list display: scheme@(guile-user)> ,use (cv) scheme@(guile-user)> (im-load "pp-17-bf.png") $2 = (85 95 3 (#f32(0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 …) …)) scheme@(guile-user)> (im-rgb->gray $2) $3 = (85 95 1 (#f32(0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 # …))) $4 = (0.0 251.0 128.3132714138286 8075) scheme@(guile-user)> (im-threshold $3 136) $5 = (85 95 1 (#f32(0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 # …))) scheme@(guile-user)> (im-label $5) $6 = (85 95 1 (#f32(0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 # …))) $7 = 2 scheme@(guile-user)> (im-features $2 $6) $8 = ((3782 0 0 84 94 43.19196319580078 45.657588958740234 0.0 # …) …) scheme@(guile-user)> ((@@ (cv features) f-display) (match $8 ((bg a) a))) area : 4293 (pixels) left top right bottom : 0 0 84 94 mean-x mean-y : 40.94992 48.18262 min (red, green, blue) : 137.00000 136.00000 135.00000 max (red, green, blue) : 255.00000 250.00000 250.00000 mean (red, green, blue) : 236.13417 232.84999 232.84207 std. dev. (red, green, blue) : 20.23275 19.41402 19.84854 major ev x, y : 0.22202 0.97504 minor ev x, y : 0.97504 -0.22202 major, minor axis : 39.86419 34.27900 (radius) angle : 77.17241 (degrees) center of mass x, y : 40.73749 48.28692 perimeter : 367.74725 skewness (red, green, blue) : -2.90164 -2.99066 -2.91777 kurtosis (red, green, blue) : 8.53371 9.05482 8.61162 circularity : 0.39891 aspect ratio : 1.16293 roundness : 0.85989 As we mentioned above, ‘f-diplay’ is defined in the ‘(cv features)’ module, but it is not exported: in Guile, calling none exported procedure (which should not be ‘abused’) is done using the syntax ‘@@ module-name binding-name’, which in this example translates to ‘(@@ (cv features) f-display)’. ---------- Footnotes ---------- (1) Note that when passed to *note im-crop::, ‘right’ and ‘bottom’ must be increased by 1: ‘(im-crop image left top (+ right 1) (+ bottom 1))’. (2) Note that Vigra calculates and returns these values in the image coordinate system, where the ‘y-axis’ is ‘flipped’ compared to the trigonometric circle ‘traditional’ representation. Guile-CV however transforms and returns these values using the trigonometric circle reference system. Particles --------- The Guile-CV procedures and methods to obtain and clean image particles. Procedures ---------- -- Procedure: im-particles image features [#:clean #t] Returns two values, a list of images (the particles) and a list of their bounding boxes in the original IMAGE. Each returned image is a ‘particle’, which is a subpart of IMAGE determined by its bounding box, given by the ‘left’ ‘top’ ‘right’ ‘bottom’ values of the corresponding ‘entry’ in FEATURES (see *note im-features:: for a complete description of a feature value list. When #:CLEAN is ‘#t’, which is the default, *note im-particle-clean:: is called upon each particle (see below for a description of the expected result). -- Procedure: im-particle-clean particle Returns a new image. Cleaning a PARTICLE (which is an image) means detecting and removing any object(s) that is(are) not connected to the ‘particle’ itself. This procedure is based on the property that in a ‘particle’, which is an (sub)image resulting from a *note im-crop:: based on the bounding box coordinates as returned by ‘im-features’, there precisely is one object that, if you call ‘im-features’ upon PARTICLE, would have its bounding box coordinates being the entire PARTICLE. In other words, if you call ‘im-particle-clean’ upon an image that is not a ‘particle’, the result will just be a black image. Filter ------ The Guile-CV procedures and methods to filter images. Procedures ---------- -- Procedure: im-gaussian-blur image sigma -- Procedure: im-gaussian-blur-channel channel width height sigma Returns a new image or channel. The new image or new channel is the result of the computation of the Gaussian blurring, also known as the Gaussian smoothing, by means of a convolution of IMAGE or CHANNEL with a 2D Gaussian function, where SIGMA is the standard deviation of the Gaussian distribution. -- Procedure: im-gaussian-gradient image sigma -- Procedure: im-gaussian-gradient-channel channel width height sigma Returns a new image or channel. The new image or new channel is the result of the computation of the strength of the first order partial derivatives by means of a convolution of IMAGE or CHANNEL with the first order derivative of a 2D Gaussian function, where SIGMA is the standard deviation of the Gaussian distribution. -- Procedure: im-gaussian-sharp image factor scale -- Procedure: im-gaussian-sharp-channel channel width height factor scale Returns a new image or channel. The new image or new channel is the result of the computation of the Gaussian sharpening: the procedure does (a) perform a Gaussian smoothing at the given SCALE to create a temporary image ‘smooth’ and (b) blends IMAGE and ‘smooth’ according to the formula ‘(- (* (+ factor 1) image) (* smooth factor))’. -- Procedure: im-sharpen image factor -- Procedure: im-sharpen-channel channel width height factor Returns a new image or channel. This procedure performs a ‘simple sharpening’ operation on IMAGE. It actually calls *note im-convolve:: with the following kernel: -1/16 -1/8 -1/16 0 0 0 ( * factor -1/8 3/4 -1/8 ) + 0 1 0 -1/16 -1/8 -1/16 0 0 0 and uses ‘mirror’ as the ‘out of bound strategy’. -- Procedure: im-median-filter image w-width w-height [#:obs 'repeat] -- Procedure: im-median-filter-channel channel width height w-width w-height [#:obs 'repeat] Returns a new image or channel. In the new image or channel, each pixel value is the ‘median’ value of neighboring entries. The pattern of neighbors is called a ‘window’, the size of which is given by ‘w-width’ and ‘w-height’ (see Median Filter (https://en.wikipedia.org/wiki/Median_filter) for more information). Both W-WIDTH and W-HEIGHT must be ‘odd’ numbers, inferior to WIDTH and HEIGHT respectively. The optional keyword argument #:OBS determines the ‘out-of-bound strategy’. Valid #:OBS symbols are: ‘avoid’ do not operate on pixels upon which (centering) the kernel does not fit in the image ‘repeat’ repeat the nearest pixels ‘mirror’ mirror the nearest pixels ‘wrap’ wrap image around (periodic boundary conditions) ‘zero’ out-of-bound pixel values to be ‘0.0’ -- Procedure: im-convolve image kernel [#:obs 'repeat] -- Procedure: im-convolve-channel channel width height kernel k-width k-height [#:obs 'repeat] Returns a new image or channel. The new image or new channel is the result of the convolution (https://en.wikipedia.org/wiki/Kernel_(image_processing)#Convolution) of IMAGE using KERNEL. The kernel (https://en.wikipedia.org/wiki/Kernel_(image_processing)) K-WIDTH and K-HEIGHT values can be different, but they must be ‘odd’ numbers, inferior to WIDTH and HEIGHT respectively. The optional keyword argument #:OBS determines the ‘out-of-bound strategy’. Valid #:OBS symbols are: ‘avoid’ do not operate on pixels upon which (centering) the kernel does not fit in the image ‘clip’ clip the kernel when operating on pixels upon which (centering) the kernel does not fit in the image (this is only useful if the kernel is >= 0 everywhere) ‘repeat’ repeat the nearest pixels ‘mirror’ mirror the nearest pixels ‘wrap’ wrap image around (periodic boundary conditions) ‘zero’ out-of-bound pixel values to be ‘0.0’ Kernel data structure, accessors, procedures and predefined kernels are all described in this node of the Guile-CV manual: *note Kernel Structure and Accessors::. -- Procedure: im-nl-means image arg... -- Procedure: im-nl-means-channel channel width height arg... Returns a new image or channel. The new image or new channel is the result of a non-local means (https://en.wikipedia.org/wiki/Non-local_means) denoising as described here(1). The following table lists the optional keyword arguments and their default values: Policy arguments: ‘#:policy-type 1’ accepts 0 (ratio policy) or 1 (norm policy) ‘#:sigma 15.0’ default to 5.0 if the policy-type is 0 ‘#:mean-ratio 5.0’ default to 0.95 if the policy-type is 0 ‘#:variance-ratio 0.5’ ‘#:epsilon 1.0e-5’ Filter arguments: ‘#:spatial-sigma 2.0’ ‘#:search-radius 3’ ‘#:patch-radius 1’ the patch-radius can be either 1 or 2 ‘#:mean-sigma 1.0’ ‘#:step-size 2’ ‘#:n-iteration 1’ The ‘im-nl-means-channel’ procedure accepts one additional optional keyword argument: ‘#:n-thread (- (current-processor-count) 1)’ FIXME need to describe the parameters ---------- Footnotes ---------- (1) P. Coupe, P. Yger, S. Prima, P. Hellier, C. Kervrann, C. Barillot. An Optimized Blockwise Non Local Means Denoising Filter for 3D Magnetic Resonance Images . IEEE Transactions on Medical Imaging, 27(4):425-441, Avril 2008. Process ------- The Guile-CV procedures and methods to process images. Procedures ---------- -- Procedure: im-threshold image threshold [#:bg 'black] Returns a new BLACK and WHITE image. The IMAGE argument can either be a GRAY or an an RGB image, in which case each pixel is converted to GRAY as it is processed. Valid #:BG values are ‘black’ (the default) and ‘white’. Pixels for which the original value is ‘>=’ THRESHOLD are set to 255.0 if #:BG is ‘'black’, and set to 0.0 if #:BG is ‘'white’. The other pixels are set to 0.0 or 255.0 respectively. -- Procedure: im-scrap image size [#:pred <] [#:con 8] [#:bg 'black] [#:exclude-on-edges #f] Returns a new image. Scraping an image is the operation of removing objects depending on their SIZE (in pixels). When EXCLUDE-ON-EDGES is #t, all objects that are on any edges are also removed. The procedure first calls *note im-label:: using CON and BG, then calls *note im-features::. The ‘area’ feature of each object is then compared to SIZE using PRED and the object is removed if the result is #t. Note that IMAGE must be a binary image. -- Method: im-add image val -- Method: im-add i1 i2 i3 ... -- Method: im-add-channel channel width height val -- Method: im-add-channel width height c1 c2 c3 ... Returns a new image or channel. Performs the scalar addition of IMAGE with VAL or the matrix addition of I1 I2 I3 ... or C1 C2 C3 ... respectively. -- Method: im-subtract image val -- Method: im-subtract i1 i2 i3 ... -- Method: im-subtract-channel channel width height val -- Method: im-subtract-channel width height c1 c2 c3 ... Returns a new image or channel. Performs the scalar subtraction of IMAGE with VAL or the matrix subtraction of I1 I2 I3 ... or C1 C2 C3 ... respectively. -- Method: im-times image val -- Method: im-times i1 i2 i3 ... -- Method: im-times-channel channel width height val -- Method: im-times-channel c1 w1 h1 c2 w2 h2 c3 w3 h3 ... Returns a new image or channel. Performs the scalar multiplication of IMAGE with VAL or the element by element multiplication of I1 I2 I3 ... or C1 C2 C3 ... respectively. -- Procedure: im-mtimes i1 i2 i3 ... -- Procedure: im-mtimes-channel width height c1 c2 c3 ... Returns a new image or channel. Performs matrix multiplication of I1 I2 I3 ... or C1 W1 H1 C2 W2 H2 C3 W3 H3 ... recursively. The number of lines of the next image must equal the number of columns of the previous intermediate result. -- Method: im-divide image val -- Method: im-divide i1 i2 i3 ... -- Method: im-divide-channel channel width height val -- Method: im-divide-channel c1 w1 h1 c2 w2 h2 c3 w3 h3 ... Returns a new image or channel. Performs the scalar division of IMAGE with VAL or the element by element division of I1 I2 I3 ... or C1 C2 C3 ... respectively. It is the user responsibility to insure that none of the C2 C3 ... values is ‘zero’. -- Procedure: im-mdivide i1 i2 i3 ... -- Procedure: im-mdivide-channel width height c1 c2 c3 ... Returns a new image or channel. Performs the matrix multiplication of I1 or C1 by the inverse of I2 I3 ... or C2 C3 ... recursively. The number of lines of the next image must equal the number of columns of the previous intermediate result(1). It is the user responsibility to insure that none of the C2 C3 ... values is ‘zero’. -- Procedure: im-range image -- Procedure: im-range-channel channel width Returns a list of six values ‘(min row col max row col)’ if IMAGE is GRAY, and a list of list of these values if IMAGE is RGB or for any ‘n-chan > 1’ images. -- Procedure: im-min image -- Procedure: im-max image -- Procedure: im-min-channel channel width -- Procedure: im-max-channel channel width Returns three multiple values if IMAGE is GRAY: ‘min row col’ or ‘max row col’ respectively. If IMAGE is RGB or for any ‘n-chan > 1’ images, it returns a list of list of these values. -- Procedure: im-map proc i1 i2 i3 ... -- Procedure: im-map-channel proc width height c1 c2 c3 ... Returns a new image or channel. Apply PROC to each pixel value of each channel of I1 (if only two arguments are given), or to the corresponding pixel values of each channels of i1 i2 i3 ... (if more than two arguments are given). -- Procedure: im-reduce image proc default -- Procedure: im-reduce-channel channel proc default Returns one value if IMAGE is GRAY. If IMAGE is RGB or for any ‘n-chan > 1’, it returns a list of values. If IMAGE is empty, ‘im-reduce’ returns DEFAULT (this is the only use for default). If IMAGE has only one pixel, then the pixel value is what is returned. Otherwise, PROC is called on the pixel values of IMAGE. Each PROC call is ‘(proc elem prev)’, where ‘elem’ is a pixel value from the channel (the second and subsequent pixel values of the channel), and ‘prev’ is the returned value from the previous call to PROC. The first pixel value - for each channel - is the ‘prev’ for the first call to ‘proc’. For example: ,use (cv) (im-load "edx.png") ⊣ $2 = (128 128 1 (#f32(4.0 26.0 102.0 97.0 58.0 10.0 9.0 21.0 # …))) (im-reduce $2 + 0) ⊣ $3 = 556197.0 -- Procedure: im-normalize image [#:value 255.0] -- Procedure: im-normalize-channel channel width height [#:value 255.0] Returns a new normalized image or channel. Normalizing an IMAGE or a CHANNEL consist of dividing all pixels by a value so they all fall in the ‘[0.0 -> 1.0]’ range. The default #:VALUE is ‘255.0’. -- Procedure: im-and i1 i2 i3 ... -- Procedure: im-and-channel width height c1 c2 c3 ... -- Procedure: im-or i1 i2 i3 ... -- Procedure: im-or-channel width height c1 c2 c3 ... -- Procedure: im-xor i1 i2 i3 ... -- Procedure: im-xor-channel width height c1 c2 c3 ... Returns IMAGE if one argument only, otherwise, it returns a new image or channel, as the result of computing the logical ‘AND’, ‘OR’ or ‘XOR’ of all images or channels. In the case of ‘AND’, for all positive results, the pixel values (of each channel) of the new image are set to the one obtained from I1 or C1 respectively, and ‘0.0’ otherwise. In the case of ‘OR’, the pixel values (of each channel) of the new image are set to the one obtained from the first non zero II or CI respectively, otherwise it is set to ‘0.0’. In the case of ‘XOR’, the pixel values (of each channel) of the new image are set to the value obtained from successively computing ‘(logior (logand a (- 255 b)) (logand (- 255 a) b))’ where ‘a’ would be the previous result and ‘b’ the current ‘image’ or ‘channel’ pixel value, until all images passed in arguments have been processed(2). All images must have the same ‘width’, ‘height’ and ‘n-channel’. There are, of course, scientific use and examples of images logical ‘XOR’, and that is why Guile-CV (http://www.gnu.org/software/guile-cv) is being developed for, but let’s have a bit of fun here, and see if our levitating GNU likes apples! [emacs-1] ---------- Footnotes ---------- (1) Technically speaking, there is no such thing as matrix division. Dividing a matrix by another matrix is an undefined function. The closest equivalent is to multiply the matrix by the inverse of the other matrix. (2) Note that there is no mathematically valid ‘XOR’ operation on floating points, hence as they are ‘accessed’, pixel values are converted to integer, using ‘float->int’, defined in the ‘(cv support libguile-cv)’ module). Transform --------- The Guile-CV procedures and methods to transform images. Procedures ---------- -- Procedure: im-rgba->rgb image [#:bg '(0.0 0.0 0.0)] -- Procedure: im-rgba->gray image [#:bg '(0.0 0.0 0.0)] -- Procedure: im-rgb->gray image Returns a new RGB or GRAY image. In the RGBA case, IMAGE channels are first normalized. The new RGB channels are obtained by applying the following pseudo code algorithm: R = (((1 - Source.A) * BG.R) + (Source.A * Source.R)) * 255.0 G = (((1 - Source.A) * BG.G) + (Source.A * Source.G)) * 255.0 B = (((1 - Source.A) * BG.B) + (Source.A * Source.B)) * 255.0 -- Procedure: im-resize image new-width new-height [#:i-mode 'bilinear] -- Procedure: im-resize-channel channel width height new-width new-height [#:i-mode 'bilinear] Returns a new image or chanbnel resized to NEW-WIDTH, NEW-HEIGHT. The interpolation mode #:I-MODE, can be one of: ‘none’ ‘bilinear’ ‘biquadratic’ ‘bicubic’ ‘? (fixme)’ -- Procedure: im-rotate image angle [#:i-mode 'bilinear] -- Procedure: im-rotate-channel channel width height angle [#:i-mode 'bilinear] Returns a new image or channel rotated by ANGLE. The ANGLE is in degrees: ‘+/-[0.0 360.0]’. It is neccessary, for rotations other than multiples of 90°, to recalculate the target coordinates, since after the rotation, they might be floats. The ’next neighbor’ interpolation possible modes, #:I-MODE, are: ‘bilinear’ ‘biquadratic’ ‘bicubic’ ‘? (fixme)’ -- Procedure: im-flip image plane -- Procedure: im-flip-channel channel width height plane Returns a new image or channel flipped according to the selected PLANE. Valid flipping PLANE values are: ‘hori horizontal’ ‘vert vertical’ ‘both’ -- Procedure: im-invert image -- Procedure: im-invert-channel channel width height Returns a new inversed image or channel. Calculating the inverse of an IMAGE or a CHANNEL consist of applying the exponent function, ‘expt’, to all pixel values, raising them to the power of -1. -- Procedure: im-transpose image -- Procedure: im-transpose-channel channel width height Returns a new tranposed image or channel. Transposing an IMAGE or a CHANNEL consist of flipping it over its main diagonal. In the transposed result, switched in size, row values are the original column values and column values are the original row values. -- Procedure: im-complement image Returns a new image. This procedure computes the mathematical complement of IMAGE, which for Guile-CV means that for each pixel of each channel, the new value is ‘(- 255.0 pixel-value)’. -- Procedure: im-clip image [#:lower 0.0] [#:upper 255.0] -- Procedure: im-clip-channel channel width height [#:lower 0.0] [#:upper 255.0] Returns a new clipped image or channel. Clipping an IMAGE or a CHANNEL consist of replacing all pixel values below ‘lower’ by the ‘lower’ value and all pixel values above ‘upper’ by the ‘upper’ value. -- Procedure: im-crop image left top right bottom -- Procedure: im-crop-channel channel width height left top right bottom [#:new-w #f] [#:new-h #f] Returns a new image, resulting of the crop of IMAGE at LEFT, TOP, RIGHT and BOTTOM. -- Procedure: im-crop-size width height left top right bottom Returns a list, ‘(new-width new-height)’. Given the original image WIDTH and HEIGHT, this procedure checks that LEFT, TOP, RIGHT and BOTTOM are valid and return a list, ‘(new-width new-height)’, otherwise, it raises an error. -- Procedure: im-padd image left top right bottom [#:color '(0.0 0.0 0.0)] -- Procedure: im-padd-channel channel width height left top right bottom [#:new-w #f] [#:new-h #f] [#:value 0.0] Returns a new image or channel, respectively padding IMAGE or CHANNEL by LEFT, TOP, RIGHT and BOTTOM pixels initialized respectively to COLOR or VALUE. Note that when ‘im-padd’ is called upon a ‘GRAY’ image, COLOR is reduced to its corresponding gray VALUE: (/ (reduce + 0 color) 3) -- Procedure: im-padd-size width height left top right bottom Returns a list, ‘(new-width new-height)’. Given the original image WIDTH and HEIGHT, this procedure checks that LEFT, TOP, RIGHT and BOTTOM are ‘>= 0’ and return a list, ‘(new-width new-height)’, otherwise, it raises an error. -- Procedure: im-local-minima image [#:threshold +float-max+] -- Procedure: im-local-maxima image [#:threshold (- +float-max+)] -- Procedure: im-local-minima-channel channel width height [#:threshold +float-max+] -- Procedure: im-local-maxima-channel channel width height [#:threshold (- +float-max+)] All local mnima and maxima related procedures also accept the following additional optional keyword arguments: [#:con 8] [#:marker 1.0] [#:borders? #f] [#:plateaus? #f] [#:epsilon 1.0e-4] Returns a new image or channel. Finds the local minima or maxima in IMAGE or CHANNEL. Local minima or maxima are defined as ‘points’ that are not on the borders (unless ‘#:borders?’ is ‘#t’), and whose values are lower or higher, respectively, then the values of all direct neighbors. In the result image or channel, these points are marked using the #:MARKER value (all other pixels values will be set to ‘0’). By default, the algorithm uses 8-connectivity to define a neighborhood, which can be changed passing the optional keyword argument #:CON, which can be either 4 or 8. The #:THRESHOLD optional keyword argument can be used to discard minima and maxima whose (original pixel) value is not below or above the threshold, respectively. Both default values depend on ‘+float-max+’, which is defined (and so is ‘+float-min+’) using the corresponding limit value as given by the C float.h header. The #:PLATEAUS? optional keyword argument can be used to allow regions of ‘constant’ (original pixel) value whose neighbors are all higher (minima) or lower (maxima) than the value of the region. Tow pixel values are considered part of the same region (representing the same ‘constant’ value) if the absolute value of their difference is ‘<=’ to #:EPSILON. *Notes*: • If you want to know how many minima or maxima were found, use *note im-reduce:: upon the result; • If you are interested by the original minima or maxima pixel values, Use *note im-times:: between the original image and the result. -- Procedure: im-fft image -- Procedure: im-fft-channel channel width height Returns two images or channels. Computes and returns the Fast Fourier Transform(1) of the IMAGE or CHANNEL. It returns two values, images or channels: the first contains the real part and the second the imaginary part of the transformation. -- Procedure: im-fft-inverse real imaginary -- Procedure: im-fft-inverse-channel real-channel imaginary-channel width height Returns two images or channels. Computes and returns the inverse Fast Fourier Transform given its REAL and IMAGINARY or REAL-CHANNEL and IMAGINARY-CHANNEL parts. It returns two values, images or channels: the first contains the real part and the second the imaginary part of the inverse transformation. -- Procedure: im-fcc image mask -- Procedure: im-fncc image mask -- Procedure: im-fcc-channel i-chan m-chan width height m-width m-height -- Procedure: im-fncc-channel i-chan m-chan width height m-width m-height Returns an image or a channel. Computes and returns the Fast Cross Correlation or Fast Normalized Cross Correlation between IMAGE and a (usually smaller) MASK(2), using the Fast Fourier Transform(3). ---------- Footnotes ---------- (1) The FFT (Fast Fourier Transform) is simply a faster way to compute the Fourier transform. All FFT related procedures, and their inverse, are obtained by calling the FFTW library (http://www.fftw.org/). (2) Also called a _template_, or a _pattern_. (3) Hence the names, FCC (Fast Cross Correlation) and FNCC (Fast Normalized Cross Correlation). Morphology ---------- The Guile-CV procedures and methods related to morphology. Procedures ---------- -- Procedure: im-disc-erode image radius -- Procedure: im-disc-erode-channel channel width height radius Returns a new image or channel. Performs the morpholgical erosion of IMAGE using a disc of a given RADIUS. Here is an example: (im-make 5 5 1 1.0) ⊣ $2 = (5 5 1 (#f32(1.0 1.0 1.0 1.0 1.0 …))) (im-set! $2 1 2 0.0) (im-disc-erode $2 1) ⊣ $3 = (5 5 1 (#f32(1.0 0.0 0.0 0.0 1.0 …))) (im-display $2 #:proc inexact->exact) ⊣ Channel 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 (im-display $3 #:proc inexact->exact) ⊣ Channel 1 1 0 0 0 1 1 0 0 0 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 -- Procedure: im-disc-dilate image radius -- Procedure: im-disc-dilate-channel channel width height radius Returns a new image or channel. Performs the morpholgical dilation of IMAGE using a disc of a given RADIUS. Here is an example: ... ⊣ $13 = (11 11 1 (#f32(0.0 0.0 0.0 0.0 0.0 …))) (im-disc-dilate $13 1) ⊣ $14 = (11 11 1 (#f32(1.0 1.0 1.0 1.0 1.0 …))) (im-display $13 #:proc inexact->exact) ⊣ Channel 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 1 1 1 0 0 1 1 1 1 0 0 1 1 1 0 0 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 0 0 1 1 0 0 0 1 1 1 1 0 0 1 1 0 0 0 1 1 1 1 0 0 1 1 0 0 0 1 1 1 1 0 0 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 (im-display $14 #:proc inexact->exact) ⊣ Channel 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 0 0 -- Procedure: im-open image radius -- Procedure: im-open-channel channel width height radius Returns a new image or channel. Performs the dilation of the erosion of IMAGE using RADIUS. Opening removes small objects. -- Procedure: im-close image radius -- Procedure: im-close-channel channel width height radius Returns a new image or channel. Performs the erosion of the dilation of IMAGE using RADIUS. Closing removes small holes. -- Procedure: im-fill-holes image -- Procedure: im-fill-holes-channel channel width height Returns a new image or channel. The argument must be a BINARY IMAGE. As its name indicate, this procedure fill the holes of all and every objects in the image. -- Procedure: im-delineate image [#:threshold 10] [#:radius 2] -- Procedure: im-delineate-channel channel width height [#:threshold 10] [#:radius 2] Returns a new image or channel. Both THRESHOLD and RADIUS must be exact integers. Also known as ‘Edge Enhancement’, this procedure performs the delineation of IMAGE, obtained by applying the following pseudo code algorithm: ;; with ;; Min = (im-disc-erode image radius) ;; Max = (im-disc-dilate image radius) D = Max - Min If D < threshold ;; not an edge output pixel = input pixel ;; it is an edge If (pixel – Min) < (Max – pixel) output pixel = Min output pixel = Max [sinter] [sinter-delin-t10-r2] [sinter-delin-t25-r5] Here above, left being the original image - a small part of an optical microscope capture of a sinter sample - you can see the difference between ‘im-delineate’ called with the default THRESHOLD and RADIUS values, then called using ‘#:threshold 25’ and ‘#:radius 5’. -- Procedure: im-distance-map image [#:bg 'black] [#:mode 'euclidean] -- Procedure: im-distance-map-channel channel width height [#:bg 'black] [#:mode 'euclidean] Returns a new image or channel. Also know as ‘Distance Tranform’, this procedure performs the distance map of IMAGE, which consist of, for each background pixel, calculating its distance to the nearest object or contour. In the return new image or channel, all background pixels will be assigned the their distance value, all other pixels will be assigned to 0. Distances larger than 255 are labelled as 255. The default backgroung pixel value is ‘'black’, the optional #:BG keyword argument also accepts ‘'white’. The default distance map mode is ’euclidean (https://en.wikipedia.org/wiki/Euclidean_distance). Other valid optional #:MODE keyword argument are ’chessboard (https://en.wikipedia.org/wiki/Chessboard_distance) and ’manhattan (https://en.wikipedia.org/wiki/Taxicab_geometry). [t-cells] [t-cells-edm] [t-cells-mdm] [t-cells-cdm] Here above, left being the original image - a few cells - you can see the results obtained by calling ‘im-distance-map’ using respectively the ‘'euclidean’, ‘'manhattan’ and ‘'chessboard’ modes. -- Procedure: im-reconstruct image seeds [#:con 8] Returns a new image. This procedure implements a ‘binary morphological reconstruction’ algorithm, which extracts the connected components of IMAGE that are ‘marked’ by (any of) the connected components contained in SEEDS. Morphological reconstruction is part of a set of image operators often referred to as ‘geodesic’ (geodesic distance, geodesic dilation ...). Morphological (or geodesic) operations upon digital images come from and use the Mathematical morphology (MM) (https://en.wikipedia.org/wiki/Mathematical_morphology) theory and technique developed for the analysis and processing of geometrical structures. First described here(1), this implementation is based on a revision of the same article published in ‘the IEEE Transactions on Image Processing, Vol. 2, No. 2, pp. 176-201, April 1993’, available here (http://www.vincent-net.com/luc/papers/93ieeeip_recons.pdf). ---------- Footnotes ---------- (1) in Serra, Jean and Vincent, Luc (1992), "An overview of morphological filtering", Circuits, Systems and Signal Processing (Springer) 11 (1): 47-108 Segmentation ------------ The Guile-CV procedures and methods related to segmentation. Procedures ---------- -- Procedure: im-label image [#:con 8] [#:bg 'black] -- Procedure: im-label-channel channel width height [#:con 8] [#:bg 'black] -- Procedure: im-label-all image [#:con 8] -- Procedure: im-label-all-channel channel width height [#:con 8] Returns two values: a new GRAY image or channel, and the total number of labels(1). The ‘im-label’ and ‘im-label-channel’ procedures label foreground objects in the binary IMAGE. In the new image or channel, 0.0 indicates a background pixel, 1.0 indicates that the pixel belongs to object number 1, 2.0 that the pixel belongs to object number 2, etc. The ‘im-label-all’ and ‘im-label-all-channel’ procedures label all objects in the binary IMAGE, with no specific distinction for any _background value_. As a result, these two procedures will label not only the continuous background, if any, but also any hole(s). As an example, they are used by *note im-fill-holes::, defined in the module ‘(cv morphology)’, which you may have a look at for a better understanding of how it works. Two pixels belong to the same object if they are neighbors. By default the algorithm uses 8-connectivity to define a neighborhood, but this can be changed through the keyword argument #:CON, which can be either 4 or 8. [pp-17-bf] [pp-17-bf-label] [pp-17-bf-label-all] Here above, left being the original image, you can see the difference between ‘im-label’ (2 labels) and ‘im-label-all’ (6 labels). Note that we had to run ‘im-threshold’ on the original image first (all labeling procedures take a binary image (or channel) as their mandatory argument), for the record, we used ‘128’ as the threshold value. -- Procedure: im-canny image [#:sigma 1.0] [#:threshold 0.0] [#:marker 255.0] -- Procedure: im-canny-channel channel width height [#:sigma 1.0] [#:threshold 0.0] [#:marker 255.0] Returns a new image or channel. Detect and mark edges using a Canny Edge Detector (https://en.wikipedia.org/wiki/Canny_edge_detector) algorithm: (a) compute the IMAGE Gaussian gradient using SIGMA, (b) remove edges whose strength is below THRESHOLD, then for all remaining edges, (d) remove the non-local maxima (edge thinning (https://en.wikipedia.org/wiki/Edge_detection#Edge_thinning)) and (e) set their intensity using MARKER. [edx] [edx-canny-s1.0-t0.0-m255.0] [edx-canny-s1.0-t8.0-m255.0] [edx-canny-s1.5-t8.0-m255.0] [edx-canny-s1.0-t8.0-m96.0] Here above, left being the original ‘tif’ image(2), you can see the difference between ‘im-canny’ called using the default values, then using #:THRESHOLD 8, and finally both #:SIGMA 1.5 and #:THRESHOLD 8. The last example is an illustration of the use of ‘#:marker 96.0’(3). -- Procedure: im-crack-edge image [#:marker 255.0] -- Procedure: im-crack-edge-channel channel width height [#:marker 255.0] Returns a new image or channel. Crack edges are marked ‘between’ the (different) pixels of IMAGE. In order to accommodate the cracks, the resulting image or channel size must be (- (* width 2) 1) and (- (* height 2) 1) respectively. Crack pixels are first inserted, then all crack pixels whose non-crack neighbors have different values are crack edges and marked using MARKER, while all other pixels (crack and non-crack) become region pixels. Here is a simple example, with two regions, a and b, and using * as the crack edge marker: Original Inserted Cracks Final Result --------------------------------------------------------------------- a b b a . b . b a * b b b a a b . . . . . a * * * b a a a a . a . b a a a * b . . . . . a a a * * a . a . a a a a a a [pp-17-label-all-marked] Here above is the result of ‘(im-crack-edge img #:marker 127)’, with ‘img’ being the 6 labels image displayed earlier. Crack Edge Images have the following properties: • Crack Edge Images have odd width and height. • Crack pixels have at least one odd coordinate. • Only crack pixels may be marked as crack edge pixels. • Crack pixels with two odd coordinates must be marked as edge pixels whenever any of their neighboring crack pixels was marked. As a consequence of the last two properties, both edges and regions are 4-connected. Thus, 4-connectivity and 8-connectivity yield identical connected components in Crack Edge Images (the so called well-composedness). This ensures that Crack Edge Images have nice topological properties(4). ---------- Footnotes ---------- (1) The number of labels correspond to the highest label value + 1: earlier version of Guile-CV, prior to version 1.8.0, did return the number of objects, which correspond to the highest label value. This was less then optimal, since not only 0.0 is a label, but other procedures, im-features for example, do consider and return and element for the background as well. (2) Actually, all images displayed in the documentation are ‘png’ images, though all described ‘im-canny’ calls where performed on the original ‘tif’ image. This is because in Guile-CV, all images are 32bit float images, and when saved as ‘tif’, all values are preserved (as opposed to being normalized): however, most viewers do not handle floating point pixel values (they don´t know how to scale the values, which may be negative, fractional...). In order to show the results in the documentation, even though all computations of this example were made upon the original ‘tif’ image, they were saved to ‘png’ (which normalize all pixel values to [0 255].). (3) Note that in order to show the result in the documentation, we had to manually set one pixel of one of the edges to 255.0: this is because, just as we explained in the previous footnote, to be able to display the image in the documentation, we had to save the image as ‘png’, which does normalize all values: if you do not set one of the pixels of one edge to 255.0, all markers values would be normalized to 255.0, there by loosing the original marker value. (4) See L. J. Latecki: Well-Composed Sets, Academic Press, 2000 Compose ------- Other Guile-CV procedures and methods to compose images. Procedures ---------- -- Procedure: im-compose position alignment [#:color '(0 0 0)] img-1 img-2 ... -- Procedure: im-compose-channels position alignment channels widths heights [#:value '0.0] Returns a new image or a new channel. The valid POSITION and ALIGNMENT symbols are: ‘left right’ ‘top center bottom’ ‘above below’ ‘left center right’ When used, the optional #:COLOR keyword argument must come after the mandatory ALIGNMENT argument and precede IMG-1, otherwise Guile will raise an exception. For RGB images, it is the color used to padd images passed in argument that are inferior, in width or height (depending on the position), to the biggest of them. For GRAY images, the #:COLOR is reduced to its corresponding gray ‘value’: (/ (reduce + 0 color) 3) For the ‘im-compose-channels’ procedure, the list of CHANNELS, WIDTHS and HEIGHTS must be of equal length and equally ordered, so the ‘nth’ element of WIDTHS and HEIGHTS are the ‘width’ and ‘height’ of the ‘nth’ element of CHANNELS. The optional ‘#:value’ keyword argument is used to padd CHANNELS that are inferior, in width or height (depending on the position), to the biggest of them. Utilities --------- Other Guile-CV utility procedures, methods and variables. Procedures ---------- Variables --------- Procedures ---------- -- Procedure: im-display image [#:proc #f] [#:port (current-output-port)] -- Procedure: im-display-channel channel width height [#:proc #f] [#:port (current-output-port)] Returns nothing. Displays the content of IMAGE or CHANNEL on PORT. The optional #:PROC keyword argument must either be ‘#f’, the default, or a procedure that accepts a single (32 bits float) argument. When #:PROC is ‘#f’, ‘im-display’ will use an internally defined procedure which formats its argument ‘à la octave’: nine positions, six decimals, all number aligned on the dot. any value ‘>= 1000’ is converted to use the exponential float notation. Here is an ‘hand made’ example: ... $2 = (4 3 3 (#f32(0.0 1.0 2.0 3.0 4.0 5.0) ... ...) scheme@(guile-user)> (im-divide $2 99) $3 = (4 3 3 (#f32(10.1010103225708 0.010101010091602802 …) …)) scheme@(guile-user)> (im-set! $3 0 0 0 10000) $4 = (4 3 3 (#f32(10000.0 0.010101010091602802 # # # # …) …)) scheme@(guile-user)> (im-display $4) ⊣ Channel 1 1.0E+4 0.01010 0.02020 0.03030 0.04040 0.05051 0.06061 0.07071 0.08081 0.09091 0.10101 0.11111 Channel 2 0.12121 0.13131 0.14141 0.15152 0.16162 0.17172 0.18182 0.19192 0.20202 0.21212 0.22222 0.23232 Channel 3 0.24242 0.25253 0.26263 0.27273 0.28283 0.29293 0.30303 0.31313 0.32323 0.33333 0.34343 0.35354 *Caution:* unless you specify PORT, both this and *note im-display-channel:: procedures are meant to be used on very small and testing images, otherwise even on a small image, it might be ok in a terminal, but it will definitely will kill your emacs. -- Method: im-show filename -- Method: im-show image [scale #f] -- Method: im-show image name [scale #f] Returns the string "#", where "..." is either FILENAME or a filename constructed by im-show, see below. The optional SCALE argument can take the following values: ‘#f’ pixel values are ‘clipped’: values ‘< 0’ are saved as ‘0’, values ‘> 255’ are saved as ‘255’, and otherwise are saved unchanged ‘#t’ all pixel values are scaled(1) to the ‘[0 255]’ range These three methods will also effectively dislay the image if you are using Geiser (http://www.nongnu.org/geiser), which analyzes Guile’s procedures and methods returned values (through the use of its pattern matcher), and when appropriate, triggers its image display mechanism. Geiser has two variables that allow you to choose either to inline images in its Emacs (https://www.gnu.org/software/emacs) (Guile repl) buffer, or to display them using externel viewer: ‘geiser-image-viewer’ and ‘geiser-repl-inline-images-p’. You may choose to add these variables in your ‘.emacs’ file, for example: (setq geiser-image-viewer "eog") (setq geiser-repl-inline-images-p nil) Note that ‘(setq geiser-repl-inline-images-p t)’ will only work if you are using a graphics-aware Emacs, and otherwise, will fall on the external viewer approach, if the variable ‘geiser-image-viewer’ has been defined. When using Geiser in a non graphics-aware Emac, or when using the external viewer approach, images will appear as buttons: press return on them to invoke (or raise) the external viewer (window containing that image). Except for the first ‘im-show’ method, Guile-CV has to save the IMAGE first, and does it in the location defined by the *note %image-cache:: variable. If you call ‘im-show’ passing NAME, the IMAGE is saved as ‘%image-cache/NAME.png’, otherwise under a generated name, the result of ‘(symbol->string (gensym "im-show-"))’. Note that if you do not specify NAME, a new external viewer window is opened at each ‘im-show’ invocation, even for identical IMAGE calls: this because in Guile-CV, on purpose, images are just list, with no (unique) identifier, and there is no way for ‘im-show’ to know ... Further to this point, when you pass NAME as an argument, you are not ‘identifying’ IMAGE, which may actually differ, but rather just ask to reuse the filename and hence the external viewer window associated with it. Last note: many external viewers, such as Eog (the Gnome Eye Viewer), will try to apply, per default, some sort of smoothing techniques, especially on ‘zoom-in’ and ‘zoom-out’: where this is fine for viewing ‘lazer’ pictures, you probably want to check and disable these options when working with Guile-CV. Variables --------- -- Variable: %image-cache Specifies the location used by *note im-show:: to save images. The default value is ‘/tmp//guile-cv’, but you may ‘set!’ it. If you’d like to reuse that location for future guile-cv sessions, you may save it in guile-cv’s ‘per user’ config file ‘/.config/guile-cv’ as an assoc pair, here is an example: cat ~/.config/guile-cv.conf ((image-cache . "~/tmp")) Note that if used, the ‘~’ is expanded at load time, so in geiser, it becomes: scheme@(guile-user)> ,use (cv) scheme@(guile-user)> %image-cache ⊣ $2 = "/home/david/tmp" -- Variable: %image-cache-format Specifies the format used by *note im-show:: to save images. The default value is ‘"png"’, but you may ‘set!’ it. If you’d like to reuse that format for future guile-cv sessions, you may save it in guile-cv’s ‘per user’ config file ‘/.config/guile-cv’, as an assoc pair, here is an example: cat ~/.config/guile-cv.conf ((image-cache-format . "jpg")) ---------- Footnotes ---------- (1) Note that in this particular context, ‘scale’ does not mean a change in dimension, but rather bringing pixel values from the range they occupy in memory to the ‘[0 255]’ range Support ======= Guile-CV uses a series of support modules, each documented in the following subsections. You may either import them all, like this ‘(use-modules (cv support))’, or individually, such as ‘(use-modules (cv support modules))’, ‘(use-modules (cv support goops))’, ... Modules ------- ‘*note re-export-public-interface::’ -- Syntax: re-export-public-interface mod1 mod2 ... Re-export the public interface of a MOD1 MOD2 ... Invoked like ‘use-modules’, where each MOD1 MOD2 ... is a module name (a list of symbol(s)). Goops ----- Pi -- Procedures ---------- -- Procedure: radian->degree rad -- Procedure: degree->radian deg Returns respectively a degree or a radian value. Variables --------- -- Variable: %pi -- Variable: %2pi -- Variable: %pi/2 Respectively bound to ‘(acos -1)’, ‘(* 2 %pi)’ and ‘(/ %pi 2)’. Utils ----- Appendix A GNU Free Documentation License ***************************************** Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 0. PREAMBLE The purpose of this License is to make a manual, textbook, or other functional and useful document “free” in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others. This License is a kind of “copyleft”, which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software. We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference. 1. APPLICABILITY AND DEFINITIONS This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The “Document”, below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as “you”. You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law. A “Modified Version” of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language. A “Secondary Section” is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document’s overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them. The “Invariant Sections” are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not fit the above definition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none. The “Cover Texts” are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words. A “Transparent” copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modification by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not “Transparent” is called “Opaque”. Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML, PostScript or PDF designed for human modification. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced by some word processors for output purposes only. The “Title Page” means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, “Title Page” means the text near the most prominent appearance of the work’s title, preceding the beginning of the body of the text. The “publisher” means any person or entity that distributes copies of the Document to the public. A section “Entitled XYZ” means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific section name mentioned below, such as “Acknowledgements”, “Dedications”, “Endorsements”, or “History”.) To “Preserve the Title” of such a section when you modify the Document means that it remains a section “Entitled XYZ” according to this definition. The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License. 2. VERBATIM COPYING You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3. You may also lend copies, under the same conditions stated above, and you may publicly display copies. 3. COPYING IN QUANTITY If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Document’s license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects. If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages. If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public. It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document. 4. MODIFICATIONS You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version: A. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission. B. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has fewer than five), unless they release you from this requirement. C. State on the Title page the name of the publisher of the Modified Version, as the publisher. D. Preserve all the copyright notices of the Document. E. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices. F. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below. G. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document’s license notice. H. Include an unaltered copy of this License. I. Preserve the section Entitled “History”, Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled “History” in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence. J. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the “History” section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission. K. For any section Entitled “Acknowledgements” or “Dedications”, Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein. L. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles. M. Delete any section Entitled “Endorsements”. Such a section may not be included in the Modified Version. N. Do not retitle any existing section to be Entitled “Endorsements” or to conflict in title with any Invariant Section. O. Preserve any Warranty Disclaimers. If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version’s license notice. These titles must be distinct from any other section titles. You may add a section Entitled “Endorsements”, provided it contains nothing but endorsements of your Modified Version by various parties—for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard. You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one. The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version. 5. COMBINING DOCUMENTS You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers. The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work. In the combination, you must combine any sections Entitled “History” in the various original documents, forming one section Entitled “History”; likewise combine any sections Entitled “Acknowledgements”, and any sections Entitled “Dedications”. You must delete all sections Entitled “Endorsements.” 6. COLLECTIONS OF DOCUMENTS You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects. You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document. 7. AGGREGATION WITH INDEPENDENT WORKS A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an “aggregate” if the copyright resulting from the compilation is not used to limit the legal rights of the compilation’s users beyond what the individual works permit. When the Document is included in an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document. If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Document’s Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate. 8. TRANSLATION Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail. If a section in the Document is Entitled “Acknowledgements”, “Dedications”, or “History”, the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title. 9. TERMINATION You may not copy, modify, sublicense, or distribute the Document except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, or distribute it is void, and will automatically terminate your rights under this License. However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, receipt of a copy of some or all of the same material does not give you any rights to use it. 10. FUTURE REVISIONS OF THIS LICENSE The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See . Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License “or any later version” applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation. If the Document specifies that a proxy can decide which future versions of this License can be used, that proxy’s public statement of acceptance of a version permanently authorizes you to choose that version for the Document. 11. RELICENSING “Massive Multiauthor Collaboration Site” (or “MMC Site”) means any World Wide Web server that publishes copyrightable works and also provides prominent facilities for anybody to edit those works. A public wiki that anybody can edit is an example of such a server. A “Massive Multiauthor Collaboration” (or “MMC”) contained in the site means any set of copyrightable works thus published on the MMC site. “CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0 license published by Creative Commons Corporation, a not-for-profit corporation with a principal place of business in San Francisco, California, as well as future copyleft versions of that license published by that same organization. “Incorporate” means to publish or republish a Document, in whole or in part, as part of another Document. An MMC is “eligible for relicensing” if it is licensed under this License, and if all works that were first published under this License somewhere other than this MMC, and subsequently incorporated in whole or in part into the MMC, (1) had no cover texts or invariant sections, and (2) were thus incorporated prior to November 1, 2008. The operator of an MMC Site may republish an MMC contained in the site under CC-BY-SA on the same site at any time before August 1, 2009, provided the MMC is eligible for relicensing. ADDENDUM: How to use this License for your documents ==================================================== To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page: Copyright (C) YEAR YOUR NAME. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled ``GNU Free Documentation License''. If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the “with...Texts.” line with this: with the Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. If you have Invariant Sections without Cover Texts, or some other combination of the three, merge those two alternatives to suit the situation. If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software. Concept Index ************* This index contains concepts, keywords and non-Schemey names for several features, to make it easier to locate the desired sections. * Menu: * Copying: Guile-CV License. (line 99) * Crack Edge Image: Segmentation. (line 2592) * Distance Map: Morphology. (line 2458) * Distance Transform: Morphology. (line 2458) * Edge Detection: Segmentation. (line 2566) * Edge Enhancement: Morphology. (line 2424) * Euclidean Distance: Morphology. (line 2458) * Fast Cross Correlation: Transform. (line 2295) * Fast Fourier Transform: Transform. (line 2269) * Fast Fourier Transform Inverse: Transform. (line 2280) * Fast Normalized Cross Correlation: Transform. (line 2295) * Features: Features. (line 1495) * Gaussian Blur: Filter. (line 1714) * Gaussian Gradient: Filter. (line 1725) * Gaussian Sharp: Filter. (line 1737) * Gaussian Smooth: Filter. (line 1714) * Geodesic Operators: Morphology. (line 2488) * GLCM: Texture. (line 1456) * GLCP: Texture. (line 1439) * GPL: Guile-CV License. (line 99) * Gray Level Co-occurence Matrix: Texture. (line 1456) * Gray Level Co-occurence Probability: Texture. (line 1439) * Image Convolution: Filter. (line 1792) * Image Particles: Particles. (line 1674) * Image Textures: Texture. (line 1403) * License: Guile-CV License. (line 99) * Mathematical Morphology: Morphology. (line 2488) * Matrix Division: Process. (line 1960) * Matrix Multiplication: Process. (line 1937) * Median Filter: Filter. (line 1763) * Morphological Reconstruction: Morphology. (line 2488) * Non-Local Means Denoising: Filter. (line 1827) * the GNU Project: Join the GNU Project. (line 82) * User Configuration: Utilities. (line 2832) Procedure Index *************** This is an alphabetical list of all the procedures, methods and macros in Guile-CV. * Menu: * degree->radian: Pi. (line 2899) * im-=-channel?: Image Structure and Accessors. (line 787) * im-=?: Image Structure and Accessors. (line 786) * im-add: Process. (line 1906) * im-add <1>: Process. (line 1907) * im-add-channel: Process. (line 1908) * im-add-channel <1>: Process. (line 1909) * im-and: Process. (line 2034) * im-and-channel: Process. (line 2035) * im-binary-channel?: Image Structure and Accessors. (line 778) * im-binary?: Image Structure and Accessors. (line 777) * im-canny: Segmentation. (line 2562) * im-canny-channel: Segmentation. (line 2564) * im-channel: Image Structure and Accessors. (line 765) * im-channel-offset: Image Structure and Accessors. (line 820) * im-channel-ref: Image Structure and Accessors. (line 832) * im-channel-set!: Image Structure and Accessors. (line 841) * im-channels: Image Structure and Accessors. (line 764) * im-clip: Transform. (line 2175) * im-clip-channel: Transform. (line 2176) * im-close: Morphology. (line 2405) * im-close-channel: Morphology. (line 2406) * im-collect: Image Structure and Accessors. (line 852) * im-complement: Transform. (line 2167) * im-compose: Compose. (line 2672) * im-compose-channels: Compose. (line 2674) * im-convolve: Filter. (line 1789) * im-convolve-channel: Filter. (line 1790) * im-copy: Image Structure and Accessors. (line 752) * im-copy-channel: Image Structure and Accessors. (line 753) * im-crack-edge: Segmentation. (line 2589) * im-crack-edge-channel: Segmentation. (line 2590) * im-crop: Transform. (line 2185) * im-crop-channel: Transform. (line 2186) * im-crop-size: Transform. (line 2192) * im-delineate: Morphology. (line 2421) * im-delineate-channel: Morphology. (line 2422) * im-disc-dilate: Morphology. (line 2354) * im-disc-dilate-channel: Morphology. (line 2355) * im-disc-erode: Morphology. (line 2322) * im-disc-erode-channel: Morphology. (line 2323) * im-display: Utilities. (line 2717) * im-display-channel: Utilities. (line 2719) * im-distance-map: Morphology. (line 2455) * im-distance-map-channel: Morphology. (line 2456) * im-divide: Process. (line 1947) * im-divide <1>: Process. (line 1948) * im-divide-channel: Process. (line 1949) * im-divide-channel <1>: Process. (line 1950) * im-fast-channel-offset: Image Structure and Accessors. (line 821) * im-fast-channel-ref: Image Structure and Accessors. (line 833) * im-fast-channel-set!: Image Structure and Accessors. (line 842) * im-fast-ref: Image Structure and Accessors. (line 801) * im-fast-set!: Image Structure and Accessors. (line 810) * im-fcc: Transform. (line 2289) * im-fcc-channel: Transform. (line 2291) * im-features: Features. (line 1494) * im-fft: Transform. (line 2267) * im-fft-channel: Transform. (line 2268) * im-fft-inverse: Transform. (line 2277) * im-fft-inverse-channel: Transform. (line 2278) * im-fill-holes: Morphology. (line 2413) * im-fill-holes-channel: Morphology. (line 2414) * im-flip: Transform. (line 2136) * im-flip-channel: Transform. (line 2137) * im-fncc: Transform. (line 2290) * im-fncc-channel: Transform. (line 2293) * im-gaussian-blur: Filter. (line 1712) * im-gaussian-blur-channel: Filter. (line 1713) * im-gaussian-gradient: Filter. (line 1723) * im-gaussian-gradient-channel: Filter. (line 1724) * im-gaussian-sharp: Filter. (line 1734) * im-gaussian-sharp-channel: Filter. (line 1735) * im-glcm: Texture. (line 1455) * im-glcp: Texture. (line 1438) * im-gray?: Image Structure and Accessors. (line 771) * im-gray? <1>: Import Export. (line 1307) * im-height: Image Structure and Accessors. (line 762) * im-height <1>: Import Export. (line 1301) * im-histogram: Histogram. (line 1327) * im-image?: Image Structure and Accessors. (line 770) * im-invert: Transform. (line 2148) * im-invert-channel: Transform. (line 2149) * im-label: Segmentation. (line 2523) * im-label-all: Segmentation. (line 2526) * im-label-all-channel: Segmentation. (line 2527) * im-label-channel: Segmentation. (line 2524) * im-load: Import Export. (line 1262) * im-local-maxima: Transform. (line 2222) * im-local-maxima-channel: Transform. (line 2225) * im-local-minima: Transform. (line 2221) * im-local-minima-channel: Transform. (line 2223) * im-make: Image Structure and Accessors. (line 742) * im-make-channel: Image Structure and Accessors. (line 743) * im-make-channels: Image Structure and Accessors. (line 744) * im-map: Process. (line 1989) * im-map-channel: Process. (line 1990) * im-max: Process. (line 1981) * im-max-channel: Process. (line 1983) * im-mdivide: Process. (line 1960) * im-mdivide-channel: Process. (line 1961) * im-median-filter: Filter. (line 1760) * im-median-filter-channel: Filter. (line 1761) * im-min: Process. (line 1980) * im-min-channel: Process. (line 1982) * im-mtimes: Process. (line 1937) * im-mtimes-channel: Process. (line 1938) * im-n-channel: Image Structure and Accessors. (line 763) * im-n-channel <1>: Import Export. (line 1302) * im-nl-means: Filter. (line 1825) * im-nl-means-channel: Filter. (line 1826) * im-normalize: Process. (line 2025) * im-normalize-channel: Process. (line 2026) * im-open: Morphology. (line 2397) * im-open-channel: Morphology. (line 2398) * im-or: Process. (line 2036) * im-or-channel: Process. (line 2037) * im-padd: Transform. (line 2200) * im-padd-channel: Transform. (line 2202) * im-padd-size: Transform. (line 2213) * im-particle-clean: Particles. (line 1687) * im-particles: Particles. (line 1673) * im-range: Process. (line 1973) * im-range-channel: Process. (line 1974) * im-reconstruct: Morphology. (line 2487) * im-reduce: Process. (line 1998) * im-reduce-channel: Process. (line 1999) * im-ref: Image Structure and Accessors. (line 800) * im-resize: Transform. (line 2104) * im-resize-channel: Transform. (line 2105) * im-rgb->gray: Transform. (line 2092) * im-rgb?: Image Structure and Accessors. (line 772) * im-rgb? <1>: Import Export. (line 1308) * im-rgba->gray: Transform. (line 2091) * im-rgba->rgb: Transform. (line 2090) * im-rotate: Transform. (line 2118) * im-rotate-channel: Transform. (line 2119) * im-save: Import Export. (line 1273) * im-scrap: Process. (line 1890) * im-set!: Image Structure and Accessors. (line 809) * im-sharpen: Filter. (line 1746) * im-sharpen-channel: Filter. (line 1747) * im-show: Utilities. (line 2766) * im-show <1>: Utilities. (line 2767) * im-show <2>: Utilities. (line 2768) * im-size: Image Structure and Accessors. (line 757) * im-size <1>: Import Export. (line 1296) * im-subtract: Process. (line 1916) * im-subtract <1>: Process. (line 1917) * im-subtract-channel: Process. (line 1918) * im-subtract-channel <1>: Process. (line 1919) * im-texture: Texture. (line 1401) * im-threshold: Process. (line 1878) * im-times: Process. (line 1926) * im-times <1>: Process. (line 1927) * im-times-channel: Process. (line 1928) * im-times-channel <1>: Process. (line 1929) * im-transpose: Transform. (line 2157) * im-transpose-channel: Transform. (line 2158) * im-width: Image Structure and Accessors. (line 761) * im-width <1>: Import Export. (line 1300) * im-xor: Process. (line 2038) * im-xor-channel: Process. (line 2039) * k-channel: Kernel Structure and Accessors. (line 1043) * k-display: Kernel Structure and Accessors. (line 1082) * k-fast-offset: Kernel Structure and Accessors. (line 1071) * k-fast-ref: Kernel Structure and Accessors. (line 1053) * k-fast-set!: Kernel Structure and Accessors. (line 1061) * k-height: Kernel Structure and Accessors. (line 1041) * k-make: Kernel Structure and Accessors. (line 920) * k-make-circular-mask: Kernel Structure and Accessors. (line 973) * k-offset: Kernel Structure and Accessors. (line 1070) * k-ref: Kernel Structure and Accessors. (line 1052) * k-set!: Kernel Structure and Accessors. (line 1060) * k-size: Kernel Structure and Accessors. (line 1042) * k-width: Kernel Structure and Accessors. (line 1040) * kernel?: Kernel Structure and Accessors. (line 1048) * radian->degree: Pi. (line 2898) * re-export-public-interface: Modules. (line 2882) Variable Index ************** This is an alphabetical list of all the important variables and constants in Guile-CV. * Menu: * %2pi: Pi. (line 2907) * %image-cache: Utilities. (line 2831) * %image-cache-format: Utilities. (line 2851) * %k-edge0: Kernel Structure and Accessors. (line 1117) * %k-edge1: Kernel Structure and Accessors. (line 1124) * %k-emboss: Kernel Structure and Accessors. (line 1174) * %k-gaussian-blur0: Kernel Structure and Accessors. (line 1146) * %k-gaussian-blur1: Kernel Structure and Accessors. (line 1154) * %k-identity: Kernel Structure and Accessors. (line 1109) * %k-laplacian: Kernel Structure and Accessors. (line 1187) * %k-mean: Kernel Structure and Accessors. (line 1138) * %k-prewitt-x: Kernel Structure and Accessors. (line 1213) * %k-prewitt-y: Kernel Structure and Accessors. (line 1203) * %k-sharpen: Kernel Structure and Accessors. (line 1131) * %k-sobel-x: Kernel Structure and Accessors. (line 1238) * %k-sobel-y: Kernel Structure and Accessors. (line 1231) * %k-unsharp: Kernel Structure and Accessors. (line 1164) * %pi: Pi. (line 2906) * %pi/2: Pi. (line 2908) Type Index ********** This is an alphabetical list of all the important data types defined in the Guile-CV Programmers Manual.