I'm working on image processing tool which translates RGB colors to human readable keywords. I need to:
- Initialize/Declare 1000 static known elements set
- Perform 10 comparisons between a dynamic element and the whole 1000 elements (total 10x1000 comparisons)
- Repeat steps 1 & 2 thousands of images.
Each element is a Struct like this one:
struct KnownColor{
cv::Scalar rgb;
std::string name;
std::vector<std::string> strings;
KnownColor ( cv::Scalar rgb, std::string name, std::vector<std::string> strings) :
rgb(rgb),
name(name),
strings(strings) {};
};
Currently I'm using a static std::vector<>
to store them. To init this vector I'm currently using a function called once, and I push my 1000 elements into the vector. Every struct is initialised using the KnownColor constructor:
static std::vector<CustomStruct> Vector;
void vectorInit() //I call this only once per image:
{
...
Vector.push_back(KnownColor(Scalar(188,198,204),"Metallic Silver",std::vector<std::string>{"gray"}));
Vector.push_back(KnownColor(Scalar(152,175,199),"Blue Gray",std::vector<std::string>{"gray","blue"}));
... (1000 push_back in total)
}
The comparison function, is a custom Euclidean distance between the Scalars which returns the closest "knownColor" and its human readable keywords:
double min = std::numeric_limits<double>::max();
int index=0;
for(int i=0; i<KnownColors.size(); i++)
{
double tmp = scalarLABDistance(rgb,KnownColors[i].rgb);
if(tmp < distanceThreshold )
{
min = tmp;
break;
}
if(tmp < min )
{
min = tmp;
index = i;
}
}
return KnownColors[index].strings;
Sadly for now, the program is called from PHP and needs to be executed once per image (client request).
I wonder if a static init would be better (init is faster? iteration is faster?), or if there is a better way to compare something to a collection of static elements without using std::vector
.