MVTec Software GmbH

MVTec HORUS for FreeBSD

(demo version)


A recent copy of this document can be obtained under http://www.mvtec.com/mvtec-products.html.

Table of contents

Starting note
  1. Overview
  2. Installation
  3. Quick Start
  4. Examples
  5. Known bugs
  6. Further Information

Starting note:

Please consider this version of MVTec HORUS still beta. This version is our first port to FreeBSD and there are still some problems, mostly regarding Motif. MVTec HORUS is a very sophisitcated tool. Up to now it consists of more than 21 MB source code. Please forgive us the bugs in the first version, report them to us, and the next version will be even better!

Thank you.


Overview

The MVTec HORUS system is a very sophisticated tool for computer aided vision engineering. Whether your goals are industrial inspection, quality control, remote sensing, medical image analysis, or camera calibration - MVTec HORUS can help you.

Most vision applications are in the field of manufacturing, industrial inspection, and quality control. MVTec HORUS offers a wide range of realtime operators to help you improve your manufacturing process.

Remote sensing is a growing market. If you want to start in this business, you need a tool for processing multi-channel images. MVTec HORUS eases the interpretation with powerful segmentation techniques.

MVTec HORUS offers operators to process a wide range of medical images from different modalities. Image segmentation is not easy in this area due to noise and other artifacts. However, a few minutes of interactive MVTec HORUS programming can solve most of the typical problems you might consider.

Camera calibration is the key to obtain exact 3D measurements from video images. MVTec HORUS calibrates your camera with a few lines of code.

Color is a key feature for many applications. MVTec HORUS gives you a set of easy-to-use operators for handling color images.

For Further Information, please go to the end of this document or contact MVTec Software GmbH directly under the address http://www.mvtec.com/.

Installation

Installing the MVTec HORUS demo is quite simple. Note, that only steps 6, 7, and 8 are mandatory. So if you just want to give MVTec HORUS a try there is no need to recompile the kernel.

You need approx. 28 MB space on your harddisk to install MVTec HORUS.

  1. if you like to use hinspector along with hdevelop configure a kernel with
         options SYSVSHM
         options SYSVSEM
         options SYSVMSG
    	  
    enabled.
  2. if you have a Matrox Meteor framegrabber in your system, add the following to your kernel configuration if you haven't done so yet (see 'man meteor'):
         device meteor0
         options METEOR_SYSTEM_DEFAULT=METEOR_PAL
         options METEOR_ALLOC_PAGES="433"
    	  
    The system default to choose (PAL/NTSC) depends on your local TV standard.

    The correct number of pages to allocate is computed the following way:

         largest width to grab:  768 pixel (PAL)
         largest height to grab: 576 pixel (PAL)
         max. byte per pixel:    4         (RGB_24)
         size of page (byte):    4096
    	  
    If you want to grab PAL signals in full resolution the correct number of pages to allocate is (768*576*4/4096)+1 = 433. If you don't have enough memory or intend to grab smaller images only you may decrease this value.

    hdevelop is capable of grabbing full, half and quarter resolution of PAL or NTSC signals in RGB_24 or YUV_16. See the help pages for 'query_framegrabber' etc. for more info. Then do a 'cd /dev; ./MAKEDEV meteor0'.

    The Matrox Meteor framegrabber won't work with Pentium Pro boards using the Intel Natoma chipset revision 1. This is due to a bug in the Natoma chipset. There is no software workaround.

  3. If you plan to use a b/w QuickCam, add
         device qcam0 at isa? port "IO_LPT1" conflicts flags 1
    	  
    to the kernel configuration. Then do a 'cd /dev; ./MAKEDEV qcam0'.

    Please note that the QuikCam code in hdevelop is untested. (Since we don't own a QuickCam, we programed it from the specs only ...)

  4. If necessary, compile and install the new kernel and reboot.
  5. If you own a 486DX or better you may want to recompile the math library. The overall performance gain of MVTec HORUS with an optimized math library is about 20 percent. To recompile, first install the library sources from the CD (unter /usr/src/lib). Then uncomment the following line in '/etc/make.conf':
         #HAVE_FPU=      yes
    	  
    Finally do
         cd /usr/src/lib/msun
         make depend
         make all
         make install
    	  
    The new math library is now in place and ready to be used.
  6. cd into the parent directory of the directory you want to install MVTec HORUS in (e.g. /usr/local, if you want to install MVTec HORUS into /usr/local/horus, which is recommended). Then untar the distribution file:
         cd /usr/local
         tar xvf {path to HORUS demo archive}/horusdemo.tar.gz
    	  
    The tar file should have created the directories
         horus/README
         horus/app-defaults
         horus/bin
         horus/doc  ->  doc_english
         horus/doc_english
         horus/examples
         horus/help
         horus/images
         horus/filter
    	
  7. link the binaries in /usr/local/horus/bin (or wherever you installed the demo) to a directory in your path, e.g. /usr/local/bin, or put the HORUS binary directory itself in your path.
  8. set some environment variables. For tcsh user:
         setenv HORUSROOT /usr/local/horus
    	  
    The HORUSROOT variable points to the root directory of the MVTec HORUS installation. Setting it is mandatory.
         setenv HORUSIMAGES /usr/local/horus/images
    	  
    The HORUSIMAGES variable points to a directory hierarchy containing images you intend to use with MVTec HORUS. This way, images can be loaded without stating the absolute directory path. Of course, even with the use of HORUSIMAGES it is still possible to load images via their absolute path. HORUSIMAGES is optional.

    Put these variables in your .login or .profile

  9. If you use the HORUSIMAGES variable and the directory contains subdirectories, put this or a similar script in the HORUSIMAGES directory and run it every time you add or remove images.
         #! /bin/sh
         # do not list LS-R
         rm LS-R
         # follow symlinks
         find * -type f -follow -print | sort > LS-R
    	  
    hdevelop reads the contents of LS-R to locate images on disk.
  10. install the application defaults in your application defaults directory (normally /usr/X11R6/lib/X11/app-defaults). You can use the environment variable XAPPLRESDIR to use a specific directory. This step is optional and only recommended if you want to change default values.
  11. Install a HTML browser, if you haven't done so yet. Hdevelop uses the HTML format for the online-help pages. The default browser is netscape. This can be changed in the application defaults.
  12. Enable 'Backing Store' in your X-Server, if it isn't enabled by default. MVTec HORUS doesn't redraw temporally occluded graphics windows and relies on the X-Server instead. If 'Backing Store' is disabled, you have to redraw explicitely (click on the image icon - see below).

    If you use Accelerated-X (like we do), a

         [SETTINGS]
             BackingStore = YES;
    
    in /etc/Xaccel.ini is sufficient. Restart the X-Server afterwards.
  13. That's it.

Quick Start

The demo package contains two executables: hdevelop and hinspector. Hdevelop is started from the command line, hinspector is started from inside hdevelop.

Hdevelop is a highly interactive programming environment faciliating the rapid prototyping of typical image analysis and machine vision applications.

Hinspector is an interactive visualization environment fully integrated into hdevelop allowing all the analysis of two-dimensional data (images and segmentation results) in order to determine parameters of operators rapidly.

Hdevelop

Hdevelop is the main tool to work with. When started, it presents three windows: The "HORUS develop" window, the "Variables" window and the "Graphics Window" window.

The "HORUS develop" window

This is the main window. Here you create, run, and debug all programs written in hdevelop. At the top row of the window you should see the following menu entries: The second row shows some additional fields: The next two adjacent areas show the current program. On the left side is an area containing breakpoints (set by clicking with the left button), the program counter (set with middle button) and the insert mark (set with right button). On the right side the current program is displayed. The effects of clicking on a line of code depend on the the settings of the replace/delete/insert/comment menu. New operators are always inserted at the insert mark.

The last area holds the parameters of the selected operator. If no operator is selected, this area is empty.

The "Variables" window

This window is used to inspect the numerical and iconic variables that are currently used by the program. In the top row to the right the iconic variables are displayed. Click on a variable to display it in the Graphics window. Do not drag and drop (middle button) variables to the Graphics window: That code is currently broken in the FreeBSD port, sorry. In the lower variable area, numerical variables are displayed.

To the left of the variable window, four icons are displayed:

The "Graphics Window" window

This window is used to display iconic data. Multiple graphics windows can be open at the same time. The active window is indicated by the 'Active' button.

At the top of the window there are four buttons:

Further hdevelop hints

Hinspector

hinspector is started from hdevelop via the "Visualization"/"Start Inspector" menu. When started, two windows appear on the screen: The "HORUS Display Manager" window and the "HORUS Inspector1" window.

The "HORUS Inspector1" window

This window replaces the hdevelop "Graphics window".

We're still working on further information for this chapter, sorry. The documentation will be published on the Web, as soon as it is finished.

The "HORUS Display Manager" window

We're still working on further information for this chapter, sorry. The documentation will be published on the Web, as soon as it is finished.

Examples

In this chapter a few of the hdevelop examples provided with this demo are explained. It is not possible to cover all of them in detail but it is straightforward to load the programs and view the operators' help texts.

diff_seq.dev

This program does simple image sequence processing: The aim is to detect movements. To do this, two succeding images of the sequence are subtracted and the resulting image is postprocessed by suitable operators (e.g. texture operators like laws followed by a threshold would work too). The result is satisfying. However, this approach only works for constant illumination.

eyes.dev

The aim of this program is finding the eyes of a mandrill. Actually, this task could also be done with only three MVTec HORUS operators:
01 read_image (Image, 'monkey')
02 threshold__ (Image, Region, 128, 255)
03 connection (Region, ConnectedRegions)
04 select_shape(ConnectedRegions, SelectedRegions, ['area','anisometry'], 'and', [500,1], [50000,1.7])
      
The example mainly intends to teach loop programming in hdevelop (In hdevelop loops are seldom needed. There are better solutions in nearly all cases imaginable).

The program looks like this (line numbers added for reading convenience):

01 dev_close_window ()
02 read_image (Image, 'monkey')
03 get_image_pointer__ (Image, Pointer, Type, Width, Height)
04 dev_open_window (0, 0, Width, Height, 'black', WindowID)
05 dev_set_draw ('fill')
06 dev_set_part (0, 0, Height-1, Width-1)
07 threshold__ (Image, Region, 128, 255)
08 dev_set_color ('white')
09 connection (Region, ConnectedRegions)
10 select_shape (ConnectedRegions, SelectedRegions, 'anisometry', 'and', 1.0, 1.7)
11 Number := |SelectedRegions|
12 Eyes := []
13 for i := 1 to Number by 1
14   ObjectSelected := SelectedRegions[i]
15   area_center (ObjectSelected, Area, Row, Column)
16   excentricity (ObjectSelected, Anisometry, Bulkiness, StructureFactor)
17   dev_set_color ('green')
18   if ((Area > 500) and (Area < 50000))
19     dev_set_color ('red')
20     Eyes := [ObjectSelected,Eyes]
21   endif
22 endfor
23 dev_display (Image)
24 dev_set_color ('red')
25 dev_display (Eyes)
      
The steps in detail:
  1. Close all leftover graphics windows
  2. Load the image
  3. Get the image size for the graphics window
  4. Open a new graphics window
  5. Set the display style for regions to "filled"
  6. Select the image part to display in the graphics window
  7. Since the eyes are light, all dark patches of the image considered irrelevant and are masked out by means of a binarization threshold of greyvalue 128.
  8. Set region output to 'white'
  9. The light patches (currently one logical region) are split into several regions (one per connection component)
  10. All connection components with an anisometry between 1.0 and 1.7 are selected for further processing. Compare this line to the select_shape call in the first version of affe.dev. The first version shows how to avoid loops completely.
  11. Count the connection components
  12. Initialize the result variable
  13. Loop over all the connection components
  14. Select the current component
  15. Compute the component's area
  16. Compute the components excentricity and anisometry
  17. Turn the region output color to green
  18. Eyes are considered 'not too big' (Area) and 'quite round' (Anisometry). If both conditions match:
  19. Turn the region output color to red
  20. Set the output variable
  21. The last three lines of the example redraw the image and display the mandrill's eyes in red.

ic.dev

Here is a longer example of color image processing. The goal is to detect and distinguish the resistors, capacitors, chips, and chip pins on a board. Here is the program (line numbers added for reading convenience):
01 dev_close_window ()
02 read_image (Image, 'ic')
03 get_image_pointer__ (Image, Pointer, Type, Width, Height)
04 dev_open_window (0, 0, Width, Height, 'black', WindowID)
05 dev_set_draw ('fill')
06 dev_set_part (0, 0, Height-1, Width-1)
07 dev_display (Image)
08 dev_set_colored (12)
09 decompose3 (Image, Red, Green, Blue)
10 trans_from_rgb (Red, Green, Blue, Hue, Saturation, Intensity, 'hsv')
11 threshold__ (Saturation, Colored, 100, 255)
12 reduce_domain (Hue, Colored, HueColored)
13 threshold__ (HueColored, Red, 10, 19)
14 connection (Red, RedConnect)
15 select_shape (RedConnect, RedLarge, 'area', 'and', 150.000000, 99999.000000)
16 shape_trans (RedLarge, Resistors, 'rectangle2')
17 threshold__ (HueColored, Blue, 114, 137)
18 connection (Blue, BlueConnect)
19 select_shape (BlueConnect, BlueLarge, 'area', 'and', 150.000000, 99999.000000)
20 shape_trans (BlueLarge, Capacitors, 'rectangle2')
21 threshold__ (Intensity, Dark, 0, 50)
22 dilation_rectangle1 (Dark, DarkDilation, 14, 14)
23 connection (DarkDilation, ICLarge)
24 add_channels (ICLarge, Intensity, ICLargeGray)
25 threshold__ (ICLargeGray, ICDark, 0, 50)
26 shape_trans (ICDark, IC, 'rectangle2')
27 dilation_rectangle1 (IC, ICDilation, 5, 1)
28 difference (ICDilation, IC, SearchSpace)
29 dilation_rectangle1 (SearchSpace, SearchSpaceDilation, 14, 1)
30 union1 (SearchSpaceDilation, SearchSpaceUnion)
31 reduce_domain (Intensity, SearchSpaceUnion, SearchGray)
32 mean__ (SearchGray, SearchMean, 15, 15)
33 dyn_threshold__ (SearchGray, SearchMean, PinsRaw, 5.000000, 'light')
34 connection (PinsRaw, PinsConnect)
35 fill_up (PinsConnect, PinsFilled)
36 select_shape (PinsFilled, Pins, 'area', 'and', 10, 100)
37 dev_display (Image)
38 dev_set_draw ('margin')
39 dev_set_line_width (3)
40 dev_set_color ('red')
41 dev_display (IC)
42 dev_set_color ('green')
43 dev_display (Resistors)
44 dev_set_color ('blue')
45 dev_display (Capacitors)
46 dev_set_color ('yellow')
47 dev_display (Pins)
      
First, any leftover graphics windows are closed, then the color image is read and displayed in a new graphics window with the right size (lines 1-8). In lines 5 and 8, some output mode initialization is done. Then the RGB image is decomposed into its R, G, and B channels (lines 9). It is easiest to detect resistors and capacitors by color (reddish and blueish). The channels are therefore transformed into HSI coding (Hue, Saturation, Intensity). That way, a classification by color is much simpler than in RGB, if the colors are not pure. Colored objects (i.e. high saturation) are detected (line 11) and distinguished in red and blue objects (lines 13 and 17). After a little postprocessing to filter artifacts (lines 15 and 19), the resistors (variable Resistors) and capacitors (variable Capacitors) are identified correctly.

The chips are the darkest patches of the image, so a simple threshold (line 21) should yield good results. Problems arise, if the chip area is not homogenous enough. Therefore the threshold result is morphologically enlarged (line 22), split into connection components (line 23) and thresholded again (line 25). The result are several logical regions, each of which consist of one or more physical regions - you can best verify this with by observing variable ICDark in 12 color mode (enabled via the "Graphics window"/"Parameters" menu. The surrounding rectangles (line 26) of the logical regions match the chips exactly.

Finally the chip pins have to be detected. Since they are in the direct vicinity of the chips, the search space is limited to the areas a few pixels to the left and right of the chips. This search space is computed by morphological operators using the detected chip regions (lines 27 to 30). Since the greyvalue of the pins is not very stable, it can't be used as a feature. However, the greyvalue differences between neighbouring pixels can be used (line 33). Finally the artifacts are filtered (lines 34 to 36) and the pins are identified (variable Pins).

Finally the results are displayed in lines 37 to 47.

marks.dev

Here the goal is to detect the marks on the walking person. The algorithm is similar to the examples above. A very powerful operator in this example is fill_interlaced__. This operator is needed, if image sequences with large interlacing effects are processed. fill_interlaced__ filters these effects, resulting in a smooth image for further processing.

meteor_grab.dev

This is a minimalist framegrabber application: The program opens a Meteor grabber and displays the grabbed images in an infinite loop.

particles.dev

In this program, blood cells have to be counted. This is quite difficult, because there are large artifacts in the image and the image itself is very noisy. Nevertheless, the solution in hdevelop takes only a few lines of code.

stamps.dev

This little program shows how easy programming in hdevelop is and how powerful five lines of code can be: The program recognizes stamps in a stamp catalogue. The algorithm is as follows: Stamps are darker than the background (white page), therefore white is mapped out. And stamps are larger than letters, therefore all the small regions are mapped out. The leftover objects are the stamps (variable Stamps).

vessel.dev

This program requires a little interaction: It tries to distiguish the inside of a capillary tube from its outside. Since the image is very bad, some user support is needed. First, the texture is enhanced with a texture filter (laws_byte), then the user is asked to mark the inside and outside with a polygon (set points with the left mouse button, close the polygon with the right mouse button). From the mean greyvalues, a suitable threshold boundary is computed and the capillary borders are found (variable Vessel).

arithmetic.dev

The rest of the examples shows some capabilities of hdevelop, that are sometimes needed but are not related to actual image processing. Error messages that may occur in these examples are intended!

This program provides some mathematical operators to demonstrate the mathematical capabilities of hdevelop. Basically all the operators from the C math library can be used. Step through the example program and watch the variables-window. As you see, hdevelop can do simple arithmetics, vector arithmetics and string processing. On errors, hdevelop provides you with warnings.

comparisons.dev

By stepping through this example, you can see the results of several comparisons in the variables-window.

sine.dev

Plots a sine curve in the graphics-window.

string.dev

The last example: Shows some string formating. Watch the variables-window: The format options are the same as in the C printf function.

Known Bugs

Please bear in mind that this version of MVTec HORUS is our first port to FreeBSD. The main development platforms of MVTec HORUS are HP/UX and Solaris, so there may still be some flaws in the code (notably because of the BSD vs. SysV differences and the different Motif versions: FreeBSD is our only platform running Motif 2.0 - The code is well tested on 1.2 but 2.0 seems to be something totally different). However, we continue our work on the BSD port and plan to release bugfix updates over the Net (see below).

The Bugs:

  1. Sometimes hdevelop and hinspector crash during startup due to Motif problems.
  2. Drag and Drop (middle button) from the hdevelop variable window to the hdevelop graphics window is buggy. Just click on the icons in the variable window instead. Drag and Drop from the hdevelop variable window to the hinspector graphics window works as expected.

    Generally: Avoid Drag and Drop at this stage of the port. Motif 2.0 seems to have some incompatibilities to 1.2. Use clicks/double clicks/etc. instead. Sorry for the inconvenience.

  3. Draging the recycle-button in the hdevelop variable window (clicking with the middle mouse button) causes a segmentation fault.
  4. Loading of images in .ima format may very rarely cause a floating exception.
  5. On standalone computers without ethernet connection, hinspector has difficulties connecting to hdevelop (rpc client/server communication). Adding
    static_routes="loopback"
    route_loopback="${hostname} localhost"
    
    in the /etc/sysconfig networking section seems to cure this problem (further testing needed).
  6. Not really a bug, but an inconveniece for the user: Not all of the online documentation is translated yet and some of the existing translations may sound a little awkward. We're working on it. Translating 2.2MB German text needs time ...

Further Information

This demonstration package of MVTec HORUS is limited to the tools hdevelop and hinspector. The whole MVTec HORUS package covers a lot more:

MVTec HORUS is tested to run on the following hard- and software platforms:
SUN Sparc (SunOS and Solaris), SUN Sparc Ultra (Solaris), HP 9000 (HP/UX 9.*, 10.*) Silicon Graphics (Irix), ALPHA (OSF/1), Intel x86 (FreeBSD, Linux), IBM RS6000 (AIX), and others (upon request). The MVTec HORUS also run on Windows NT. A port of the interactive MVTec tools is on its way.

MVTec HORUS is developed and sold by MVTec Software GmbH:

For FreeBSD related bug reports and questions (but only those, please) send a mail to Walter Hafner. I did the FreeBSD port, but I am only marginally involved in the further MVTec HORUS development otherwise.

MVTec Software GmbH


Walter Hafner
Last modified: Thu Mar 6 14:39:02 MET