Code

ba85f0fa63be9c62e99f27b3c7491c1cab598f4b
[inkscape.git] / src / trace / siox.h
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
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
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 //########################################################################