As far as I know, a modern JPEG decoder produces the same image when given the same input JPEG file.
Normally, we create JPEG files in such a way that the decoded image is an approximation of some input image.
Is the JPEG format flexible enough to allow lossless encoding of arbitrary input images with a custom encoder?
I'd image you'd at least have to fiddle with how quantization tables are used to essentially disable them? Perhaps something else?
(To be clear, I don't mean the special 'lossless' mode in JPEG that many decoders don't support. I am talking about using the default, mainstream code path through the decoder.)
No. Even with no quantization, the RGB to YCbCr transformation is lossy in the low few bits. Also the chroma channels are then downsampled, but that step can be skipped. While the DCT is mathematically lossless, in reality it is lossy in the least significant bit or two in the integer representation.
Related
As we know jpeg , PNG , gif are all compressed file formats, my question is what is the original source of input we provide to these compression algorithms and in which form a image data is stored before it gets converted into one of these file formats.
That depends.
PNG is generally lossless, but it does have a limit on the number of bits/pixel. GIF turns out to be lossless, too, but it is more complicated to get a high number of colors. These formats are still compressed, but use a compression that doesn't lose data.
JPEG is lossy. If you save as a JPEG, you will not be able to revert back to another format without losing some clarity. By representing the data as equations it can get quite small, but it can start to look "blurry" as the approximations get worse.
There are other images formats, like TIFF, RAW and BMP, which generally don't do any compression, although they are really more like containers and technically can contain compressed data, but they usually don't.
The original, uncompressed, data depends on what generates it. A photoshop file will save as a PSD but internally may represent it differently in memory. Every digital camera may have a different way of laying out its internal memory, and the photo sensors tend to map 1 to 1 from a sensor to a memory location of a set number of bits.
The common pattern, however, is that each pixel of the image is stored as 3 (sometimes 4) color values, each one between 8 and 16 bits. The 3 values may represent Red, Green and Blue, or alternatively Hue, Saturation and Value. For design, it could be CMYK (Cyan, Magenta, Yellow and blacK). There could also be an alpha value. It's unusual to use more than 16 bits for each color channel and most common to use 8. Using 12 bits is considered by most to be full color, but that doesn't align very well on 32 bit or even 64 bit machines. Still, 12 bit is used sometimes in digital video signals since when broadcast serially the color values don't need to fit into words.
Different formats will go in a different order. Usually rows first, but some formats start at the bottom row and some start at the top.
So, the real answer is it depends on what the particular compressor is looking for. Most software that saves as JPEG or PNG will accept multiple formats and the most common is probably 32bit/pixels with 8 bytes each for RGB (red, green, blue) and one either unused or alpha. It will need width and height of the image so the image data should be width*height*4 in bytes. You generally pass in a defined constant that tells it the byte order: RBGA, ARGB, BGR, RGB, etc.
I'm trying to write a TCP client/server application that transmits objects containing OpenCv Mat. I'd like to serialize these objects using JSON. I found some libraries that help me in doing that (rapidjson), but they of course do not take into account images as object members.
What would you suggest to serialize in a JSON object a cv::Mat variable? How can I use RapidJson, for example, to achieve that?
imencode can be used to encode an viewable image (with CV_8UC1 or CV_8UC3 pixel formats) into a std::vector<uchar>. Link to documentation.
The vector<uchar> will contain the same bytes as if OpenCV had saved the image into one of the supported image file formats (such as JPEG or PNG) and then have the file bytes loaded back into a byte array.
imencode can be found in highgui module when using OpenCV 2.x, or imgcodecs module when using OpenCV 3.x.
With the compressed data in a vector<uchar>, you can use Base64 encoding to format it into a string, which can then be added as a JSON value inside a JSON object.
When using JSON to transmit large amounts of data, consider very very carefully the character encoding format that the JSON library is instructed to emit. Normally, If a large portion of the data is going to be Base64, you will want to make sure the JSON is emitted in UTF8.
If you have the option of sending in binary (which requires an "out-of-band" design in the web service, something not always doable), it should be seriously considered.
When considering different serialization choices for images, these things should be taken into account:
Typical image sizes (total number of pixels)
Size efficiency is less of a concern if images are small.
Pixel format (number of channels and precision)
Most common image file formats will only allow 8-bit grayscale and 24-bit RGB pixel data. Trying to save higher-precision pixel data into these image formats will result in partial loss of precision.
Available transmission bandwidth (if it is scarce enough to be a concern). With less available bandwidth, compression becomes more important.
Compression options.
Typical (photographic or synthetic) images are highly compressible due to the common sense that images that are too "dense" will be too hard to comprehend when viewed by human eyes.
Compression can be lossless or lossy.
Choice of compression may depend on the statistical characteristics of the pixel values (image content).
As mentioned above, if compression is performed by encoding into some image formats, you have to make sure the image format can satisfy the pixel value precision requirements of your application.
If no existing image format meets your requirements and you still want to perform lossless compression, consider using the zlib API that is integrated into the OpenCV Core module.
If you are good at image processing and data compression theory, you may be able to devise an application-specific compression method based on your own needs.
Remember that reducing the image resolution can be a powerful (and super-lossy) way of reducing the transmission file size. Consider carefully what minimum image resolution is actually needed for your application.
Other considerations
Binary or text
Endianness
Availability of highgui, imgcodecs or an image decoder for the chosen image format on the receiving end.
Information source: just did this a few months ago.
I have few questions on JPEG Compression.
In my windows system, I have some image processing application. For example, Windows msPaint: which provides an option to convert BMP image to JPEG format.
Can anybody please tell me, what is the JPEG compression here using in mspaint- is it lossy or lossless.
If somebody is referring to "JPEG Standard compression", which compression it is internally using: lossy or lossless?
Thanks in advance.
Alvin
JPEG is a family of related compression techniques. There is lossless JPEG but is it generally relegated to 12bit, medical applications.
Any JPEG that you are likely to use creates loss. This occurs at several steps.
The transformation from the RGB to YCbCR. The two color spaces intersect but do not have the same gamut of colors. RGB colors outside of YCbCr get clamped into range. Also the transformation from RGB to YCbCr is a floating point operation that creates integer values, so there are rounding errors.
The Discrete Cosine Transform is usually performed on the data using scaled integers. This introduces small rounding errors. Even if you do this in floating point there will be some small errors and the values have to be rounded to integers for the final output.
Quantization is the big one. This divides the DCT output by integer values. You can eliminate rounding at this step by making all the quantization values 1.
JPEG compression is considered a lossy compression, because it is not possible to build the exact binary from an original source through uncompression.
Even at the highest quality, JPEG works by discarding data. You control the quality to trade off what you think is an acceptable loss to still have a fair representation of your image. Although data is lost, what can be seen might still be identical to the untrained eye - and that is the point. The same as what minidisc used to do for audio.
The intent for JPEG is to make photographic images smaller in file size for internet transmission, you get to decide how small, but if you want absolute quality a format like TIFF is better suited.
Incidently, TIFF offers a lossless compression, but the file sizes are still massive!
One more thing... If you take a 300 x 500 bitmap and convert it to JPEG, then convert it back. The file size will still be the same, because bitmap works by storing a common number of bits per pixel. But the contents of the file will be quite different. In this regard it might be naively viewed as lossless, but in practical terms it is far from it.
I need to extract CbCr chroma data from JPEG images, for image analysis. (in C/C++)
As I understand it, the JPEG "raw data" is compressed YCbCr. Am I correct in this assumption? How can I verify this for a given image?
I am currently using TubroJpeg lib. The documentation of tjDecompressToYUV says that it:
Decompress a JPEG image to a YUV planar image. This function
performs JPEG but leaves out the color conversion step, so a
planar YUV is generated instead of an RGB image.
I am a bit confused as to the output of this function. I thought that YUV and YCbCr were slightly different color spaces. Does this mean that for UV chroma I'd need to manipulate the output, and that the output "UV" components are actually CbCr components ?
The JPEG standard has no knowledge of color spaces. It simply compresses color components.
If is the specific file format (e.g. JFIF, EXIF, ADOBE) that specifies the color format. In most cases it is YCbCR. In some cases it is not (some adobe).
This link may explained the confusion
http://en.wikipedia.org/wiki/Yuv#Confusion_with_Y.27CbCr
YUV and YCbCR are similar, but different. If there is no color conversion, I have to believe that they have confused YUV and YCbCr.
I am trying to compress my .jpeg image in Photoshop.
WHat is the best way to do this?
I am now calculating the bpp taking the image size in kb, calculating how many bits that is. Then I take the image size in pixel*pixel to get the amount of pixels in the image. After that I divide bits/pixels, to find how many bits per pixel the image has.
But How can I change this number? My guess is to change how many kb the image is, but how do i do this?
Thanks for any help!!
Yes, you can achieve higher compression ratio than 4 bits per pixel. Images with solid color can have rate as low as 0.13bpp.
In fact 4bpp is quite poor compression — it's same as uncompressed 16-color image or half of 256-color image, which even GIF can manage. JPEG can look decent at 1-2bpp.
in general, you cannot "compress" a jpeg image. all you can do is to reduce the image quality further in order to achieve a lower bpp value. jpeg streams are always compressed and they use a lossy compression method. it means that the original image will never ever be reconstructed from a jpeg image. the smaller the file the more information you have lost.
a specific "bpp value" is not, and should never be your target. especially with lossy compression. you should always look at your current image and decide whether it is still good enough or not.
if you still have the original image, try a lossless compression format, like zip-compressed or lzw-compressed tiff or compressed png. i'm sure PhotoShop can handle these formats as well. another softwares like IrfanView (https://www.irfanview.com/) or XnView MP (https://www.xnview.com/en/xnviewmp/) will convert your images too.
if you want manual (eg. full) control over your images, you should use command line utilities, like ImageMagick (https://imagemagick.org/) or NConvert (please find the XnView MP link above)
if you have only the jpeg images do not touch (edit & save) them. with every single save operation you lose another bunch of information. you should always work on file copies.
you should always keep your master image (the very picture you took with your phone or your camera).
of course, these rules of thumb will not answer your original question.