Samplecode
This code snippet demonstrates how Image math and the [http://en.wikipedia.org/wiki/HSV_color_space HSV color space] can be used to isolate one particular color in an image.
Note that this is '''not''' a general solution to this problem. It only works for hues that are not near 0 or 1, where hue wraps around.
ImageView<PixelRGB<double> > rgb_im;
double hue_ref = 0.54;
ImageView<PixelHSV<double> > hsv_im = GaussianFilter( input, 1.0 );
ImageView<double> hue = ChannelSlice( hsv_im, 0 );
ImageView<double> sat = ChannelSlice( hsv_im, 1 );
ImageView<double> match_im = ( 1.0 - 20.0*abs(hue-hue_ref) ) * sat*sat;
The functions described below can be loaded into your program with:
#include <vw/Histogram/Histogram3D.h>
To generate a histogram from an image (where name is the image path):
Histogram3D hist(name,CBINS,RBINS,PBINS);
To write a histogram to disk (where name is the path to store the histogram in EXR format):
hist.write(name);
To load and compare two histograms:
Histogram3D one(firstname);
Histogram3D two(secondname);
printf("%f\n",one.match(two));
The functions described below can be loaded into your program with:
#include <vw/Texture/Texture.h>
To generate a ConvolutionFilterBank containing 52 Gaussian derivative and Laplacian filter kernels:
ConvolutionFilterBank cfb=generate_texture_kernels();
To calculate the texture vector for a given sample image:
ImageView<double> texture_vector=calculate_texture(your_image, cfb);
To compare a texture vector to a database of texture vectors, and sort by best match:
vector<TextureMatch> all_matches=best_texture_matches(texture_database, texture_vector);
Sample function for analyzing a sample and printing its texture vector to STDOUT, for storage in a database:
void print_to_database(string filename)
{
ConvolutionFilterBank cfb=generate_texture_kernels();
ImageView<double> your_image,calculation;
read_image(your_image,filename);
calculation=calculate_texture(your_image,cfb);
printf("%s\t1",filename.c_str());
for(int i=0;i<37;i++)
printf("\t%f",calculation(i,0));
printf("\n");
}
Sample function for loading a database, comparing to a sample, and printing the names of the 12 best matches:
void print_best_matches(string filename, string dbname)
{
ConvolutionFilterBank cfb=generate_texture_kernels();
ImageView<double> your_image,calculation;
read_image(your_image,filename);
calculation=calculate_texture(your_image,cfb);
string line;
ifstream myfile(dbname.c_str());
vector<string> in;
if (myfile.is_open())
{
while (!myfile.eof())
{
getline(myfile,line);
in.push_back(line);
}
myfile.close();
}
else
{
cerr<<"Unable to open file";
exit(1);
}
vector<texture> v(in.size());
double min[37],max[37];
for(int i=0;i<in.size();i++)
{
v[i].file=in[i].substr(0,in[i].find('\t'));
in[i]=in[i].substr(in[i].find('\t')+1);
v[i].segments=atoi(in[i].substr(0,in[i].find('\t')).c_str());
in[i]=in[i].substr(in[i].find('\t')+1);
for(int j=0;j<37;j++)
{
v[i].value[j]=atof(in[i].substr(0,in[i].find('\t')).c_str());
if((i==0)||(v[i].value[j]<min[j]))
min[j]=v[i].value[j];
if((i==0)||(v[i].value[j]>max[j]))
max[j]=v[i].value[j];
if(j!=36)
in[i]=in[i].substr(in[i].find('\t')+1);
}
}
for(int i=0;i<v.size();i++)
for(int j=0;j<37;j++)
v[i].value[j]=(v[i].value[j]-min[j])/max[j];
TextureDatabase db;
db.data=v;
for(int i=0;i<37;i++)
{
db.min[i]=min[i];
db.max[i]=max[i];
}
vector<TextureMatch> matches=best_texture_matches(db,calculation);
for(int i=0;i<12;i++)
printf("%s\n",matches[i].name.c_str());
}