I'm trying to cluster textures, based on the features extracted from Gabor bank that I've created. But the result is far from what is typically expected so here is what I'm doing >>
1-generate a filter bank (based on the Miki's answer here I'm getting both real and imaginary part so that I can later extract Magnitude feature)
void Gabor::generateFilterbank(int bankRows,int bankCols)
{
bankCol=bankCols;
bankRow=bankRows;
setBankSize();
int thetaStep=pos_th_max/bankCols;
int lambadaStep=(pos_lm_max/bankRows) /10;
for (int i = 1; i <= bankRows; i++) // cols = theta rows = lambda
for (int j = 1; j <= bankCols; j++ )
{
int ks=(kernel_size-1)/2;
Size KernalSize(ks,ks);
double Sigma = pos_sigma;
double Lambda = 0.5+(i*lambadaStep);
double Theta = (j*thetaStep)*CV_PI/180;
double psi = pos_psi;//*CV_PI/180
double Gamma = 0;
vector<Mat> realImag;
realImag.push_back(getGaborKernel(KernalSize,Sigma,Theta,Lambda,Gamma,psi,CV_32F));//real
realImag.push_back(getGaborKernelImag(KernalSize,Sigma,Theta,Lambda,Gamma,psi,CV_32F));//imag
Kernels.push_back(realImag);
}
}
2-process input image
void Gabor::process(Mat img)
{
img.convertTo(img, CV_32F, 1.0/255, 0);
for (int i=0;(unsigned)i<Kernels.size();i++)
{
vector<Mat > responseIR;
for (int j=0;(unsigned)j<Kernels[i].size();j++)
{
Mat IR ;
filter2D(img, IR , CV_32F,Kernels[i][j]);
responseIR.push_back(IR );
IR.release();
}
responses.push_back(responseIR);
}
}
3- extract the feature vector from all Gabor responses
vector<float> Gabor::getGaborFetures(ofstream &out,float name)
{
vector<float>fetures;
Mat magnituder (responses.size(),responses[0][0].rows*responses[0][0].cols,CV_32FC1, Scalar(0.0));
fetures.push_back(name);
if (responses.size()>0)
{
for (int i=0;(unsigned)i<responses.size();i+=2)
{
vector<float> mag,rel,imag;
mat2Vector(responses[i][0],rel);
mat2Vector( responses[i][1],imag);
cv::magnitude(rel,imag, mag);
for (int j=0;j<mag.size();j++)
{
magnituder.at<float>(i,j) =mag[j];
}
}
PCA pca( magnituder,Mat(),CV_PCA_DATA_AS_ROW,10);
Mat result(pca.project( magnituder));
magnituder.release();
for (int i=0;i<result.rows;i++)
{
for(int j=0;j<result.cols;j++)
{
fetures.push_back(result.at<float>(i,j));
}
}
result.release();
for (int i=0;(unsigned)i<fetures.size();i++)
out <<fetures[i]<<",";
out<<endl;
return fetures;
}
else
{
cerr<<"You have to process your image first!"<<endl;
return fetures;
}
}
4- finally cluster extracted features with K-means
int kt=14;
Mat labTexture;
kmeans(ftTexture,kt,labTexture,TermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS, 10000,0.0001),10,KMEANS_RANDOM_CENTERS );
currently, I'm testing the code on this dataset I expected to cluster data set to 14 class, for example, all bricks images goes to one folder.