Next: Import Export, Previous: Image Structure and Accessors, Up: Image Processing [Contents][Index]
The Guile-CV procedures and methods related to kernel data structure, creating and accessing kernels.
A Guile-CV kernel 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 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.
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 valuea 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 from0
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
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)
, wheren
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 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 image9
Returns, respectively, the width, the height, the list of width and height or the kdata for kernel.
Returns #t
if kernel is a Guile-CV kernel.
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.
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.
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.
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
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, im-gaussian-blur, im-gaussian-sharp, im-sharpen (a simple sharpening procedure), im-canny (edge detection) ... and (b) in order to make these definitions easier to read, we’ve added some spaces and newlines.
(k-display %k-identity #:proc float->int) -| 0 0 0 0 1 0 0 0 0
(k-make 3 3 '( 1 0 -1 0 0 0 -1 0 1 ))
(k-make 3 3 '( 0 1 0 1 -4 1 0 1 0 ))
(k-make 3 3 '( -1 -1 -1 -1 9 -1 -1 -1 -1 ))
(k-make 3 3 '( 1 1 1 1 1 1 1 1 1 ) 9)
(k-make 3 3 '( 1 2 1 2 4 2 1 2 1 ) 16)
(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)
(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)
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 ))
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 ))
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 ))
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 ))
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))
.
(k-make 3 3 '( 1 2 1 0 0 0 -1 -2 -1 ))
(k-make 3 3 '( 1 0 -1 2 0 -2 1 0 -1 ))
The 'scale
optional argument passed to 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 …
Next: Import Export, Previous: Image Structure and Accessors, Up: Image Processing [Contents][Index]