0

I'm using Python 3.11 with Pillow 9.3.0 and OpenCV 4.6.0.66. I want to make sure if I doing 90 degree rotate with PIL, the quality of image is same.

ret = False
frame = None
camera = cv2.VideoCapture(0, cv2.CAP_DSHOW)
if camera.isOpened():
    camera.set(cv2.CAP_PROP_FPS, 30.0)
    camera.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter.fourcc('m', 'j', 'p', 'g'))
    camera.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter.fourcc('M', 'J', 'P', 'G'))
    camera.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
    camera.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)
    for _ in range(0, 11, 1):
        ret, frame = camera.read()
    if ret:
        cv2.imwrite("1.jpg", frame)
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        pil_im = Image.fromarray(frame)
        buffer_ = io.BytesIO()
        pil_im.save(buffer_, format="JPEG", quality=95)
        print(f"Before Rotate: {buffer_.getbuffer().nbytes}")
        pil_im = pil_im.rotate(90, Image.Resampling.NEAREST, expand=True)
        buffer_ = io.BytesIO()
        pil_im.save(buffer_, format="JPEG", quality=95)
        print(f"After Rotate: {buffer_.getbuffer().nbytes}")
        pil_im.save("1_edit.jpg", format="JPEG", quality=95)

The result of that program:

Before Rotate: 269183 After Rotate: 268793

Are this output indicate that the quality image is drop? Thanks in advance!

Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
jon_17z
  • 91
  • 7
  • As you are doing resampling, which obviously most of the time reduces the image quality, and in your case its reducing the quality about 2 to 3% – Zain Ul Abidin Dec 08 '22 at 04:16
  • @ZainUlAbidin Is it possible to do rotate without resampling? If I read at https://www.cambridgeincolour.com/tutorials/image-interpolation.htm, there is a statement The 90° rotation is lossless because no pixel ever has to be repositioned onto the border between two pixels (and therefore divided). Are this statement valid? – jon_17z Dec 08 '22 at 04:21
  • 1
    This statement is valid only theoratically, in practise there is always a small margin of replacements hence that's the reason we need resampling for most reliable and accurate rotation – Zain Ul Abidin Dec 08 '22 at 04:43
  • 1
    See rotate_90 at https://deeplearninguniversity.com/pillow-python/pillow-image-rotate/ – fmw42 Dec 08 '22 at 05:12
  • @fmw42 After I try it, the size of rotated image is bigger than original image (2-3%). I think the transpose method is do resampling as well as rotate method. But anyway thanks – jon_17z Dec 08 '22 at 07:29
  • @fmw42 There is a note at the end of page "Note– Using transpose(Image.ROTATE_90) is the same as using rotate(90, expand = True). Similarly, transpose(Image.ROTATE_180) and transpose(Image.ROTATE_270) is the same as rotate(180, expand = True) and rotate(270, expand = True) respectively." – jon_17z Dec 08 '22 at 07:39
  • [mre] please. this code depends on camera access, making this hard to reproduce. – Christoph Rackwitz Dec 08 '22 at 08:56

1 Answers1

1

The length in bytes of a JPEG file is not a very accurate indicator of its quality. It can be affected by other things including the content of your image.

The statement that an image may be able to be rotated through 90 degrees without loss is correct since the raster grids will coinicide and no resampling will be required. If you want to convince yourself of this, you could try rotating the image back through -90 degrees and comparing the result with the original to prove there is no loss/difference - note that I am talking about rotating the originally captured frame with no JPEGs involved.

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • Thanks I already tried to rotate image back and the size of result image same as the size of original image. So when using parameter format="JPEG", we cannot use bytes as indicator of the quality right? – jon_17z Dec 08 '22 at 08:18
  • 1
    Yes, that's the first part of my answer. Try making a solid red 800x800 JPEG and an 800x800 JPEG full of random data `Image.fromarray(np.random.randint(0,256,(800,800,3), np.uint8)` and compare the sizes. The content will affect the size. – Mark Setchell Dec 08 '22 at 08:22