Matlab imwrite function changes the pixel values - image

I tried to change some pixel values of a Grayscale image and save it using imwrite in matlab.
no problem with saving.
the problem is when I read it back, some pixel values have been changed. not exactly the same values I assigned to pixels before saving it.
I'm trying to hash images so 1unit difference will effect the hash numbers.

As mentioned by mmgp, JPG can be lossy. That means that some of the information in your image will be lost in favor of storage efficiency.
The rationale behind JPG is somewhat like that behind MP3 -- changes in hues etc. that the human eye is not particularly well-adapted to distinguish will be simplified or removed altogether, thus decreasing the amount of information in the image. The information in a JPG represents a similar-looking, but in fact very different image. This is probably what you're experiencing.
In Matlab, have a look at the output of help imwrite. You can give a parameter to the jpg write called 'Quality', which is a number between 0 and 100, 100 meaning (near-)lossless compression.
Although the JPEG standard does allow for (near-)lossless compression, it is not often used in practice (at least, in my field). More popular lossless image formats are PNG, JPEG2000 and TIFF. Read more about it here.
All of these are also available in Matlab's imwrite function.

Related

My .jpg file is larger than .png?

I used Microsoft Paint to create a 15248 x 6552 solid color picture. I saved it as both .png and .jpg and was expecting the .jpg to be smaller than .png, but it was not.
The .jpg file is 1.49MB, while the .png is 391KB. Shouldnt jpeg being a lossy compression be technically smaller in size?
I read somewhere that .png is better for solid colors etc, so I downloaded a picture form the web (not a solid color) and used paint to save it in both formats. This time the jpeg was smaller than png. Is it solely due to the gradient of colors? if so then why?
Even if the picture is a solid color should jpg encodng be able to compress it even better?
It's to be expected that PNG performs better than JPEG in this scenario.
As pointed out in other answer, PNG does a per-line pixel prediction, followed by ZLIB compression. If the image has a single colour, the prediction will produce a constant zero value for all the pixels, except for the start of each row. Hence the compression will be very effective. I'd bet that if the image were "landscape" (6552 x 15248 instead of 15248 x 6552) the compression would be even a little better.
JPEG compression, instead, divides the image in blocks of 8x8 pixels, and for each one it attempts to quantize finely the low frequency components and coarsely the high frequency components. This works nicely for "natural" (photographic or rendered) images, but no so nicely for images with few colors (or a single one!).
See some comparisons here.
Not necessarily.
PNG is a prediction-based algorithm, which means that it tries to deduct the value of one pixel based on previously coded pixels. I bet the prediction is really accurate for a solid image, thence the very good results.
JPEG accepts different "quality levels" which determine the size of your compressed file. The size differences between your experiment and the web version are likely due to that (unless you're downloading a different image, of course!).
Note that JPEG may introduce some image artifacts because it is a lossy algorithm, while PNG will recover the exact input image for you.
I've found for the same picture that if you save as PNG 1st then JPG the PNG will be smaller and if saved as JPG 1st it will be smaller than the PNG saved afterwards

How can an Interlaced .png file's size be smaller than the original file?

Ok, so I tried to use the imagemagick command:
"convert picA.png -interlace line picB.png"
to make an interlace version of my .png images. Most of the time, I got the resulting image is larger than the original one, which is kinda normal. However, on certain image, the resulting image size is smaller.
So I just wonder why does that happen? I really don't want my new image to lose any quality because of the command.
Also, is there any compatibility problem with interlaced .png image?
EDIT: I guess my problem is that the original image was not compressed as best as it could be.
The following only applies to the cases where the pixel size is >= 8 bits. I didn't investigate for other cases but I expect similar outcomes.
A content-identical interlaced PNG image file will almost always be greater because of the additional data for filter type descriptions required to handle the passes scanlines. This is what I explained in details in this web page based on the PNG RFC RFC2083.
In short, this is because the sum of the below number of bytes for interlaced filter types description per interlacing pass is almost always greater than the image height (which is the number of filter types for non-interlaced images):
nb_pass1_lines = CEIL(height/8)
nb_pass2_lines = (width>4?CEIL(height/8):0)
nb_pass3_lines = CEIL((height-4)/8)
nb_pass4_lines = (width>2?CEIL(height/4):0)
nb_pass5_lines = CEIL((height-2)/4)
nb_pass6_lines = (width>1?CEIL(height/2):0)
nb_pass7_lines = FLOOR(height/2)
Though, theoretically, it can be that the data entropy/complexity accidentally gets lowered enough by the Adam7 interlacing so that, with the help of filtering, the usually additional space needed for filter types with interlacing may be compensated through the deflate compression used for the PNG format. This would be a particular case to be proven as the entropy/complexity is more likely to increase with interlacing because the image data is made less consistent through the interlacing deconstruction.
I used the word "accidentally" because reducing the data entropy/complexity is not the purpose of the Adam7 interlacing. Its purpose is to allow the progressive loading and display of the image through a passes mechanism. While, reducing the entropy/complexity is the purpose of the filtering for PNG.
I used the word "usually" because, as shown in the explanation web page, for example, a 1 pixel image will be described through the same length of uncompressed data whether interlaced or not. So, in this case, no additional space should be needed.
When it comes to the PNG file size, a lower size for interlaced can be due to:
Different non-pixel encoding related content embedded in the file such as palette (in the case of color type =! 3) and non-critical chunks such as chromaticities, gamma, number of significant bits, default background color, histogram, transparency, physical pixel dimensions, time, text, compressed text. Note that some of those non-pixel encoding related content can lead to different display of the image depending on the software used and the situation.
Different pixel encoding related content (which can change the image quality) such as bit depth, color type (and thus the use of palette or not with color type = 3), image size,... .
Different compression related content such as better filtering choices, accidental lower data entropy/complexity due to interlacing as explained above (theoretical particular case), higher compression level (as you mentioned)
If I had to check whether 2 PNG image files are equivalent pixel wise, I would use the following command in a bash prompt:
diff <( convert non-interlaced.png rgba:- ) <( convert interlaced.png rgba:- )
It should return no difference.
For the compatibility question, if the PNG encoder and PNG decoder implement the mandatory aspects of the PNG RFC, I see no reason for the interlacing to lead to a compatibility issue.
Edit 2018 11 13:
Some experiments based on auto evolved distributed genetic algorithms with niche mechanism (hosted on https://en.oga.jod.li ) are explained here:
https://jod.li/2018/11/13/can-an-interlaced-png-image-be-smaller-than-the-equivalent-non-interlaced-image/
Those experiments show that it is possible for equivalent PNG images to have a smaller size interlaced than non-interlaced. The best images for this are tall, they have a one pixel width and have pixel content that appear random. Though, the shape is not the only important aspect for the interlaced image to be smaller than the non-interlaced image as random cases with the same shape lead to different size differences.
So, yes, some PNG images can be identical pixel wise and for non-pixel related content but have a smaller size interlaced than non-interlaced.
So I just wonder why does that happen?
From section Interlacing and pass extraction of the PNG spec.
Scanlines that do not completely fill an integral number of bytes are padded as defined in 7.2: Scanlines.
NOTE If the reference image contains fewer than five columns or fewer than five rows, some passes will be empty.
I would assume the behavior your experiencing is the result of the Adam7 method requiring additional padding.

Compression method effectiveness varies hugely

I decided I'd attempt an image compression (From pixel RGBs) idea I had for a bit of extra credit in class. I've finished, but I find the levels of compression I get varies HUGELY from image to image. With this image, I'm getting a file size 1.25x the size of the coresponding PNG. With this image however, I'm getting a file size 22.5x the size of the PNG.
My compression works by first assigning each color in the image with an int(starting from 0), then using that int rather than the actual color in the file. The file is formatted as:
0*qj8c1*50i2p2*pg93*9zlds4*2rk5*4ok4r6*8mv1w7*2r25l8*3m89o9*9yp7c10*111*2clz112*g1j13*2w34z14*auq15*3zhg616*mmhc17*5lgsi18*25lw919*7ip84+0!0!0!0!0!0!0!0!0!0!0!0!0!1!1!1!#2!2!2!2!2!2!2!2!2!2!2!2!2!3!3!3!#4!4!4!4!4!4!4!4!4!4!4!4!4!5!5!5!#6!6!6!6!6!6!6!6!6!6!6!6!6!0!0!0!#3!3!3!3!3!3!3!3!3!3!3!3!3!2!2!2!#1!1!1!1!1!1!1!1!1!1!1!1!1!4!4!4!#7!7!7!7!7!7!7!7!7!7!7!7!7!6!6!6!#5!5!5!5!5!5!5!5!5!5!5!5!5!8!8!8!#9!9!9!9!9!9!9!9!9!9!9!9!9!10!10!10!#8!8!8!8!8!8!8!8!8!8!8!8!8!11!11!11!#12!12!12!12!12!12!12!12!12!12!12!12!12!7!7!7!#13!13!13!13!13!13!13!13!13!13!13!13!13!14!14!14!#15!15!15!15!15!15!15!15!15!15!15!15!15!16!16!16!#17!17!17!17!17!17!17!17!17!17!17!17!17!13!13!13!#18!18!18!18!18!18!18!18!18!18!18!18!18!15!15!15!#10!10!10!10!10!10!10!10!10!10!10!10!10!19!19!19!#
Where the first bit (With the *s and base36 numbers) is the dictionary defining the colors, and the second part seperated by !s is the actual image.
Why am I seeing the level of compression vary so hugely image from image? Is there a flaw in my compression algorithm?
Edit: The fact that the actual level of compression is poor compared to JPEG or PNG isn't an issue, I wasn't expecting to rival any major formats.
Thanks

Match two images in different formats

I'm working on a software project in which I have to compare a set of 'input' images against another 'source' set of images and find out if there is a match between any of them. The source images cannot be edited/modified in any way; the input images can be scaled/cropped in order to find a match. The images can be in BMP,JPEG,GIF,PNG,TIFF of any dimensions.
A constraint: I'm not allowed to use any external libraries. ImageMagick is an exception and can be used.
I intend to use Java/Python. The software is purely command-line based.
I was reading on SO and some common image comparing algorithms. I'm planning to take 2 approaches.
1. I could use Histograms/buckets to find out the RGB values of the 2 images being compared.
2. Use SIFT/SURF to fin keypoint descriptors and find the euclidean distance between them and output the result based on the resultant distance.
The 2 images in comparison can be in different formats. An intuitive thought is that before analysis/comparison, the 2 images must be converted to a common format.I reasoned that the image should be converted to the one with lesser quality e.g. if the 2 input images are BMP and JPEG, convert the BMP to JPEG. This can be thought of as a pre-processing step.
My question:
Is image conversion to a common format required? Can 2 images of different formats be compared? IF they have to be converted before comparison, is my assumption of comparing from higher quality(BMP) to lower(JPEG) correct? It'd also be helpful if someone can suggest some algorithms for image conversion.
EDIT
A match is said to be found if the pattern image is found in the source image.
Say for example the source image consists of a football field with one player. If the pattern image contains the player EXACTLY as he is in the source image, then its a match.
No, conversion to a common format on disk is not required, and likely not helpful. If you extract feature descriptors from an image (SIFT/SURF, for example), it matters much less how the original images were stored on disk. The feature descriptors should be invariant to small compression artifacts.
A bit more...
Suppose you have a BMP that is an image of object X in your source dataset.
Then, in your input/query dataset, you have another image of object X, but it has been saved as a JPEG.
You have no idea how what noise was introduced in the encoding process that produced either of these images. There is lighting differences, atmospheric effects, lens effects, sensor noise, tone-mapping, gammut-mapping. Some of these vary from image to image, others vary from camera to camera. All this is done before the image even gets saved to storage in the camera. Yes, there are also JPEG compression artifacts, but to assume the BMP is "higher" quality and then degrade it through JPEG compression will not help. Perhaps the BMP has even gone through JPEG compression before being saved as a BMP.

Ruthlessly compressing large images for the web

I have a very large background image (about 940x940 pixels) and I'm wondering if anyone has tips for compressing a file this large further than Photoshop can handle? The best compression without serious loss of quality from Photoshop is PNG 8 (250 KB); does anyone know of a way to compress an image down further than this (maybe compress a PNG after it's been saved)?
I don't normally deal with optimizing images this large, so I was hoping someone would have some pointers.
It will first depend on what kind of image you are trying to compress. The two basic categories are:
Picture
Illustration
For pictures (such as photographs), a lossy compression format like JPEG will be best, as it will remove details that aren't easily noticed by human visual perception. This will allow very high compression rates for the quality. The downside is that excessive compression will result in very noticeable compression artifacts.
For illustrations that contain large areas of the same color, using a lossless compression format like PNG or GIF will be the best approach. Although not technically correct, you can think of PNG and GIF will compress repetitions the same color very well, similar to run-length encoding (RLE).
Now, as you've mentioned PNG specifically, I'll go into that discussion from my experience of using PNGs.
First, compressing a PNG further is not a viable option, as it's not possible to compress data that has already been compressed. This is true with any data compression; removing the entropy from the source data (basically, repeating patterns which can be represented in more compact ways) leads to the decrease in the amount of space needed to store the information. PNG already employs methods to efficiently compress images in a lossless fashion.
That said, there is at least one possible way to drop the size of a PNG further: by reducing the number of colors stored in the image. By using "indexed colors" (basically embedding a custom palette in the image itself), you may be able to reduce the size of the file. However, if the image has many colors to begin with (such as having color gradients or a photographic image) then you may not be able to reduce the number of colors used in a image without perceptible loss of quality.
Basically it will come down to some trial-and-error to see if the changes to the image will cause any change in image quailty and file size.
The comment by Paul Fisher reminded me that I also probably wouldn't recommend using GIF either. Paul points out that PNG compresses static line art better than GIF for nearly every situation.
I'd also point out that GIF only supports 8-bit images, so if an image has more than 256 colors, you'll have to reduce the colors used.
Also, Kent Fredric's comment about reducing the color depth has, in some situtations, caused a increase in file size. Although this is speculation, it may be possible that dithering is causing the image to become less compressible (as dithering introduces pixels with different color to simulate a certain other color, kind of like mixing pigment of different color paint to end up with another color) by introducing more entropy into the image.
Have a look at http://www.irfanview.com/, is an oldy but a goody.
Have found this is able to do multipass png compression pretty well, and does batch processing way faster than PS.
There is also PNGOUT available here http://advsys.net/ken/utils.htm, which is apparently very good.
Heres a point the other posters may not have noticed that I found out experimentally:
On some installations, the default behaviour is to save a full copy of the images colour profile along with the image.
That is, the device calibration map, usually SRGB or something similar, that tells using agents how to best map the colour to real world-colours instead of device independant ones.
This image profile is however quite large, and can make some of the files you would expect to be very small to be very large, for instance, a 1px by 1px image consuming a massive 25kb. Even a pure BMP format ( uncompressed ) can represent 1 pixel in less.
This profile is generally not needed for the web, so, when saving your photoshop images, make sure to export them without this profile, and you'll notice a marked size improvement.
You can strip this data using another tool such as gimp, but it can be a little time consuming if there are many files.
pngcrush can further compress PNG files without any data loss, it applies different combinations of the encoding and compression options to see which one works best.
If the image is photographic in nature, JPEG will compress it far better than PNG8 for the same loss in quality.
Smush.It claims to go "beyond the limitations of Photoshop". And it's free and web-based.
It depends a lot on the type of image. If it has a lot of solid colors and patterns, then PNG or GIF are probably your best bet. But if it's a photo-realistic image then JPG will be better - and you can crank down the quality of JPG to the point where you get the compression / quality tradeoff you're looking for (Photoshop is very good at showing you a preview of the final image as you adjust the quality).
The "compress a PNG after it's been saved" part looks like a deep misunderstanding to me. You cannot magically compress beyond a certain point without information loss.
First point to consider is whether the resolution has to be this big. Reducing the resolution by 10% in both directions reduces the file size by 19%.
Next, try several different compression algorithms with different grades of compression versus information/quality loss. If the image is sketchy, you might get away with quite rigorous JPEG compression.
I would tile it, Unless you are absolutely sure that you audience has bandwidth.
next is jpeg2k.
To get more out of a JPEG file you can use the 'Modified Quality Setting' of the "Save as Web" dialog.
Create a mask/selection that contains white where you want to keep the most detail, eq around Text. You can use Quick-Mask to draw the mask with a brush. It helps to Feather the selection, this results in a nice white to black transition in the next step.
save this mask/selection as a channel and give the channel a name
Use File->Save as Web
Select JPEG as file format
Next to the Quality box there is a small button with a circle on it. Click that. Select the saved channel in step 2 and play with the quality setting for the white and black part of the channel content.
http://www.jpegmini.com is a new service that creates standard jpgs with an impressively small filesize. I've had good success with it.
For best quality single images, I highly recommend RIOT. You can see the original image, aside from the changed one.
The tool is free and really worth trying out.
JPEG2000 gives compression ratios on photographic quality images that are significantly higher than JPEG (or PNG). Also, JPEG2000 has both "lossy" and "lossless" compression options that can be tuned quite nicely to your individual needs.
I've always had great luck with jpeg. Make sure to configure photoshop to not automatically save thumbnails in jpegs. In my experience I get the greatest bang/buck ratio by using 3 pass progressive compression, though baseline optimized works pretty well. Choose very low quality levels (e.g. 2 or 3) and experiment until you've found a good trade off.
PNG images are already compressed internally, in a manner that doesn't benefit from more compression much (and may actually expand if you try to compress it).
You can:
Reduce the resolution from 940x940 to something smaller like 470x470.
Reduce the color depth
Compress using a lossy compression tool like JPEG
edit: Of course 250KB is large for a web background. You might also want to rethink the graphic design that requires this.
Caesium is the best tool i have ever seen.

Resources