I need a function like entropyfilt() in matlab, which doesn't exists in opencv.
In matlab, J = entropyfilt(I) returns the array J, where each output pixel contains the entropy value of the 9-by-9 neighborhood around the corresponding pixel in the input image I.
I wrote a function to implement it in c++, foreach pixel get its entropy like this:
- Use
cvCalHistwith the mask parameter appropriately set to get image ROI (That's a 9*9 rectangle). - Normalize the histogram so the sum of its bins is equal to 1.
- Use the formula for (Shannon) entropy.
I list the C++ code below:
GetLocalEntroyImage( const IplImage*gray_src,IplImage*entopy_image){
int hist_size[]={256};
float gray_range[]={0,255};
float* ranges[] = { gray_range};
CvHistogram * hist = cvCreateHist( 1, hist_size, CV_HIST_SPARSE, ranges,1);
for(int i=0;i<gray_src.width;i++){
for(int j=0;j<gray_src.height;j++){
//calculate entropy for pixel(i,j)
//1.set roi rect(9*9),handle edge pixel
CvRect roi;
int threshold=Max(0,i-4);
roi.x=threshold;
threshold=Max(0,j-4);
roi.y=threshold;
roi.width=(i-Max(0,i-4))+1+(Min(gray_src->width-1,i+4)-i);
roi.height=(j-Max(0,j-4))+1+(Min(gray_src->height-1,j+4)-j);
cvSetImageROI(const_cast<IplImage*>(gray_src),roi);
IplImage*gray_src_non_const=const_cast<IplImage*>(gray_src);
//2.calHist,here I chose CV_HIST_SPARSE to speed up
cvCalcHist( &gray_src_non_const, hist, 0, 0 );*/
cvNormalizeHist(hist,1.0);
float total=0;
float entroy=0;
//3.get entroy
CvSparseMatIterator it;
for(CvSparseNode*node=cvInitSparseMatIterator((CvSparseMat*)hist- >bins,&it);node!=0;node=cvGetNextSparseNode(&it)){
float gray_frequency=*(float*)CV_NODE_VAL((CvSparseMat*)hist->bins,node);
entroy=entroy-gray_frequency*(log(gray_frequency)/log(2.0f));//*(log(gray_frequency)/log(2.0))
}
((float*)(local_entroy_image->imageData + j*local_entroy_image->widthStep))[i]=entroy;
cvReleaseHist(&hist);
}
}
cvResetImageROI(const_cast<IplImage*>(gray_src));
}
However, the code is too slow. I tested it in a 600*1200 image and it costs 120s, while entroyfilt in matlab only takes 5s.
Does anyone know how to speed up it or know any other good implementation?