Introduction

Wavelet transform is the replacement of the well known DCT in JPEG 2000 standard (For a review of the subject, have a look at M. Rabanni, An overview of the JPEG 2000 still image compression standard, Signal Processing: Image Communication 17 (2002) 3-48.) The advantage of wavelets over Fourier is that you transform the whole image without subdivision to 8x8 blocks. Hence you can achieve more compression without blocking defect with superb quality. The Bior97 is one of the filters used in JPEG 2000 with floating point coefficients, allowing perfect compression quality results. I've written an SSE optimized version of this transform for faster processing extending the BaseFWT2D class from my other article 2D Fast Wavelet Transform Library for Image Processing.

The compression of the wavelet-spectrum in JPEG 2000 is implemented with arithmetic codec, though there are several other schemes available for compression. One of them is embedded zero tree (EZW) algorithm. Its advantage is speed. It takes about 1 ms or so to compress about 640x480 wavelet-spectrum. In short, EZW takes advantage of the fact that every pixel in the wavelet frequency band has 4 child pixels in the previous band. It is similar to twice down sampled series of image, with every down sampled image's pixels having four corresponding child pixels in the previous image. So with 3 level wavelet-transform, there are trees of pixels with corresponding structure 1-4-16. If the root pixel of that tree is equal to zero, we set the whole tree to zero without too much loss of the details in the reconstructed image. So instead of saving 21 pixels for a tree using 168 bits, we encode it with 1 bit only as a zero tree, 1:168 compression. In my EZW implementation, I scan wavelet-spectrum in predefined scanning order inspecting those trees, if the root is zero and its four children in the next level are also zeros, I output 0 bit to the stream only, 1:168 compression of the tree. If this condition is not met I output 1 bit and the root pixel value. Then also just one 0 bit for its zero pixel children, having 1:40 compression for that part of the tree and 1 bit and the pixels values for non-zeros from the second level and its children at the third level. With EZW scheme, we actually rearrange the wavelet spectrum, encoding only non-zero pixel coefficients. This way encoded wavelet-spectrum can also be entropy coded with arithmetic codec. It provides about 1.5 additional compression only.

Background

You should have a background with fast wavelet transform for image processing and principles behind embedded zero tree algorithm. I'm not going to introduce another tutorial on the subject. Just have a look at the various papers available on the Internet. My intent is to share my optimized code. I used the EZW paper "Embedded Zerotree Wavelet Encoding" written by C. Valens when I studied the algorithm. There you can also find a wavelet tutorial. Here I provide my own C++ implementation of the algorithm.

Using the Code

I provided gray scale image compression console application only, with which you can compress the image to my EZW custom file. The RGB image is converted to a gray scale one and then compressed to the file. Just run the console with the following params:

>ezwconsole.exe c image_file quality

Here image_file is your file to compress and quality is an integer in the range 0 to 100 indicating compressed quality of the image. You can pass any image format to it as it uses GDI+ Bitmap class to load it. It will output image_file.ezw as the compressed image file, and print compression results.

To decompress the file, just run it this way:

>ezwconsole.exe d image_file.ezw

It will decompress it to ezw.bmp file and open it in your image browser program for viewing with ShellExecute() function.

The classes in the project are:

BaseFWT2D

mBior97 : public BaseFWT2D

vec1D

EZW

CodecY

mBior97 is just the SSE implementation of the Bior97 wavelet filter. I added zeros to tG and H filters to facilitate SSE optimized convolutions with vec1D and BaseFWT2D classes you might be familiar from my 2D Fast Wavelet Transform Library for Image Processing article. EZW is the class for embedded zero tree algorithm for a 3 level wavelet-transform. It provides two overloads for compression and decompression of the wavelet spectrum:

You can use it with char or unsignedcharwavelet spectrum. For the latter, the zero assumed pixel is equal to 128. The dest is the buffer where the EZW coded data will be placed and sour is the wavelet spectrum. w and h are the width and height of the image. They return 0 in case of error and non-zero result indicating the size of the compressed/decompressed spectrum.

The implementation of the codec is done in the CodecY class. It provides three functions:

You need to initialize it to specific image width and height before compression and decompression with initgray() function. For compression, call compressgray() providing with data your image. Upon success it will output compressed image size to variable size and return the pointer to the compressed data. TH is the threshold below which all pixels in the wavelet-spectrum will be zeroed.

After compression, the codec puts the CRC of the frame to its header, calculated in the IP checksum manner. The checksum error is res = -3, and the rest of the error codes are put to the codecy.h file.

Points of Interest

I've provided only gray image codec for a start. You can easily extend it to color image compression just arranging three mBior97 classes for Y, U and V channels and compress them separately as I do with just the Y channel. I hope I'll have time in future to extend it myself.

History

Update 1.0 - 21 Oct, 2007

Without plunging into writing CodecYUV class supporting compression of color images, I modified a little console application to enable it to compress RGB images with existing CodecY class. I just added RGB to YCbCr conversion and provided three CodecY objects for Y, Cb and Cr channels. Then I just save compressed frames to the file in that order.

You may compare the quality of EZW compression with Windows JPEG compressors or others. Additional lossless compression of the EZW file provides about 1.7 compression ratio, however you cannot do the same with JPEG files.

Just a quick note when in YCbCr, you could quarter sample the Cb and Cr channels (by averaging their values on a 2x2 pixel cell basis) then put them through FWT and EZ encoding and you "should" end-up with an encoding scheme that should result in a PSNR that is roughly equivalent to full sampling of all three channels but would consume far less storage and by virtue of being smaller in dimension would lead to faster FWT and I-FWT.

The key here is Y, as the psycho-visual model is more sensitive to changes in intensity (luma Y) than it is to chroma (Cb Cr).