camellia 2.5.10-i486-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. data/README +58 -0
  2. data/doc/README +58 -0
  3. data/doc/camellia.dox +205 -0
  4. data/doc/html/annotated.html +46 -0
  5. data/doc/html/camellia_8h-source.html +1350 -0
  6. data/doc/html/camellia_8h.html +4873 -0
  7. data/doc/html/doxygen.css +310 -0
  8. data/doc/html/doxygen.png +0 -0
  9. data/doc/html/files.html +27 -0
  10. data/doc/html/ftv2blank.png +0 -0
  11. data/doc/html/ftv2doc.png +0 -0
  12. data/doc/html/ftv2folderclosed.png +0 -0
  13. data/doc/html/ftv2folderopen.png +0 -0
  14. data/doc/html/ftv2lastnode.png +0 -0
  15. data/doc/html/ftv2link.png +0 -0
  16. data/doc/html/ftv2mlastnode.png +0 -0
  17. data/doc/html/ftv2mnode.png +0 -0
  18. data/doc/html/ftv2node.png +0 -0
  19. data/doc/html/ftv2plastnode.png +0 -0
  20. data/doc/html/ftv2pnode.png +0 -0
  21. data/doc/html/ftv2vertline.png +0 -0
  22. data/doc/html/functions.html +292 -0
  23. data/doc/html/functions_func.html +204 -0
  24. data/doc/html/functions_vars.html +177 -0
  25. data/doc/html/globals.html +172 -0
  26. data/doc/html/globals_defs.html +37 -0
  27. data/doc/html/globals_func.html +170 -0
  28. data/doc/html/hierarchy.html +46 -0
  29. data/doc/html/index.html +8 -0
  30. data/doc/html/main.html +21 -0
  31. data/doc/html/pages.html +23 -0
  32. data/doc/html/structCamArithmParams.html +61 -0
  33. data/doc/html/structCamBasin.html +63 -0
  34. data/doc/html/structCamBitmapFont.html +38 -0
  35. data/doc/html/structCamBlobInfo.html +91 -0
  36. data/doc/html/structCamBlobs.html +52 -0
  37. data/doc/html/structCamImage.html +791 -0
  38. data/doc/html/structCamLabelingResults.html +47 -0
  39. data/doc/html/structCamLinearFilterKernel.html +64 -0
  40. data/doc/html/structCamMeasuresResults.html +55 -0
  41. data/doc/html/structCamMorphoMathsKernel.html +82 -0
  42. data/doc/html/structCamPoint.html +47 -0
  43. data/doc/html/structCamRLEImage.html +184 -0
  44. data/doc/html/structCamROI.html +89 -0
  45. data/doc/html/structCamRun.html +57 -0
  46. data/doc/html/structCamSepFilterKernel.html +68 -0
  47. data/doc/html/structCamTable.html +47 -0
  48. data/doc/html/structCamTableOfBasins.html +38 -0
  49. data/doc/html/structCamVolbergFwdParams.html +47 -0
  50. data/doc/html/structCamWarpingParams.html +79 -0
  51. data/doc/html/tab_b.gif +0 -0
  52. data/doc/html/tab_l.gif +0 -0
  53. data/doc/html/tab_r.gif +0 -0
  54. data/doc/html/tabs.css +102 -0
  55. data/doc/html/todo.html +28 -0
  56. data/doc/html/tree.html +132 -0
  57. data/doc/rtf/refman.rtf +38378 -0
  58. data/ext/INSTALL +9 -0
  59. data/ext/Makefile +139 -0
  60. data/ext/camellia_ruby.i +308 -0
  61. data/ext/camellia_ruby_wrap.cxx +16086 -0
  62. data/ext/extconf.rb +4 -0
  63. data/ext/install.rb +11 -0
  64. data/ext/swig_ruby.dsp +159 -0
  65. data/inc/camellia.h +2624 -0
  66. data/inc/camellia_internals.h +192 -0
  67. data/lib/camellia-fox.rb +39 -0
  68. data/test/test_arithm.rb +13 -0
  69. data/test/test_color_labeling.rb +45 -0
  70. data/test/test_copy.rb +13 -0
  71. data/test/test_draw.rb +15 -0
  72. data/test/test_fixed_filters.rb +23 -0
  73. data/test/test_fox.rb +106 -0
  74. data/test/test_fox2.rb +108 -0
  75. data/test/test_histogram.rb +18 -0
  76. data/test/test_hough.rb +29 -0
  77. data/test/test_labeling.rb +30 -0
  78. data/test/test_mask.rb +34 -0
  79. data/test/test_watershed.rb +35 -0
  80. data/test/ts_camellia.rb +10 -0
  81. metadata +138 -0
@@ -0,0 +1,192 @@
1
+ /** \file camellia_internals.h
2
+ * \brief Camellia Image Processing Library header file
3
+ * \author Bruno STEUX (ENSMP)
4
+ *
5
+ * Camellia Image Processing Library
6
+ *
7
+
8
+ The Camellia Image Processing Library is an open source low-level image processing library.
9
+ As it uses the IplImage structure to describe images, it is a good replacement to the IPL (Intel) library
10
+ and a good complement to the OpenCV library. It includes a lot of functions for image processing
11
+ (filtering, morphological mathematics, labeling, warping, loading/saving images, etc.),
12
+ some of them being highly optimized; It is also cross-platform and robust. It is doxygen-documented
13
+ and examples of use are provided.
14
+
15
+ This software library is an outcome of the Camellia european project (IST-2001-34410).
16
+ It was developped by the Ecole des Mines de Paris (ENSMP), in coordination with
17
+ the other partners of the project.
18
+
19
+ ==========================================================================
20
+
21
+ Copyright (c) 2002-2006, Ecole des Mines de Paris - Centre de Robotique
22
+ All rights reserved.
23
+
24
+ Redistribution and use in source and binary forms, with or without
25
+ modification, are permitted provided that the following conditions are met:
26
+
27
+ * Redistributions of source code must retain the above copyright
28
+ notice, this list of conditions and the following disclaimer.
29
+ * Redistributions in binary form must reproduce the above copyright
30
+ notice, this list of conditions and the following disclaimer
31
+ in the documentation and/or other materials provided with the distribution.
32
+ * Neither the name of the Ecole des Mines de Paris nor the names of
33
+ its contributors may be used to endorse or promote products
34
+ derived from this software without specific prior written permission.
35
+
36
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
37
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
38
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
41
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
42
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
43
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
44
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
45
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47
+
48
+ ==========================================================================
49
+
50
+ */
51
+
52
+ #ifndef _CAMELLIA_INTERNALS_H_
53
+ #define _CAMELLIA_INTERNALS_H_
54
+
55
+ // Binary images management
56
+ #ifdef CAM_64BITS
57
+ #ifdef _WIN32
58
+ #define CAM_BIT_BLOCK unsigned __int64
59
+ #else
60
+ #define CAM_BIT_BLOCK unsigned long long int
61
+ #endif
62
+ #define CAM_BIT_BLOCK_SIZE_SHIFT 6
63
+ #ifndef CAM_BIG_ENDIAN
64
+ #ifdef _WIN32
65
+ #define CAM_BIT_BLOCK_SWAP(x) ( \
66
+ (((x)&0x00000000000000ffi64)<<56)| \
67
+ (((x)&0x000000000000ff00i64)<<40)| \
68
+ (((x)&0x0000000000ff0000i64)<<24)| \
69
+ (((x)&0x00000000ff000000i64)<< 8)| \
70
+ (((x)&0x000000ff00000000i64)>> 8)| \
71
+ (((x)&0x0000ff0000000000i64)>>24)| \
72
+ (((x)&0x00ff000000000000i64)>>40)| \
73
+ (((x)&0xff00000000000000i64)>>56))
74
+ #else
75
+ #define CAM_BIT_BLOCK_SWAP(x) ( \
76
+ (((x)&0x00000000000000ffull)<<56)| \
77
+ (((x)&0x000000000000ff00ull)<<40)| \
78
+ (((x)&0x0000000000ff0000ull)<<24)| \
79
+ (((x)&0x00000000ff000000ull)<< 8)| \
80
+ (((x)&0x000000ff00000000ull)>> 8)| \
81
+ (((x)&0x0000ff0000000000ull)>>24)| \
82
+ (((x)&0x00ff000000000000ull)>>40)| \
83
+ (((x)&0xff00000000000000ull)>>56))
84
+ #endif //_WIN32
85
+ #else
86
+ #define CAM_BIT_BLOCK_SWAP(x) (x)
87
+ #endif
88
+ #else
89
+ #define CAM_BIT_BLOCK unsigned int
90
+ #define CAM_BIT_BLOCK_SIZE_SHIFT 5
91
+ #ifndef CAM_BIG_ENDIAN
92
+ #define CAM_BIT_BLOCK_SWAP(x) ((((x)&0x000000ff)<<24)|(((x)&0x0000ff00)<<8)|(((x)&0x00ff0000)>>8)|(((x)&0xff000000)>>24))
93
+ #else
94
+ #define CAM_BIT_BLOCK_SWAP(x) (x)
95
+ #endif
96
+ #endif
97
+ #define CAM_BIT_BLOCK_SIZE (sizeof(CAM_BIT_BLOCK)*8)
98
+
99
+ // Internal functions
100
+ typedef struct {
101
+ unsigned char *srcptr;
102
+ unsigned char *dstptr;
103
+ CamROI srcroi; // Source ROI after clipping
104
+ CamROI dstroi; // Dest ROI after clipping
105
+ int srcchoffset; // Channel offset for the source
106
+ int dstchoffset; // Channel offset for the destination image
107
+ int nChannels; // Number of effective channels (considering ROIs)
108
+ int srcinc; // Pixel to pixel increment
109
+ int dstinc; // Pixel to pixel increment
110
+ int srclinc; // Line to line increment
111
+ int dstlinc; // Line to line increment
112
+ int srcpinc; // Plane to plane increment
113
+ int dstpinc; // Plane to plane increment
114
+
115
+ int mask_xOffset;// Offset when mask doesn't fit within image boundaries
116
+ int mask_yOffset;// Offset when mask doesn't fit within image boundaries
117
+ CamRLEImage *mask; // Mask to be applied to the operation
118
+ CamRLEImage auto_mask; // Automatically allocated if provided mask is not RLE
119
+ } CamInternalROIPolicyStruct;
120
+
121
+ #define CAM_MASK_SUPPORT 1
122
+ #define CAM_IGNORE_COI_MISMATCH 2
123
+ #define CAM_NO_ROI_INTERSECTION 4
124
+
125
+ int camInternalROIPolicy(CamImage* src, CamImage *dst, CamInternalROIPolicyStruct *res, int options);
126
+ void camInternalROIPolicyExit(CamInternalROIPolicyStruct *res); // Call to this function is necessary only when the caller manages image bit-masking
127
+
128
+ const char *camGetErrorStr();
129
+ void camSetErrorStr(const char *s);
130
+
131
+ // Check arguments
132
+ #ifndef CAM_OPTIMIZE
133
+ #define CAM_CHECK_ARGS(function, condition) \
134
+ if (!(condition)) {camError(#function, "Bad argument : " #condition);return 0;}
135
+ #else
136
+ #define CAM_CHECK_ARGS(function, condition)
137
+ #endif
138
+
139
+ #ifndef CAM_OPTIMIZE
140
+ #define CAM_CHECK_ARGS2(function, condition, text) \
141
+ if (!(condition)) {camError(#function, "Bad argument : " #text);return 0;}
142
+ #else
143
+ #define CAM_CHECK_ARGS2(function, condition, text)
144
+ #endif
145
+
146
+ #ifndef CAM_OPTIMIZE
147
+ #define CAM_CHECK(function, condition) \
148
+ if (!(condition)) {camError(#function, NULL);return 0;}
149
+ #else
150
+ #define CAM_CHECK(function, condition)
151
+ #endif
152
+
153
+ // Mask management macros
154
+
155
+ #define INIT_MASK_MANAGEMENT \
156
+ if (iROI.mask) { \
157
+ run=iROI.mask->runs+1; \
158
+ while (run->line!=iROI.mask_yOffset) run++; \
159
+ } else { \
160
+ run=NULL; \
161
+ }
162
+
163
+ #define BEGIN_MASK_MANAGEMENT(code) \
164
+ startx=-iROI.mask_xOffset; \
165
+ do { \
166
+ if (!iROI.mask) { \
167
+ endx=width; \
168
+ } else { \
169
+ do { \
170
+ while ((run->value==0)&&(run->line==y+iROI.mask_yOffset)) { \
171
+ startx+=run->length; \
172
+ run++; \
173
+ } \
174
+ if (run->line!=y+iROI.mask_yOffset) break; \
175
+ endx=startx+run->length; \
176
+ } while ((endx<=0)&&(run++)); \
177
+ if (run->line!=y+iROI.mask_yOffset) break; \
178
+ if (startx<0) startx=0; \
179
+ if (startx>width) startx=width; \
180
+ if (endx>width) endx=width; \
181
+ code \
182
+ }
183
+
184
+ #define END_MASK_MANAGEMENT \
185
+ if (iROI.mask) { \
186
+ startx=endx; \
187
+ run++; \
188
+ } \
189
+ } while ((run)&&(run->line==y+iROI.mask_yOffset));
190
+
191
+ #endif
192
+
@@ -0,0 +1,39 @@
1
+ require 'rubygems'
2
+ require_gem 'fxruby'
3
+
4
+ require 'camellia'
5
+ include Camellia
6
+
7
+ class Fox::FXImage
8
+ def to_camellia
9
+ s=FXStream.new
10
+ mem=" "*(width*height*4)
11
+ s.open(FXStreamSave, width*height*4, mem)
12
+ unbound_savePixels=FXImage.instance_method(:savePixels)
13
+ bound_savePixels=unbound_savePixels.bind(self)
14
+ bound_savePixels.call(s)
15
+ image=CamImage.new(width, height, CAM_DEPTH_8U, CAM_COLORMODEL_RGBA)
16
+ image.set_pixels(mem)
17
+ return image
18
+ end
19
+ end
20
+
21
+ class Camellia::CamImage
22
+ def to_fox(app, picture=nil)
23
+ if picture==nil
24
+ pict=FXImage.new(app, nil, IMAGE_OWNED|IMAGE_KEEP, width, height)
25
+ else
26
+ pict=picture
27
+ end if
28
+ image=CamImage.new(width, height, CAM_DEPTH_8U, CAM_COLORMODEL_RGBA)
29
+ copy(image)
30
+ FXStream.new { |stream|
31
+ stream.open(FXStreamLoad, image.imageSize, image.to_s)
32
+ unbound_loadPixels=FXImage.instance_method(:loadPixels)
33
+ bound_loadPixels=unbound_loadPixels.bind(pict)
34
+ bound_loadPixels.call(stream)
35
+ }
36
+ return pict
37
+ end
38
+ end
39
+
@@ -0,0 +1,13 @@
1
+ require 'test/unit'
2
+ require 'lib/camellia'
3
+ include Camellia
4
+ class TestArithm < Test::Unit::TestCase
5
+ def test_arithm
6
+ source=CamImage.new
7
+ # load picture chess.pgm
8
+ source.load_pgm("resources/chess.pgm")
9
+ n=source.arithm(source,source,CAM_SUB)
10
+ # resulting pixel sum should be 0
11
+ assert_equal(n,0)
12
+ end
13
+ end
@@ -0,0 +1,45 @@
1
+ require 'test/unit'
2
+ require 'lib/camellia'
3
+ include Camellia
4
+ class TestLabeling < Test::Unit::TestCase
5
+ def test_labeling
6
+
7
+ # load picture alfa156.bmp
8
+ image=CamImage.new
9
+ image.load_bmp("resources/alfa156.bmp")
10
+ yuv=image.to_yuv
11
+
12
+ # set color clusters
13
+ clusters=CamTable.new
14
+ clusters.set([
15
+ # Ymin Ymax Umin Umax Vmin Vmax
16
+ 0, 60, 0, 255, 0, 255, # Black
17
+ 230, 255, 0, 255, 0, 255, # White
18
+ 0, 255, 0, 255, 140, 255 # Red
19
+ ])
20
+ cluster_colors=[cam_rgb(0,0,0),cam_rgb(255,255,255),cam_rgb(255,0,0)]
21
+
22
+ # threshold and encode
23
+ encoded=yuv.encode_color(clusters)
24
+ puts "Number of runs : #{encoded.nb_runs}"
25
+
26
+ # labeling
27
+ blobs=encoded.labeling!
28
+ puts "#{blobs.nb_blobs} blobs detected"
29
+
30
+ # print and deaw the results
31
+ i=0
32
+ blobs.each {|b|
33
+ puts "Blob #{i} : Val=#{b.value} (#{b.top},#{b.left},#{b.width},#{b.height}) Surface=#{b.surface}"
34
+ image.draw_rectangle(b.left,b.top,b.left+b.width-1,b.top+b.height-1,cluster_colors[b.value-1])
35
+ i=i+1
36
+ }
37
+
38
+ # save the result
39
+ image.save_bmp("output/ruby_alfa156_labeling.bmp")
40
+
41
+ # assertions
42
+ assert_equal(encoded.nb_runs,3026)
43
+ assert_equal(blobs.nb_blobs,190)
44
+ end
45
+ end
data/test/test_copy.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'test/unit'
2
+ require 'lib/camellia'
3
+ include Camellia
4
+ class TestCopy < Test::Unit::TestCase
5
+ def test_copy
6
+ source=CamImage.new
7
+ # load picture alfa156.bmp
8
+ source.load_bmp("resources/alfa156.bmp")
9
+ dest=CamImage.new(source.width,source.height,CAM_DEPTH_8U,CAM_COLORMODEL_RGBA)
10
+ source.copy(dest)
11
+ dest.save_bmp("output/copy_alfa156.bmp")
12
+ end
13
+ end
data/test/test_draw.rb ADDED
@@ -0,0 +1,15 @@
1
+ require 'test/unit'
2
+ require 'lib/camellia'
3
+ include Camellia
4
+
5
+ class TestDraw < Test::Unit::TestCase
6
+ def test_draw
7
+ image=CamImage.new(320,240,CAM_DEPTH_8U,CAM_COLORMODEL_RGB)
8
+ font=CamBitmapFont.new('resources/fonts/xenon2.bmp')
9
+ image.set!(0)
10
+ image.draw_line(0,0,320,240,cam_rgb(255,0,0))
11
+ image.fill_color(50,100,cam_rgb(255,0,0))
12
+ image.draw_text_bitmap('Hello World',100,140,font)
13
+ image.save_bmp('output/drawing_ruby.bmp')
14
+ end
15
+ end
@@ -0,0 +1,23 @@
1
+ require 'test/unit'
2
+ require 'lib/camellia'
3
+ include Camellia
4
+ class TestFixedFilters < Test::Unit::TestCase
5
+ def test_fixed_filters
6
+ source=CamImage.new
7
+ result=CamImage.new
8
+ # load picture chess.pgm
9
+ source.load_pgm("resources/chess.pgm")
10
+ # gaussian filtering 3x3
11
+ source.fixed_filter(result,CAM_GAUSSIAN_3x3);
12
+ # save the result
13
+ result.save_pgm("output/ruby_chess_gaussian_3x3.pgm");
14
+ # gaussian filtering 5x5
15
+ source.fixed_filter(result,CAM_GAUSSIAN_5x5);
16
+ # save the result
17
+ result.save_pgm("output/ruby_chess_gaussian_5x5.pgm");
18
+ # gaussian filtering 7x7
19
+ source.fixed_filter(result,CAM_GAUSSIAN_7x7);
20
+ # save the result
21
+ result.save_pgm("output/ruby_chess_gaussian_7x7.pgm");
22
+ end
23
+ end
data/test/test_fox.rb ADDED
@@ -0,0 +1,106 @@
1
+ require 'rubygems'
2
+ require_gem 'fxruby'
3
+ include Fox
4
+
5
+ require_gem 'camellia'
6
+ require 'camellia-fox.rb'
7
+ include Camellia
8
+
9
+ class ImageWindow < FXMainWindow
10
+
11
+ def initialize(app)
12
+ # Invoke base class initializer first
13
+ super(app, "Camellia/FXRuby test", nil, nil, DECOR_ALL, 0, 0, 440, 240)
14
+
15
+ contents = FXHorizontalFrame.new(self,
16
+ LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0, 0, 0, 0, 0, 0, 0, 0)
17
+
18
+ # RIGHT pane for the buttons
19
+ buttonFrame = FXVerticalFrame.new(contents, (FRAME_SUNKEN|LAYOUT_FILL_Y|
20
+ LAYOUT_TOP|LAYOUT_LEFT), 0, 0, 0, 0, 10, 10, 10, 10)
21
+
22
+ # Label above the buttons
23
+ FXLabel.new(buttonFrame, "Button Frame", nil,
24
+ JUSTIFY_CENTER_X|LAYOUT_FILL_X);
25
+
26
+ # Horizontal divider line
27
+ FXHorizontalSeparator.new(buttonFrame, SEPARATOR_RIDGE|LAYOUT_FILL_X)
28
+
29
+ # Erode button
30
+ erodeBtn = FXButton.new(buttonFrame,
31
+ "Erode Image...\tGrey scale erosion",
32
+ nil, nil, 0, (FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|
33
+ LAYOUT_TOP|LAYOUT_LEFT), 0, 0, 0, 0, 10, 10, 5, 5) { |button|
34
+ button.connect(SEL_COMMAND, method(:onCmdErode))
35
+ }
36
+
37
+ # Save button
38
+ saveBtn = FXButton.new(buttonFrame,
39
+ "Save Image...\tRead back image and save to file",
40
+ nil, nil, 0, (FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|
41
+ LAYOUT_TOP|LAYOUT_LEFT), 0, 0, 0, 0, 10, 10, 5, 5)
42
+ saveBtn.connect(SEL_COMMAND, method(:onCmdRestore))
43
+
44
+ # Exit button
45
+ FXButton.new(buttonFrame, "E&xit\tQuit FXRuby test", nil,
46
+ getApp(), FXApp::ID_QUIT, (FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|
47
+ LAYOUT_TOP|LAYOUT_LEFT), 0, 0, 0, 0, 10, 10, 5, 5)
48
+
49
+ # Create a FXBMPImage and load a picture from disk
50
+ @picture=FXBMPImage.new(getApp(), nil, IMAGE_KEEP|IMAGE_OWNED, 320, 240);
51
+ FXFileStream.open('resources/alfa156.bmp', FXStreamLoad) { |stream| @picture.loadPixels(stream) }
52
+ @picture.render
53
+ source=@picture.to_camellia
54
+ @image=source.to_yuv
55
+ @image.set_roi(CamROI.new(@image,1)) # Select Y plane (B&W)
56
+
57
+ @imgFrame=FXImageFrame.new(contents,@picture)
58
+
59
+ # Make a tip
60
+ FXToolTip.new(getApp())
61
+ end
62
+
63
+ # Create and initialize
64
+ def create
65
+ # Create the windows
66
+ super
67
+
68
+ # Make the main window appear
69
+ show(PLACEMENT_SCREEN)
70
+ end
71
+
72
+ # Restore image from offscreen pixmap
73
+ def onCmdRestore(sender, sel, ptr)
74
+ saveDialog = FXFileDialog.new(self, "Save as BMP")
75
+ if saveDialog.execute != 0
76
+ @picture.restore
77
+ # Get back a CamImage and save it
78
+ @picture.to_camellia.save_bmp(saveDialog.filename)
79
+ end
80
+ return 1
81
+ end
82
+
83
+ # Erode image
84
+ def onCmdErode(sender, sel, ptr)
85
+ @image.erode_circle5!
86
+ @image.to_fox(getApp(),@picture)
87
+ @picture.render
88
+ @imgFrame.update
89
+ end
90
+
91
+ end
92
+
93
+ if __FILE__ == $0
94
+ # Make application
95
+ application = FXApp.new("Camellia/FXRuby", "Camellia/FXRuby test")
96
+
97
+ # Make the main window
98
+ ImageWindow.new(application)
99
+
100
+ # Create the application window and resources
101
+ application.create
102
+
103
+ # Run the application
104
+ application.run
105
+ end
106
+
data/test/test_fox2.rb ADDED
@@ -0,0 +1,108 @@
1
+ require 'rubygems'
2
+ require_gem 'fxruby'
3
+ include Fox
4
+
5
+ require_gem 'camellia'
6
+ require 'camellia-fox.rb'
7
+ include Camellia
8
+
9
+ class ImageWindow < FXMainWindow
10
+
11
+ def initialize(app)
12
+ # Invoke base class initializer first
13
+ super(app, "Camellia/FXRuby test", nil, nil, DECOR_ALL, 0, 0, 440, 240)
14
+
15
+ contents = FXHorizontalFrame.new(self,
16
+ LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0, 0, 0, 0, 0, 0, 0, 0)
17
+
18
+ # RIGHT pane for the buttons
19
+ buttonFrame = FXVerticalFrame.new(contents, (FRAME_SUNKEN|LAYOUT_FILL_Y|
20
+ LAYOUT_TOP|LAYOUT_LEFT), 0, 0, 0, 0, 10, 10, 10, 10)
21
+
22
+ # Label above the buttons
23
+ FXLabel.new(buttonFrame, "Button Frame", nil,
24
+ JUSTIFY_CENTER_X|LAYOUT_FILL_X);
25
+
26
+ # Horizontal divider line
27
+ FXHorizontalSeparator.new(buttonFrame, SEPARATOR_RIDGE|LAYOUT_FILL_X)
28
+
29
+ # Erode button
30
+ erodeBtn = FXButton.new(buttonFrame,
31
+ "Erode Image...\tGrey scale erosion",
32
+ nil, nil, 0, (FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|
33
+ LAYOUT_TOP|LAYOUT_LEFT), 0, 0, 0, 0, 10, 10, 5, 5) { |button|
34
+ button.connect(SEL_COMMAND, method(:onCmdErode))
35
+ }
36
+
37
+ # Save button
38
+ saveBtn = FXButton.new(buttonFrame,
39
+ "Save Image...\tRead back image and save to file",
40
+ nil, nil, 0, (FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|
41
+ LAYOUT_TOP|LAYOUT_LEFT), 0, 0, 0, 0, 10, 10, 5, 5)
42
+ saveBtn.connect(SEL_COMMAND, method(:onCmdRestore))
43
+
44
+ # Exit button
45
+ FXButton.new(buttonFrame, "E&xit\tQuit FXRuby test", nil,
46
+ getApp(), FXApp::ID_QUIT, (FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|
47
+ LAYOUT_TOP|LAYOUT_LEFT), 0, 0, 0, 0, 10, 10, 5, 5)
48
+
49
+ # Load image using Camellia
50
+ source=CamImage.new
51
+ source.load_bmp("resources/alfa156.bmp")
52
+ @image=source.to_yuv
53
+ @image.set_roi(CamROI.new(@image,1)) # Select Y plane (B&W)
54
+
55
+ # Create a FXImage from the Camellia image
56
+ @picture=@image.to_fox(getApp())
57
+ @picture.render
58
+
59
+ @imgFrame=FXImageFrame.new(contents,@picture)
60
+
61
+ # Make a tip
62
+ FXToolTip.new(getApp())
63
+ end
64
+
65
+ # Create and initialize
66
+ def create
67
+ # Create the windows
68
+ super
69
+
70
+ # Make the main window appear
71
+ show(PLACEMENT_SCREEN)
72
+ end
73
+
74
+ # Restore image from offscreen pixmap
75
+ def onCmdRestore(sender, sel, ptr)
76
+ saveDialog = FXFileDialog.new(self, "Save as BMP")
77
+ if saveDialog.execute != 0
78
+ @picture.restore
79
+ # Get back a CamImage and save it
80
+ @picture.to_camellia.save_bmp(saveDialog.filename)
81
+ end
82
+ return 1
83
+ end
84
+
85
+ # Erode image
86
+ def onCmdErode(sender, sel, ptr)
87
+ @image.erode_circle5!
88
+ @image.to_fox(getApp(),@picture)
89
+ @picture.render
90
+ @imgFrame.update
91
+ end
92
+
93
+ end
94
+
95
+ if __FILE__ == $0
96
+ # Make application
97
+ application = FXApp.new("Camellia/FXRuby", "Camellia/FXRuby test")
98
+
99
+ # Make the main window
100
+ ImageWindow.new(application)
101
+
102
+ # Create the application window and resources
103
+ application.create
104
+
105
+ # Run the application
106
+ application.run
107
+ end
108
+
@@ -0,0 +1,18 @@
1
+ require 'test/unit'
2
+ require 'lib/camellia'
3
+ include Camellia
4
+ class TestHistogram < Test::Unit::TestCase
5
+ def test_histogram
6
+ source=CamImage.new
7
+ # load picture alfa156.bmp
8
+ source.load_bmp("resources/alfa156.bmp")
9
+ # convert to YUV
10
+ yuv=CamImage.new
11
+ yuv=source.to_yuv
12
+ # compute the histogram
13
+ result=CamImage.new
14
+ yuv.histogram_2_channels(2,3,result)
15
+ # save the result
16
+ result.save_pgm("output/alfa156_histo.pgm")
17
+ end
18
+ end
@@ -0,0 +1,29 @@
1
+ require 'test/unit'
2
+ require 'lib/camellia'
3
+ include Camellia
4
+ class TestHough < Test::Unit::TestCase
5
+ def test_hough
6
+ image=CamImage.new(100,100)
7
+ # Draw a filled circle in mask
8
+ image.set!(0)
9
+ image.draw_circle(40,40,50,128)
10
+ image.fill_color(40,40,128)
11
+ res=image.hough_circle(10,40,60)
12
+ puts "Found a circle at (#{res[1]},#{res[2]}) (radius=#{res[3]}) (confidence=#{res[0]})"
13
+ assert((res[1]-40).abs<=1)
14
+ assert((res[2]-40).abs<=1)
15
+
16
+ for i in 1..3 do
17
+ # Load an image with a road sign
18
+ image.load_bmp("resources/road#{i}.bmp")
19
+ yuv=CamImage.new
20
+ image.to_yuv(yuv)
21
+ yuv.set_roi(CamROI.new(1,8,8,image.width-16,image.height-128))
22
+ yuv.fixed_filter!(CAM_GAUSSIAN_3x3)
23
+ res=yuv.hough_circle(100,6,25)
24
+ image.draw_circle(res[1],res[2],res[3],cam_rgb(255,0,0))
25
+ image.save_bmp("output/road_circle_hough#{i}.bmp")
26
+ puts "Found a circle at (#{res[1]},#{res[2]}) (radius=#{res[3]}) (confidence=#{res[0]})"
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,30 @@
1
+ require 'test/unit'
2
+ require 'lib/camellia'
3
+ include Camellia
4
+ class TestLabeling < Test::Unit::TestCase
5
+ def test_labeling
6
+ image=CamImage.new
7
+ # load picture alfa156.bmp
8
+ image.load_bmp("resources/alfa156.bmp")
9
+ yuv=image.to_yuv
10
+ # consider only the V plane (red)
11
+ yuv.set_roi(CamROI.new(yuv,3))
12
+ # threshold and encode
13
+ thr=yuv.encode_threshold(150)
14
+ # labeling
15
+ blobs=thr.labeling!
16
+ puts "#{blobs.nb_blobs} blobs detected"
17
+ # draw rectangle on all detected blobs
18
+ blobs.each {|b| image.draw_rectangle(b.left,b.top,b.left+b.width-1,b.top+b.height-1,cam_rgb(255,0,0))}
19
+ # save the resulting picture
20
+ image.save_bmp("output/ruby_alfa156_labeling.bmp")
21
+ # find out the biggest blob
22
+ sorted=blobs.sort {|a,b| b.surface<=>a.surface}
23
+ puts "The bigger blob is at position (#{sorted[0].cx},#{sorted[0].cy}) and its surface is #{sorted[0].surface}"
24
+ # assertions
25
+ assert_equal(blobs.nb_blobs,12)
26
+ assert_equal(sorted[0].cx,170)
27
+ assert_equal(sorted[0].cy,128)
28
+ assert_equal(sorted[0].surface,601)
29
+ end
30
+ end
data/test/test_mask.rb ADDED
@@ -0,0 +1,34 @@
1
+ require 'test/unit'
2
+ require 'lib/camellia'
3
+ include Camellia
4
+ class TestMask < Test::Unit::TestCase
5
+ def test_mask
6
+ source=CamImage.new
7
+ # load picture chess.pgm
8
+ source.load_pgm("resources/chess.pgm")
9
+ mask=CamImage.new(source.width,source.height)
10
+ # draw a filled circle in mask
11
+ mask.set!(0)
12
+ mask.draw_circle(mask.width/2,mask.height/2,50,255)
13
+ n=mask.fill_color(mask.width/2,mask.height/2,255)
14
+ assert_equal(n,7837) # number of pixels filled with color
15
+ # encode the mask and associate it to the source image
16
+ encoded_mask=mask.encode
17
+ source.mask=encoded_mask
18
+ encoded_mask.inverse!
19
+ dest=CamImage.new
20
+ source.copy(dest) # copies only the mask! not like dup or clone!
21
+ # and then compute a sobel inside
22
+ encoded_mask.inverse!
23
+ b=source.sobel_v_abs(dest) # sobel only on the mask
24
+ dest.save_pgm("output/ruby_chess_sobel_mask.pgm")
25
+ # checking types
26
+ assert_equal(source.class,Camellia::CamImage)
27
+ assert_equal(encoded_mask.class,Camellia::CamRLEImage)
28
+
29
+ # use a non compressed mask
30
+ source.mask=mask
31
+ source.set!(0)
32
+ source.save_pgm("output/ruby_chess_hole.pgm");
33
+ end
34
+ end