title: Finding entropy in opencv
body: <p>I need a function like <code>entropyfilt()</code> in matlab, which doesn't exists in opencv.</p>
  
  <p>In matlab, <code>J = entropyfilt(I)</code> 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.</p>
  
  <p>I wrote a function to implement it in c++, foreach pixel get its entropy like this:</p>
  
  <ol>
  <li>Use <code>cvCalHist</code> with the mask parameter appropriately set to get image ROI (That's a 9*9 rectangle).</li>
  <li>Normalize the histogram so the sum of its bins is equal to 1. </li>
  <li>Use the formula for (Shannon) entropy. </li>
  </ol>
  
  <p>I list the C++ code below:</p>
  
  <pre><code>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&lt;gray_src.width;i++){
              for(int j=0;j&lt;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-&gt;width-1,i+4)-i);
                  roi.height=(j-Max(0,j-4))+1+(Min(gray_src-&gt;height-1,j+4)-j);
                  cvSetImageROI(const_cast&lt;IplImage*&gt;(gray_src),roi);
                  IplImage*gray_src_non_const=const_cast&lt;IplImage*&gt;(gray_src);                            
  
                  //2.calHist,here I chose CV_HIST_SPARSE to speed up
                  cvCalcHist( &amp;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-   &gt;bins,&amp;it);node!=0;node=cvGetNextSparseNode(&amp;it)){
                  float gray_frequency=*(float*)CV_NODE_VAL((CvSparseMat*)hist-&gt;bins,node);
                  entroy=entroy-gray_frequency*(log(gray_frequency)/log(2.0f));//*(log(gray_frequency)/log(2.0))
                  }
                  ((float*)(local_entroy_image-&gt;imageData + j*local_entroy_image-&gt;widthStep))[i]=entroy;
                  cvReleaseHist(&amp;hist);
              }
          }
          cvResetImageROI(const_cast&lt;IplImage*&gt;(gray_src));
      }
  </code></pre>
  
  <p><strong>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.</strong></p>
  
  <p><strong>Does anyone know how to speed up it or know any other good implementation</strong>?</p>