Нахождение энтропии в opencv
Мне нужна функция какentropyfilt()
в Matlab, который неT существует в OpenCV.
В Matlab,J = entropyfilt(I)
возвращает массив J, где каждый выходной пиксель содержит значение энтропии окрестности 9 на 9 вокруг соответствующего пикселя во входном изображении I.
Я написал функцию для реализации ее в c ++, каждый пиксель получает свою энтропию следующим образом:
использованиеcvCalHist
с параметром маски, соответствующим образом установленным, чтобы получить ROI изображенияs прямоугольник 9 * 9).Нормализуйте гистограмму так, чтобы сумма ее бинов была равна 1.Используйте формулу для (Шеннона) энтропии.Я перечислю код C ++ ниже:
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;iheight-1,j+4)-j);
cvSetImageROI(const_cast(gray_src),roi);
IplImage*gray_src_non_const=const_cast(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(gray_src));
}
Однако код слишком медленный. Я протестировал его на изображении 600 * 1200, и оно стоит 120 с, в то время как entroyfilt в Matlab занимает всего 5 с.
Кто-нибудь знает, как ускорить его или знает какую-либо другую хорошую реализацию?