|
900731 Data Handling for Eye-in-the-Sea on MARS : Notes from Porting Segmentation Code from Matlab to C++
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):
Now in order to view images, I had to export my display using:
and run a Xserver on skagit. Then I could view the results with:
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 ... |
| Document generated by Confluence on Feb 03, 2026 14:51 |