# Why entropy is undefined in low contrast image

I am trying to measure contrast of image by entropy of histogram of image.

Code for computing entropy

float measureContrast_inImage(Mat imagel) {

Mat hist;
/// Establish the number of bins
int histSize = 256;
/// Set the ranges ( for B,G,R) )
float range[] = { 0, 256 };
const float* histRange = { range };
bool uniform = true; bool accumulate = false;
/// Compute the histograms:
calcHist(&imagel, 1, 0, Mat(), hist, 1, &histSize, &histRange, uniform, accumulate);
hist /= imagel.total();

Mat logP;
cv::log(hist, logP);

cv::imshow("logP", logP);

//Performs an element-wise multiplication or division of the two matrices
float entropy = -1 * sum(hist.mul(logP)).val[0];

cout << entropy << endl;

//float entropy = 0;

waitKey(0);
return entropy;
}


Lena image

But entropy is -nan(ind)

similarly, entropy is undefined for another Image.

Entropy is 5.29657 for another image.

Is there any problem in my code.

I wonder that why in low contrast image, entropy is undefined. Kindly help me to figure out.

Edited

I computed histogram and get entropy by the following code and my entropy is 256

float entropy(Mat seq, Size size, int index)
{

int cnt = 0;

float entr = 0;

float total_size = size.height * size.width; //total size of all symbols in an image

for (int i = 0; i<index; i++)
{

float sym_occur = (float)seq.at<uchar>(0, i); //the number of times a sybmol has occured

if (sym_occur>0) //log of zero goes to infinity

{

cnt++;

entr += (sym_occur / total_size)*(log2(total_size / sym_occur));

}
}

cout << "cnt: " << cnt << endl;

return entr;
}

void imhist(Mat image, int histogram[])
{
// initialize all intensity values to 0
for (int i = 0; i < 256; i++)
{
histogram[i] = 0;
}

// calculate the no of pixels for each intensity values
for (int y = 0; y < image.rows; y++)
for (int x = 0; x < image.cols; x++)
histogram[(int)image.at<uchar>(y, x)]++;
}

Mat histDisplay(int histogram[], const char* name)
{
int hist[256];
for (int i = 0; i < 256; i++)
{
hist[i] = histogram[i];
}
// draw the histograms
int hist_w = 512; int hist_h = 400;
int bin_w = cvRound((double)hist_w / 256);

Mat histImage(hist_h, hist_w, CV_8UC1, Scalar(255, 255, 255));

// find the maximum intensity element from histogram
int max = hist[0];
for (int i = 1; i < 256; i++) {
if (max < hist[i]) {
max = hist[i];
}
}

// normalize the histogram between 0 and histImage.rows

for (int i = 0; i < 256; i++) {
hist[i] = ((double)hist[i] / max)*histImage.rows;
}

// draw the intensity line for histogram
for (int i = 0; i < 256; i++)
{
/*line(histImage, cvPoint(bin_w*(i), hist_h),
cvPoint(bin_w*(i), hist_h - hist[i]),
Scalar(0, 0, 0), 1, 8, 0);*/
line(histImage, cvPoint(bin_w*(i), hist_h),
cvPoint(bin_w*(i), hist_h - hist[i]),
Scalar(0, 0, 0));
}

// display histogram
//namedWindow(name, CV_WINDOW_AUTOSIZE);
//imshow(name, histImage);
return histImage;
}

int main () {
int hist[256];
imhist(image, hist);
Mat histImg = histDisplay(hist, "hist");

float en = entropy(histImg, image.size(), 256);
}


I believe that it is still wrong. Please correct me .

• You can put your code in a try-catch block and then you'll be able to catch the line that is causing the exception (just put a breakpoint somewhere in your catch block). – dsp_user Nov 29 '17 at 8:11

Based on your code, the only option I can see is the log operater that theoretically yields $-\infty$ when you attempt to take the logarithm of a 0-valued pixel. C++ will thus consider it not a number. Other functions I have seen for calculating entropy such as this example in octave, just ignore the zero pixels to solve these cases.