4

I've found a very strange jpeg file. (b.jpg)

This image has different sizes depending on which library you use, PIL or opencv.

For a comparative image (normal image), I created a.jpg.

The following code shows that the two libraries return different sizes!

What's wrong with this b.jpg ??

import cv2
from PIL import Image
a_path = "a.jpg"
b_path = "b.jpg"
PIL_a = Image.open(a_path)
CV2_a = cv2.imread(a_path)
PIL_b = Image.open(b_path)
CV2_b = cv2.imread(b_path)

PIL_a.size  # width, height
>> (235, 149)
CV2_a.shape[1], CV2_a.shape[0]  # width, height
>> (235, 149)

PIL_b.size  # width, height
>> (5312, 2988)
CV2_b.shape[1], CV2_b.shape[0]  # width, height
>> (2988, 5312)   <-- strange

a.jpg : a.jpg

b.jpg : b.jpg

Cauchy
  • 248
  • 1
  • 13
  • 2
    @Miki I know that. See the code again. I printed shape[1], shape[0]. – Cauchy May 11 '21 at 08:26
  • 2
    @PiotrSiekański I don't think the question is considered to be true duplication, because it compares OpenCV and PIL results. (SO allows duplicated answers - many answers are based on other answers). – Rotem May 11 '21 at 09:07

1 Answers1

4

The reason is the EXIF orientation tag

  • OpenCV cv2.imread method looks for the orientation tag, and rotates/flips the image accordingly.
  • Image.open doesn't look for the orientation tag - you may solve it programmatically.

Here is a code sample that reproduces your case (you need ExifTool for executing):

import numpy as np
import cv2
from PIL import Image
import subprocess as sp
import shlex

# Build synthetic image
img = np.full((100, 300, 3), 60, np.uint8)
cv2.putText(img, '1', (130, 70), cv2.FONT_HERSHEY_DUPLEX, 2, (255, 30, 30), 4)  # Blue number

cv2.imwrite('image.jpg', img)

# Change the orientation by setting "orientation" exif tag:
# https://superuser.com/questions/435443/how-can-i-modify-the-exif-orientation-tag-of-an-image
sp.run(shlex.split('exiftool -orientation=5 -n image.jpg'))  # Mark image as rotated.

cv_img = cv2.imread('image.jpg')
print((cv_img.shape[1], cv_img.shape[0]))  # (100, 300)

pil_img = Image.open('image.jpg')
print(pil_img.size)  # (300, 100)
pil_img.show()

cv2.imshow('cv_img', cv_img)
cv2.waitKey()
cv2.destroyAllWindows()

pil_img.show():
enter image description here

cv2.imshow('cv_img', cv_img):
enter image description here

Rotem
  • 30,366
  • 4
  • 32
  • 65