1

I've already asked this question I did not get satisfactory answers, So I did more research and I'm putting this question forward in a better way. I read an image through OpenCV``imread method. And I saved it using imwrite method. It increases the output file size by more than double.

Below are the details of the images which I obtained from imagemagick (I did not write all the details down, I'm attaching the images for all the details are needed):

Input Image:

Format: JPEG (Joint Photographic Experts Group JFIF format)
Mime type: image/jpeg
Class: DirectClass
Geometry: 1836x3264+0+0
Resolution: 72x72
Print size: 25.5x45.3333
Units: PixelsPerInch
Type: TrueColor
Endianess: Undefined
Colorspace: sRGB
Depth: 8-bit
Channel depth:
    red: 8-bit
    green: 8-bit
    blue: 8-bit
Channel statistics:
    Pixels: 5992704
Compression: JPEG
Quality: 75
Filesize: 267KB
Number pixels: 5.993M

Output Image:

  • Format: JPEG (Joint Photographic Experts Group JFIF format)
  • Mime type: image/jpeg
  • Class: DirectClass
  • Geometry: 1836x3264+0+0
  • Units: Undefined
  • Type: TrueColor
  • Endianess: Undefined
  • Colorspace: sRGB
  • Depth: 8-bit
  • Channel depth: red: 8-bit green: 8-bit blue: 8-bit
  • Channel statistics:
    Pixels: 5992704
  • Compression: JPEG
  • Quality: 95
  • Filesize: 611KB
  • Number pixels: 5.993M

As you can see, the input image size is 267KB but the output image size turned out to be 611KB. Now I know that its size depends on the encoder, Compression value, bit-rate etc.
I want to know is there anyway I can save the image in the exact same size of the input image.

I also tried using the compression in openCV like this
cv2.imwrite('result.jpg', image, [int(cv2.IMWRITE_JPEG_QUALITY), 45]).
Here the image quality would be 45, but the image size would still be greater than the input image (around 300KB).
I don't want to go less than 45 because it would affect the image details and loss of data.

I tried using external libraries like scipy, matplotlib. But they all bump the image size regardless.

Any clue on why the output image increase and how we can fix it is very much appreciated.

Here is some code for reference

import cv2  #opencv library for image processing implementations 

def main():   
    im = cv2.imread('sample.jpg')
    cv2.imwrite('result.jpg', im)

if __name__=='__main__':
    main()

And here is the image for reference. Sample Image

greybeard
  • 2,249
  • 8
  • 30
  • 66
Beeti Sushruth
  • 321
  • 2
  • 12
  • You will get the same image, thus the same image size, if you save the image the way the original image was saved or generated in first place... Where does your original image come from, some cell phone? Do you have any information on how exactly the image is stored, which (JPEG) compression exactly is used? You can't expect any other software to have the exact same (JPEG) image saving than for example a (potential) highly adapted image saving software from some device, we don't know you used to take the original image in first place. You compare apples and oranges here, I'm afraid. – HansHirse Oct 14 '19 at 11:29
  • Hem, a copy will generate an image of exactly the same size. There is no point decompressing and recompressing. –  Oct 14 '19 at 11:55
  • @HansHirse My original image comes from cell phone. I don't have any idea on the JPEG compression it uses, I'm afraid. So you say, there is no way possible to save the image in it's original size from OpenCV. – Beeti Sushruth Oct 14 '19 at 12:17
  • @YvesDaoust I don't just want to copy it. Ofcourse there is some processing I want to do on the image before saving it. – Beeti Sushruth Oct 14 '19 at 12:17
  • @BeetiSushruth: if you modify the image, there is no reason it keeps the same size, even approximately. –  Oct 14 '19 at 12:24
  • By default the compression/quality factor being used by cv2 is higher and that's why you see the increased image size. You can mitigate this by passing the quality/compression threshold in the `cv2.write` function ex: `cv2.imwrite(path, image, [int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality])` here the jpg_quality value can be anything between 0-100. source: https://www.life2coding.com/save-opencv-images-jpeg-quality-png-compression/ – Neeraj Komuravalli May 27 '20 at 11:02

2 Answers2

1

Your original image has quality 75. If you don't define the quality of saving with OpenCV it defaults to 95, so you should expect the file to be larger.

If you want to set it to some maximum size, you can use ImageMagick like this to set it to, say 300kB:

convert sample.jpg -define jpeg:extent=300k a.jpg

And that gets you a 299,810 byte file with quality 83.

If you are prepared to permit 400kB, you can use:

convert sample.jpg -define jpeg:extent=400k a.jpg

and that gets you a 358,000 byte file with quality 93.


I wrote something similar in Python that lets you save at a specified size using a binary search here.

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
1

The solution for this will be, saving an image using imageio.imwrite, this worked for me, when I was doing image compression. while saving a compressed image file using CV2 it increased the compressed image size more than the original image size. imageio.imwrite solved this issue for me

example: imageio.imwrite("image_name.jpg", cv2_image)

The increase in file size while saving with jpg is that it decompresses the image file

Nikitha K
  • 11
  • 3