Image Processing and Analysis in Guile
a Computer Vision functional programming library
A clipping bug has been fixed in vigra_exportgrayimage_c, vigra_exportrgbimage_c and vigra_exportrgbaimage_c. A new vigra_clipimage_c function is available and Guile-CV uses it.
Configuring Guile for Guile-CV
Previously, these two procedures were respectively named im-fill and im-fill-channel, but that was a bit ambiguous.
New optional keyword,
Return n-label, not n-object. 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 a feature object for the background as well.
Note that Vigra C functions return the label highest value, but the vigra-label-all function starts to label using 1.0, so in this case, the label highest value is also the number of label used, hence im-label-all-channel has to return 'n-object' and not '(+ n-object 1)', fixed. I don't like this, for me it is inconsistent, and im-label-all should start to label using 0.0 as well, so I mailed the Vigra folks, let's see...
Consistency between im-label, im-label-all and im-features. All these already named their argument 'n-label', but it actually ment 'n-object'. I changed all this - and the segmentation related code as well - so it is consistent everywhere in the code. And now, the n-label argument value also correspond to the length of the list of features returned, so much better.
Vigra C functions, at the contrary, expect 'n-object', or expressed differently, expect the label highest value, which correspond to (- n-label 1). This is also consistent everywhere in the code now.
Now accepts more then one image.
We had and-l already. There are (well known among schemers) situations where you need a function that works on lists.
Composite images only differs to others in the sence that they can have more then 3 channels, any number of channels actually, the 4th _not_ being the traditional alpha channel. Each channel holds on specific information, depending on the application domaim. It is sometime necessary to visualize these though, in which case they must be 'converted' to RGB images, hence this new procedure. This is a 'work in progress': as it is, it will only work if the composite image has 4 channels. In this first implementation, the algorithm will super impose the 4th channel to the RGB's, so one says 'white pixels always win' (this because the 4th channel is (generally) associated with the White 'color').
It was a bad idea to make this internal procedure public, and users can call (apply im-=? ...) anyway.
Calls im-rgb->gray-1, which was unnecessary calling float-round at each step, and I also noticed that recursive tail call procedures have a tiny penalty compared to loop, so rewrote both. Now, in addition, both procedures will split their work in between as many core as available, except if the parameter %use-par-map has been set to #f. On my laptop - i5-2450M CPU @ 2.50GHz × 4 and 5.7GB of mem - both procedures are now 3 to 4 times faster.
Labels are 'discrete' floats, by definition, so we can use = instead of float=?, which is 3 to 4 times faster.
Area, left, top, right, bottom values are discrete floats, use float->int, not float-round.
Till Guile-3.0 becomes available, I decided to temporarily rewrite the math, linear algebra and logical 'low level' procedures in C. Tests performed on my laptop - i5-2450M CPU @ 2.50GHz × 4 and 5.7GB of mem - using GRAY and RGB test images of 2718 x 1732 show gains in the range of 23x to 100x faster, depending on the operation and wether images involved have 1 or more channels (though in Guile-CV, unless the user sets the %use-par-map parameter to #f, all multi channel operations are multi threaded).
Because all memory allocation still is done in scheme, and not in C, I am very confortable with this approach, as I said, till we have an AOT compiler that compiles fixed size floating point and small integers operations and vector loops for these that runs as fast as in C, and I am prety confident that it will happen, maybe not tomorrow, but it will happen.
That commit introduces - kindly implemented by Benjamin Seppke upon our request - the following new features: centre of mass, perimeter, skewness, kurtosis.
Adding an optional (scale #f) argument. Till now, images pixel values would be always scaled at save time, unless saving the file using tif. This was really less then optimal because (a) tif preserves values, but no image viewer knows how to display these Guile-CV 32 bits float images (they beleive these are RGBA images) and (b) scaling at save time totally destroyed the results of im memory calcuations ... What we really want here, most of the time at least, and hence it becomes the default from now on, is what is called 'clipping': pixel values are ‘clipped’, which means that values < 0 are saved as 0, values > 255 are saved as 255, and otherwise are saved unchanged.
Previously, these procedures were using the name 'inverse', but that was not 'optimal', fixed.
major-ev-x, major-ev-y, minor-ev-x, minor-ev-y, major-axis, minor-axis, angle, center-mass-x, center-mass-y, perimeter, skewness, kurtosis, circularity, aspect-ratio, roundness.
major-ev-x, major-ev-y, minor-ev-x, minor-ev-y, major-axis, minor-axis, angle, center-mass-x, center-mass-y, perimeter, skewness-r, skewness-g, skewness-b, kurtosis-r, kurtosis-g, kurtosis-b, circularity, aspect-ratio, roundness.
both procedures have been 'relaxed' and do not check anymore that either the value or pixel values respectively are in the [0 255] range, as doing so was actually incorrect: images need to be normalized and scaled (as in bringing their pixel values in the [0 255] range) only to be displayed, but otherwise, their should be no such limitations.
was returning #f for BLACK and WHITE images, so either composed of eiher 0.0 or 255.0, fixed.
Adding an optional #:key (val 255.0), since we need to be able to normalize to specific values in some circumstances, such as, for example, to normalize gray level co-occurrence matrices.
The arguments order has been changed for 'vector proc default' not 'proc default vector', because it is the order we use in im-reduce and im-reduce-channel - as [almost] all other im-* procedures or methods take an image as their first argument. As a user, it is also a bit more naturel, imo at least, to 'reduce image using proc, return default if the image is empty'.
All linear algebra matrix methods now accept any number of images or channels. Note that due to the inherent checks between lines and columns of intermediate results, im-multiply-channel and im-divide-channel methods arguments must be a series of at least one tuple(s) composed of three values - channel width height - represented in the manual as: c1 w1 h1 c2 w2 h2 c3 w3 h3 …
Updated so its interface is 'identical' to im-map and friends, and a typical call now looks like: im-collect what i1 i2 i3 … (instead of im-collect images what).
the width and height of the result normalized image were inadvertently inverted, now fixed.
the sub results were inadvertently using 'n' instead of 'p' to compute their destination position in the 'n x p' cells returned result f32vector, now fixed.
This is the first public release of Guile-CV, earlier releases were made available to GNU evaluators and Savannah hackers only.
packages: inputenc, fontenc, lmodern, xcolor, booktabs, siunitx, iwona
The GNU evaluation of Guile-CV has been completed on March the 11th, 2017, but due to backlog, we've been informed then that its approval step would take another five weeks, so we decided to upload it on Savannah non gnu in the mean time, done!
A couple of months ago, we started to work on Guile-CV, a Computer Vision functional library for the Guile Scheme language, and now is the right time for it to be evaluated to be part of the GNU Project.