# 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). Commented Nov 29, 2017 at 8:11

You are getting a nan returned because you are performing an operation that yields undefined result.

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.

• so you mean iterate every intensity frequency and check if it is > 0,
– Abc
Commented Nov 29, 2017 at 8:23
• Correct, but since you shouldn't have to expect negative values I would just check for intensity values not equal to zero and throw exception if the are bellow. thus, you won't miss innapropriate images for the method. Commented Nov 29, 2017 at 8:51
• i tried it. but there is another problem i got .How can i share it? Should i edit my question? or i should post another question ?
– Abc
Commented Nov 29, 2017 at 10:19
• Also, cam i use histogram in int values?
– Abc
Commented Nov 29, 2017 at 10:35
• Please check me edited question.
– Abc
Commented Nov 29, 2017 at 10:50