siox.cpp revision 411b8ce8881e841bd236bd6aab966cbbd166bd39
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani Copyright 2005, 2006 by Gerald Friedland, Kristian Jantz and Lars Knipping
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani Conversion to C++ for Inkscape by Bob Jamison
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani Licensed under the Apache License, Version 2.0 (the "License");
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani you may not use this file except in compliance with the License.
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani You may obtain a copy of the License at
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani Unless required by applicable law or agreed to in writing, software
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani distributed under the License is distributed on an "AS IS" BASIS,
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani See the License for the specific language governing permissions and
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani limitations under the License.
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani//########################################################################
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani//########################################################################
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * Convert integer A, R, G, B values into an pixel value.
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahanistatic unsigned long getRGB(int a, int r, int g, int b)
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani if (a<0) a=0;
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani if (r<0) r=0;
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani if (g<0) g=0;
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani if (b<0) b=0;
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * Convert float A, R, G, B values (0.0-1.0) into an pixel value.
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahanistatic unsigned long getRGB(float a, float r, float g, float b)
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani (int)(r * 256.0),
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani (int)(g * 256.0),
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani (int)(b * 256.0));
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani//#########################################
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani//# Root approximations for large speedup.
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani//#########################################
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani double y = cbrt_table[int(x*ROOT_TAB_SIZE )]; // assuming x \in [0, 1]
b3ff20978a5e9c5a9fdc693128f29988b4070c8aSusant Sahani double y = qn_table[int(x*ROOT_TAB_SIZE )]; // assuming x \in [0, 1]
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani double Y = y*y;
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahanistatic bool _clab_inited_ = false;
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani cbrt_table[0] = pow(float(1)/float(ROOT_TAB_SIZE*2), 0.3333);
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani qn_table[0] = pow(float(1)/float(ROOT_TAB_SIZE*2), 0.2);
dc75168823540076b354135f6e2de7a9a978fbcaZbigniew Jędrzejewski-Szmek cbrt_table[i] = pow(float(i)/float(ROOT_TAB_SIZE), 0.3333);
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani qn_table[i] = pow(float(i)/float(ROOT_TAB_SIZE), 0.2);
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * Construct this CieLab from a packed-pixel ARGB value
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani //printf("fr:%f fg:%f fb:%f\n", fr, fg, fb);
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani //fr = (float) pow((fr + 0.055) / 1.055, 2.4);
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani //fg = (float) pow((fg + 0.055) / 1.055, 2.4);
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani //fb = (float) pow((fb + 0.055) / 1.055, 2.4);
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani // Use white = D65
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani const float x = fr * 0.4124 + fg * 0.3576 + fb * 0.1805;
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani const float y = fr * 0.2126 + fg * 0.7152 + fb * 0.0722;
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani const float z = fr * 0.0193 + fg * 0.1192 + fb * 0.9505;
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani //printf("vx:%f vy:%f vz:%f\n", vx, vy, vz);
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani //vx = (float) pow(vx, 0.3333);
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani //vy = (float) pow(vy, 0.3333);
dc75168823540076b354135f6e2de7a9a978fbcaZbigniew Jędrzejewski-Szmek //vz = (float) pow(vz, 0.3333);
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani * Return this CieLab's value converted to a packed-pixel ARGB value
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani float vr =(float)(vx * 3.2406 + vy * -1.5372 + vz * -0.4986);
dc75168823540076b354135f6e2de7a9a978fbcaZbigniew Jędrzejewski-Szmek float vg =(float)(vx * -0.9689 + vy * 1.8758 + vz * 0.0415);
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani float vb =(float)(vx * 0.0557 + vy * -0.2040 + vz * 1.0570);
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani vr = (float)(1.055 * pow(vr, (1.0 / 2.4)) - 0.055);
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani vg = (float)(1.055 * pow(vg, (1.0 / 2.4)) - 0.055);
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani vb = (float)(1.055 * pow(vb, (1.0 / 2.4)) - 0.055);
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * Squared Euclidian distance between this and another color
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * Computes squared euclidian distance in CieLab space for two colors
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * given as RGB values.
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahanifloat CieLab::diffSq(unsigned int rgb1, unsigned int rgb2)
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * Computes squared euclidian distance in CieLab space for two colors
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * given as RGB values.
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahanifloat CieLab::diff(unsigned int rgb0, unsigned int rgb1)
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani//########################################################################
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani//########################################################################
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * Helper class for storing the minimum distances to a cluster centroid
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * in background and foreground and the index to the centroids in each
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * signature for a given color.
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani return *this;
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani//########################################################################
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani//# S I O X I M A G E
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani//########################################################################
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * Create an image with the given width and height
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant SahaniSioxImage::SioxImage(unsigned int widthArg, unsigned int heightArg)
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * Copy constructor
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant SahaniSioxImage &SioxImage::operator=(const SioxImage &other)
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani return *this;
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * Clean up after use.
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * Returns true if the previous operation on this image
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * was successful, else false.
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * Sets whether an operation was successful, and whether
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * this image should be considered a valid one.
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * was successful, else false.
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * Set a pixel at the x,y coordinates to the given value.
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * If the coordinates are out of range, do nothing.
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani unsigned int y,
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani unsigned int pixval)
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * Set a pixel at the x,y coordinates to the given r, g, b values.
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * If the coordinates are out of range, do nothing.
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahanivoid SioxImage::setPixel(unsigned int x, unsigned int y,
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani unsigned int a,
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani unsigned int r,
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani unsigned int g,
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani unsigned int b)
9c8e3101ceef00342263d57dce3fa61956824985Lennart Poettering unsigned int pixval = ((a << 24) & 0xff000000) |
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani ((b ) & 0x000000ff);
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * Get a pixel at the x,y coordinates given. If
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * the coordinates are out of range, return 0;
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahaniunsigned int SioxImage::getPixel(unsigned int x, unsigned int y)
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * Return the image data buffer
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * Set a confidence value at the x,y coordinates to the given value.
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * If the coordinates are out of range, do nothing.
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani unsigned int y,
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * Get a confidence valueat the x,y coordinates given. If
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * the coordinates are out of range, return 0;
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahanifloat SioxImage::getConfidence(unsigned int x, unsigned int y)
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * Return the confidence data buffer
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * Return the width of this image
7d4866548d028489d84c39af1bb9206842a77b2bDavid Herrmann * Return the height of this image
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * Initialize values. Used by constructors
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahanivoid SioxImage::init(unsigned int widthArg, unsigned int heightArg)
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani for (unsigned long i=0 ; i<imageSize ; i++)
ad1ad5c8e36ea795034fcdac660b15d7c141d55bSusant Sahani * Assign values to that of another
for (unsigned long i=0 ; i<imageSize ; i++)
for (unsigned int y=0 ; y<height; y++)
for (unsigned int x=0 ; x<width ; x++)
fputc((unsigned char) r, f);
fputc((unsigned char) g, f);
fputc((unsigned char) b, f);
fclose(f);
#ifdef HAVE_GLIB
if (!buf)
int row = 0;
for (unsigned int y=0 ; y<height ; y++)
for (unsigned int x=0 ; x<width ; x++)
p += n_channels;
bool has_alpha = true;
if (!pixdata)
return NULL;
int row = 0;
for (unsigned int y=0 ; y < height ; y++)
for (unsigned x=0 ; x < width ; x++)
p += n_channels;
return buf;
init();
init();
cleanup();
#ifdef HAVE_GLIB
#ifdef HAVE_GLIB
if (!sioxObserver)
if (!ret)
keepGoing = false;
return ret;
unsigned int backgroundFillColor)
init();
keepGoing = true;
for (unsigned long i=0 ; i<pixelCount ; i++)
delete[] imageClab;
delete[] labelField;
return workImage;
delete[] imageClab;
delete[] labelField;
return workImage;
delete[] imageClab;
delete[] labelField;
return workImage;
delete[] imageClab;
delete[] labelField;
return workImage;
//trace("### bgSignature:%d", bgSignature.size());
delete[] imageClab;
delete[] labelField;
return workImage;
delete[] imageClab;
delete[] labelField;
return workImage;
for (unsigned int i=0; i<pixelCount; i++)
if (i % progressResolution == 0)
float progress =
delete[] imageClab;
delete[] labelField;
return workImage;
bool isBackground = true;
int minIndex = 0;
if (d<minBg)
minBg = d;
minIndex = j;
if (d < minFg)
minFg = d;
minIndex = j;
//workImage.setValid(false);
if (isBackground)
delete[] imageClab;
for (unsigned int i=0; i < pixelCount; i++)
delete[] labelField;
return workImage;
for (unsigned long i = 0; i<pixelCount ; i++)
delete[] labelField;
keepGoing = false;
return workImage;
unsigned int leftBase,
unsigned int rightBase,
unsigned int recursionDepth,
unsigned int *clusterCount,
const unsigned int dims)
left++;
right--;
left++;
right--;
if (newpoint.C != 0)
(*clusterCount)++;
unsigned int leftBase,
unsigned int rightBase,
unsigned int recursionDepth,
unsigned int *clusterCount,
const float threshold,
const unsigned int dims)
left++;
right--;
left++;
right--;
unsigned int sum = 0;
(*clusterCount)++;
const unsigned int dims)
if (!input)
for (unsigned int i=0 ; i < length ; i++)
unsigned int stage1length = 0;
unsigned int stage2length = 0;
for (unsigned int i=0 ; i < stage2length ; i++)
double sizeFactorToKeep)
int curlabel = 0;
int maxregion= 0;
int maxblob = 0;
for (unsigned long i=0 ; i<pixelCount ; i++)
int regionCount = 0;
for (unsigned int i=0 ; i<pixelCount ; i++)
int componentSize = 0;
return componentSize;
for (unsigned long i=0; i<pixelCount; i++)
for (int y=0; y<yres; y++)
for (int y=0; y<yres; y++)
for (int x=0; x<xres; x++)
for (int x=0; x<xres; x++)
for (int y=0; y<yres; y++)
for (int y=0; y<yres; y++)
for (int x=0; x<xres; x++)
for (int x=0; x<xres; x++)
for (int i=0; i<cmSize; i++)
for (int y=0; y<yres; y++)
for (int y=0; y<yres; y++)
for (int x=0; x<xres; x++)
for (int x=0; x<xres; x++)
for (int i=0; i<pSize; i++)
sum += v*v;
return sum;