Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error using cv2.equalizeHist

I am trying to equalize the histogram of a gray level image using the following code:

import cv2
im = cv2.imread("myimage.png")
eq = cv2.equalizeHist(im)

The following exception is raised:

error: (-215) CV_ARE_SIZES_EQ(src, dst) && CV_ARE_TYPES_EQ(src, dst) && CV_MAT_TYPE(src->type) == CV_8UC1 in function cvEqualizeHist

The version of opencv is 2.4.2

Any guesses?

like image 794
Shan Avatar asked Mar 03 '14 17:03

Shan


4 Answers

cv2.equalizeHist only works on grayscale ( 1 channel ) images. either:

im = cv2.imread("myimage.png", 0)        # load as grayscale

or:

im = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY) # or convert
like image 58
berak Avatar answered Nov 15 '22 13:11

berak


I have had the same problem too. This is because your image is in BGR even if it looks like it is in grayscale. What you can do about it is:

  1. first convert the image from grayscale to bgr.
  2. use the image equilization function.
  3. Convert the image back to bgr.
  4. Tadaaaa!

I'll show you my code

# reading image
image = cv2.imread(image_path)

# Showing the orignal image
plt.imshow(image)
plt.title('Low-contrast256.tif')
plt.show()

# Displaying a histogram
plt.hist(image.ravel(),256,[0,256])
plt.title('Histogram of the orignal image')
plt.show()

# Converting image to grayscale 
image = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)

# Histogram equilization
image = cv2.equalizeHist(image)

# Converting image back to BGR
image = cv2.cvtColor(image,cv2.COLOR_GRAY2BGR)

# Showing the equilized image
plt.imshow(image)
plt.title('Equilized Low-contrast256.tif')
plt.show()

# Displaying a histogram
plt.hist(image.ravel(),256,[0,256])
plt.title('Histogram of the equilized image')
plt.show()
like image 44
abbujaansboy Avatar answered Oct 13 '22 22:10

abbujaansboy


I got the same error, here is the solution:

  1. Thanks to: zwep (Error using cv2.equalizeHist) and Reti43 (Conversion of image type int16 to uint8)

  2. Error

The error is because the dtype of the array as zwep said. But we can't just use img.astype(np.uint8) or np.uint8(img); it will change the image. Here is the result.

  • Raw Image(img):

enter image description here

plt.imshow(np.uint8(img),cmap=plt.cm.gray)

enter image description here

  1. Solution

    img1=np.uint8(cv2.normalize(img, None, 0, 255, cv2.NORM_MINMAX))
    plt.imshow(cv2.equalizeHist(img1),cmap=plt.cm.gray)
    

enter image description here

PS: Adaptive histogram equalization is better for MRI.

clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
plt.imshow(clahe.apply(img1),cmap=plt.cm.gray)

enter image description here

like image 11
Ningrong Ye Avatar answered Nov 15 '22 12:11

Ningrong Ye


If anyone else stumbled across this but is already using grayscale ($M \times N$) ndarrays... There can be another problem.

When you use cv2.imread() it reads in the image as a numpy ndarray using dtype=np.uint8. However, when I use any other method it can be stored as a dtype=np.uint16 which will trigger the following warning

OpenCV Error: Assertion failed (_src.type() == (((0) & ((1 << 3) - 1)) + (((1)-1) << 3))) in cv::equalizeHist, file C:\projects\opencv-python\opencv\modules\imgproc\src\histogram.cpp, line 3913
Traceback (most recent call last):
  File "<input>", line 1, in <module>
cv2.error: C:\projects\opencv-python\opencv\modules\imgproc\src\histogram.cpp:3913: error: (-215) _src.type() == (((0) & ((1 << 3) - 1)) + (((1)-1) << 3)) in function cv::equalizeHist

Solution:

img_int8 = img.astype(np.uint8)

EDIT: might be doing something wrong though... because the output now gives strange results in some cases of transformation.

like image 2
zwep Avatar answered Nov 15 '22 12:11

zwep