Monday, August 11, 2008

find closest RGB value

Given an RGB value, find the closest match in an 256-element array of RGB values.

Solution: Imagine graphing the values of the RGB table on a 3d coordinate system with R being X, G being Y, and B being Z. Then graph the given RGB value to find. Now all we need to do is find the point with the shortest distance between it and the given RGB.

#include <iostream>
#include <iomanip>
#include <math.h>
#include <float.h>

using namespace std;

struct RGB {
    short r, g, b;
    RGB(short _r, short _g, short _b) : r(_r), g(_g), b(_b) {}
    friend ostream& operator<<(ostream& _out, const RGB& _rgb);
};

ostream& operator<<(ostream& _out, const RGB& _rgb)
{
    return _out << "(" << setw(3) << _rgb.r << ", " 
        << setw(3) << _rgb.g << ", " 
        << setw(3) << _rgb.b << ")";
}

inline
double square(double x)
{
    return x*x;
}

/** 
 * @param[in] _rgb color to match
 * @param[in] _table table to search for closest color
 * @param[in] _tableSize number of elements in _table
 * @return the index to the table element with the closest similarity in color
 */
int findClosest(RGB *_rgb, RGB** _table, size_t _tableSize)
{
    double minDistance = DBL_MAX;
    double distance;
    int retVal;
    for (size_t i=0; i<_tableSize; i++)
    {
        distance = sqrt(
                square(_rgb->r - _table[i]->r) +
                square(_rgb->g - _table[i]->g) +
                square(_rgb->b - _table[i]->b) );
        if (distance < minDistance)
        {
            minDistance = distance;
            retVal = i;
        }
    }
    return retVal;
}

int main()
{
    const int size = 256;
    RGB *table[size];
    srand(time(NULL));
    for (int i=0; i<256; i++)
    {
        table[i] = new RGB(rand()%256, rand()%256, rand()%256);
        cout << *table[i] << endl;
    }
    cout << "closest=" << *table[findClosest(&RGB(0,0,0), table, 256)] << endl;
    return 0;
}

No comments: