This page last changed on Jan 23, 2007 by kgomes.

I am using the OpenCV libraries where I can so I had to build them and store them locally in my home directory on nanomia. After build them, I needed to include them in the LD_LIBRARY_PATH. So in order to run the test-segmentation program, I have to do the following (example for Baxter clips):

  1. cd originalppms/Baxter
  2. export LD_LIBRARY_PATH=/usr/lib/aved:/home/kgomes/opencv-install/lib
  3. ~/aved/mbarivision/test-segmentation --input-frames=500-501@0 --mbari-segment-algorithm=AdaptiveThreshold --mbari-segment-algorithm-se-type=Benthic baxter

Now in order to view images, I had to export my display using:

  1. export DISPLAY=skagit.shore.mbari.org:0.0

and run a Xserver on skagit. Then I could view the results with:

  1. gm display baxter_segmented_000500.ppm

1/19/2007

I have the adapative thresholding working, but the results are quite different. I am going to try to examine the differences in each step of the process to see if I can minimize the differences.

The first step in the Matlab code is to convert the raw image to greyscale calling rgb2gray, in the C++ code, is uses the method called luminance to convert it to grayscale. When I take a difference of the two images and look at a histogram, they are close, but there are some differences (in the list below the rest of the values were 0).

0        1103
1        2790
2        7560
3       30549
4       86626
5      104728
6       70701
7       19907
8        1848
9         448
10        255
11        164
12        166
13         76
14         77
15         53
16         24
17         22
18         18
19          4
20          1
21          0

So the starting point looks like the luminance and rgb2gray and not exactly the same, but maybe they are close enough. It the errors compound, I will come back to this. Oh, by the way, I also converted the image to an OpenCV image and back to make sure that conversion was not causing any errors. I got the exact same results, so the conversion seems to be fine.

So now, I moved to the next step, which is the matlab imopen function using a structing element in the shape of a disk of radius 15. In OpenCV I constructed one of their structing elements and then ran the cvMorphologyEx function and compared that to the matlab opened image. Fortunately, not much changed and they looked very close, here is the histogram of the differences:

0        1639
1        4581
2        9865
3       36890
4       89465
5      108729
6       62680
7       12125
8         590
9         217
10        193
11         89
12         27
13         14
14         10
15          0
16          0
17          5
18          0

Now the next step is to compare the images after subtracting the background from the original image. Here is the difference histogram:

0       150603
1       142764
2        20474
3         3754
4         1887
5         1542
6         1124
7         1005
8          876
9          835
10         736
11         432
12         358
13         235
14         172
15         109
16          77
17          50
18          21
19          25
20          11
21           8
22           8
23           4
24           7
25           0
26           2
27           1
28           0

Although the images have diverged a little as the histogram spreads out, it actually is getting closer as the number move more towards zero. Now here is where it gets messy. OpenCV did not have a adaptive histogram equalization algorithm, so I took the one from the Graphic Gems IV code and tried to get it working here. There are a large number of variables to tweak so I am just playing with those variables to try to shrink the differences down (if that is possible). As a first pass, the results weren't horrible (leaving off bin numbers), but could be better. Let the iterations begin!

       23265
       53846
       26447
       64754
       28573
       25928
       25770
       29613
        9120
       12304
        7148
        4507
        3050
        2213
        1583
         909
         946
         825
         608
         434
         476
         465
         375
         312
         397
         342
         269
         275
         337
         258
         199
         163
         149
         149
         128
         121
          99
          95
          99
          79
          69
          58
          57
          58
          50
          48
          38
          33
          19
          12
           5
           4
           7
          11
           3
           4
           5
           2
           2
           2
           1
           0
           0
           1
           0
           0
           1

So after some iteration, it looks like an fClipLimit of 5.1 or 5.2 is the best for the test image. The only question I would have is whether or not this will change from image to image. I think, though because it is simply matrix manipulations, the most closely matched will always be the most closely matched. For now I will leave it at 5.1. If you are interested in how I found the best value, you can look at the excel spreadsheet I've attached (AdaptFClipLimitChart.xls).

The next step is to compare them after converting it to a binary image. In matlab, the graythresh function is used to find the threshold value using Otsu's method. After this is found, then that is applied to threshold the image using im2bw. In the C++ code, I used the cvThreshold method and used an undocumented type called CV_THRESH_OTSU (found in a forum). The results were not that good. I had 15,000 pixels (out of 45,000) that were thresholded differently. I grabbed the value from the threshold matlab method and used that as the threshold (matlab generated a level of 0.2 which comes out to 51.2 that I used in the cvThreshold with type CV_THRESH_BINARY. The results were WAY better and only 3,000 pixles were different. Now, the level that cvThreshold calculates is done by a routine called icvGetThreshVal_Otsu() and there is no visibility to see what value that is calculating. A forum suggested cutting/pasting the open code into my code ... maybe I will try that ...


AdaptFClipLimitChart.xls (application/octet-stream)
Document generated by Confluence on Feb 03, 2026 14:51