ba85f0fa63be9c62e99f27b3c7491c1cab598f4b
1 #ifndef __SIOX_H__
2 #define __SIOX_H__
3 /**
4 * Copyright 2005, 2006 by Gerald Friedland, Kristian Jantz and Lars Knipping
5 *
6 * Conversion to C++ for Inkscape by Bob Jamison
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
21 /**
22 * Note by Bob Jamison:
23 * After translating the siox.org Java API to C++ and receiving an
24 * education into this wonderful code, I began again,
25 * and started this version using lessons learned. This version is
26 * an attempt to provide an dependency-free SIOX engine that anyone
27 * can use in their project with minimal effort.
28 *
29 * Many thanks to the fine people at siox.org.
30 */
32 #include <string>
33 #include <vector>
35 #define HAVE_GLIB
37 #ifdef HAVE_GLIB
38 #include <glib.h>
39 #include <gdk-pixbuf/gdk-pixbuf.h>
40 #endif
43 namespace org
44 {
46 namespace siox
47 {
50 //########################################################################
51 //# C L A B
52 //########################################################################
54 /**
55 *
56 */
57 class CLAB
58 {
59 public:
61 /**
62 *
63 */
64 CLAB()
65 {
66 C = 0;
67 L = A = B = 0.0f;
68 }
71 /**
72 *
73 */
74 CLAB(unsigned long rgb);
77 /**
78 *
79 */
80 CLAB(float lArg, float aArg, float bArg)
81 {
82 C = 0;
83 L = lArg;
84 A = aArg;
85 B = bArg;
86 }
89 /**
90 *
91 */
92 CLAB(const CLAB &other)
93 {
94 C = other.C;
95 L = other.L;
96 A = other.A;
97 B = other.B;
98 }
101 /**
102 *
103 */
104 CLAB &operator=(const CLAB &other)
105 {
106 C = other.C;
107 L = other.L;
108 A = other.A;
109 B = other.B;
110 return *this;
111 }
113 /**
114 *
115 */
116 virtual ~CLAB()
117 {}
119 /**
120 * Retrieve a CLAB value via index.
121 */
122 virtual float operator()(unsigned int index)
123 {
124 if (index==0) return L;
125 else if (index==1) return A;
126 else if (index==2) return B;
127 else return 0;
128 }
131 /**
132 *
133 */
134 virtual void add(const CLAB &other)
135 {
136 C += other.C;
137 L += other.L;
138 A += other.A;
139 B += other.B;
140 }
143 /**
144 *
145 */
146 virtual void mul(float scale)
147 {
148 L *= scale;
149 A *= scale;
150 B *= scale;
151 }
154 /**
155 *
156 */
157 virtual unsigned long toRGB();
159 /**
160 * Computes squared euclidian distance in CLAB space for two colors
161 * given as RGB values.
162 */
163 static float diffSq(unsigned int rgb1, unsigned int rgb2);
165 /**
166 * Computes squared euclidian distance in CLAB space for two colors
167 * given as RGB values.
168 */
169 static float diff(unsigned int rgb0, unsigned int rgb1);
172 unsigned int C;
173 float L;
174 float A;
175 float B;
178 };
181 //########################################################################
182 //# S I O X I M A G E
183 //########################################################################
185 /**
186 * This is a generic image type that provides a consistent interface
187 * to Siox, so that developers will not need to worry about data arrays.
188 */
189 class SioxImage
190 {
191 public:
193 /**
194 * Create an image with the given width and height
195 */
196 SioxImage(unsigned int width, unsigned int height);
198 /**
199 * Copy constructor
200 */
201 SioxImage(const SioxImage &other);
203 /**
204 * Assignment
205 */
206 SioxImage &operator=(const SioxImage &other);
208 /**
209 * Clean up after use.
210 */
211 virtual ~SioxImage();
213 /**
214 * Returns true if the previous operation on this image
215 * was successful, else false.
216 */
217 virtual bool isValid();
219 /**
220 * Sets whether an operation was successful, and whether
221 * this image should be considered a valid one.
222 * was successful, else false.
223 */
224 virtual void setValid(bool val);
226 /**
227 * Set a pixel at the x,y coordinates to the given value.
228 * If the coordinates are out of range, do nothing.
229 */
230 virtual void setPixel(unsigned int x,
231 unsigned int y,
232 unsigned int pixval);
234 /**
235 * Set a pixel at the x,y coordinates to the given r, g, b values.
236 * If the coordinates are out of range, do nothing.
237 */
238 virtual void setPixel(unsigned int x, unsigned int y,
239 unsigned int a,
240 unsigned int r,
241 unsigned int g,
242 unsigned int b);
244 /**
245 * Get a pixel at the x,y coordinates given. If
246 * the coordinates are out of range, return 0
247 */
248 virtual unsigned int getPixel(unsigned int x, unsigned int y);
251 /**
252 * Return the image data buffer
253 */
254 virtual unsigned int *getImageData();
256 /**
257 * Set a confidence value at the x,y coordinates to the given value.
258 * If the coordinates are out of range, do nothing.
259 */
260 virtual void setConfidence(unsigned int x,
261 unsigned int y,
262 float conf);
264 /**
265 * Get a confidence value at the x,y coordinates given. If
266 * the coordinates are out of range, return 0
267 */
268 virtual float getConfidence(unsigned int x, unsigned int y);
270 /**
271 * Return the confidence data buffer
272 */
273 virtual float *getConfidenceData();
275 /**
276 * Return the width of this image
277 */
278 virtual int getWidth();
280 /**
281 * Return the height of this image
282 */
283 virtual int getHeight();
285 /**
286 * Saves this image as a simple color PPM
287 */
288 bool writePPM(const std::string fileName);
292 #ifdef HAVE_GLIB
294 /**
295 * Special constructor to create an image from a GdkPixbuf.
296 */
297 SioxImage(GdkPixbuf *buf);
299 /**
300 * Creates a GdkPixbuf from this image. The user must
301 * remember to destroy the image when no longer needed.
302 * with g_free(pixbuf)
303 */
304 GdkPixbuf *getGdkPixbuf();
306 #endif
308 private:
310 SioxImage()
311 {}
313 /**
314 * Assign values to that of another
315 */
316 void assign(const SioxImage &other);
318 /**
319 * Initialize values. Used by constructors
320 */
321 void init(unsigned int width, unsigned int height);
323 bool valid;
325 unsigned int width;
327 unsigned int height;
329 unsigned long imageSize;
331 /**
332 * Pixel data
333 */
334 unsigned int *pixdata;
336 /**
337 * Confidence matrix data
338 */
339 float *cmdata;
340 };
346 //########################################################################
347 //# S I O X
348 //########################################################################
350 /**
351 *
352 */
353 class Siox
354 {
355 public:
357 /**
358 * Confidence corresponding to a certain foreground region (equals one).
359 */
360 static const float CERTAIN_FOREGROUND_CONFIDENCE; //=1.0f;
362 /**
363 * Confidence for a region likely being foreground.
364 */
365 static const float FOREGROUND_CONFIDENCE; //=0.8f;
367 /**
368 * Confidence for foreground or background type being equally likely.
369 */
370 static const float UNKNOWN_REGION_CONFIDENCE; //=0.5f;
372 /**
373 * Confidence for a region likely being background.
374 */
375 static const float BACKGROUND_CONFIDENCE; //=0.1f;
377 /**
378 * Confidence corresponding to a certain background reagion (equals zero).
379 */
380 static const float CERTAIN_BACKGROUND_CONFIDENCE; //=0.0f;
382 /**
383 * Construct a Siox engine
384 */
385 Siox();
387 /**
388 *
389 */
390 virtual ~Siox();
392 /**
393 * Extract the foreground of the original image, according
394 * to the values in the confidence matrix. If the operation fails,
395 * sioxImage.isValid() will be false.
396 * backgroundFillColor is any ARGB color, such as 0xffffff (white)
397 * or 0x000000 (black)
398 */
399 virtual SioxImage extractForeground(const SioxImage &originalImage,
400 unsigned int backgroundFillColor);
402 private:
404 /**
405 * Our signature limits
406 */
407 float limits[3];
409 /**
410 * Image width
411 */
412 unsigned int width;
414 /**
415 * Image height
416 */
417 unsigned int height;
419 /**
420 * Image size in pixels
421 */
422 unsigned long pixelCount;
424 /**
425 * Image data
426 */
427 unsigned int *image;
429 /**
430 * Image confidence matrix
431 */
432 float *cm;
434 /**
435 * Markup for image editing
436 */
437 int *labelField;
440 /**
441 * Maximum distance of two lab values.
442 */
443 float clusterSize;
445 /**
446 * Initialize the Siox engine to its 'pristine' state.
447 * Performed at the beginning of extractForeground().
448 */
449 void init();
451 /**
452 * Clean up any debris from processing.
453 */
454 void cleanup();
456 /**
457 * Error logging
458 */
459 void error(char *fmt, ...);
461 /**
462 * Trace logging
463 */
464 void trace(char *fmt, ...);
466 /**
467 * Stage 1 of the color signature work. 'dims' will be either
468 * 2 for grays, or 3 for colors
469 */
470 void colorSignatureStage1(CLAB *points,
471 unsigned int leftBase,
472 unsigned int rightBase,
473 unsigned int recursionDepth,
474 unsigned int *clusters,
475 const unsigned int dims);
477 /**
478 * Stage 2 of the color signature work
479 */
480 void colorSignatureStage2(CLAB *points,
481 unsigned int leftBase,
482 unsigned int rightBase,
483 unsigned int recursionDepth,
484 unsigned int *clusters,
485 const float threshold,
486 const unsigned int dims);
488 /**
489 * Main color signature method
490 */
491 bool colorSignature(const std::vector<CLAB> &inputVec,
492 std::vector<CLAB> &result,
493 const unsigned int dims);
496 /**
497 *
498 */
499 void keepOnlyLargeComponents(float threshold,
500 double sizeFactorToKeep);
502 /**
503 *
504 */
505 int depthFirstSearch(int startPos, float threshold, int curLabel);
508 /**
509 *
510 */
511 void fillColorRegions();
513 /**
514 * Applies the morphological dilate operator.
515 *
516 * Can be used to close small holes in the given confidence matrix.
517 */
518 void dilate(float *cm, int xres, int yres);
520 /**
521 * Applies the morphological erode operator.
522 */
523 void erode(float *cm, int xres, int yres);
525 /**
526 * Normalizes the matrix to values to [0..1].
527 */
528 void normalizeMatrix(float *cm, int cmSize);
530 /**
531 * Multiplies matrix with the given scalar.
532 */
533 void premultiplyMatrix(float alpha, float *cm, int cmSize);
535 /**
536 * Blurs confidence matrix with a given symmetrically weighted kernel.
537 */
538 void smooth(float *cm, int xres, int yres,
539 float f1, float f2, float f3);
541 /**
542 * Squared Euclidian distance of p and q.
543 */
544 float sqrEuclidianDist(float *p, int pSize, float *q);
546 /**
547 * Squared Euclidian distance of p and q.
548 */
549 float sqrEuclidianDist(const CLAB &p, const CLAB &q);
552 };
557 } // namespace siox
558 } // namespace org
560 #endif /* __SIOX_H__ */
561 //########################################################################
562 //# E N D O F F I L E
563 //########################################################################