1 / 40

Programming Assignment 4

Programming Assignment 4. CS 302 - Data Structures Dr. George Bebis. Project Objectives. Use a priority queue in image compression. Implement and manipulate binary trees Learn about Huffman Coding Learn about bit and byte input/output. Image Compression.

mheater
Download Presentation

Programming Assignment 4

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Programming Assignment 4 CS 302 - Data Structures Dr. George Bebis

  2. Project Objectives • Use a priority queue in image compression. • Implement and manipulate binary trees • Learn about Huffman Coding • Learn about bit and byte input/output

  3. Image Compression • In today's world, many images are transmitted across the internet. • To send them efficiently and to store them efficiently requires that we compress them before we send them and then uncompress them when they are received. • JPEG, GIF, and TIFF are some popular image file formats using compression.

  4. Image Coding • Image coding is a special case of image compression. • Find an “optimum” code for representing the pixels values.

  5. Binary Coding • Each pixel value is represented using 8 bits (fixed-length codes). Binary Encoding Gray-level

  6. Huffman Coding • Huffman coding compresses an image by encoding the pixel values so that not all pixel values require the same number of bits of storage (variable-length codes). Gray-level Huffman Encoding

  7. Huffman Coding (cont’d) • IDEA: assign fewer bits to pixel values that appear more frequently in the image and more bits to pixel values that appear less frequently in the image. Gray-level Huffman Encoding

  8. Huffman Coding - Example • Consider a 6x6 image where every pixel is encoded using 8 bits; storing this image would require 36x8= 288 bits. • Assuming 3 bits per pixel, it would require 36x3=108 bits. • Using Huffman coding, it would require 93 bits.

  9. Table of Bit Encodings • To compress an image, you need a table of bit encodings, (e.g., a table giving a sequence of bits that's used to encode each pixel value). • This table is constructed from a coding tree. Table of Bit Encodings Image

  10. Coding Tree • Pixel values are stored at the leaves of the tree. • A left-edge is labeled 0 (or 1) and a right-edge is labeled 1 (or 0). 0 1 36 22 6 4 2 5 7 3 1 0 14 4 8 3 6 1 0 0 1 12 10 1 0 1 0 2 1 4 2 2 3 0 1 0 1

  11. Generation of Table of Bit Encodings • The Huffman code for any pixel value can be obtained by following the root-to-leaf path (i.e., leaf corresponding to the pixel value) and concatenating the 0's and 1's in the path. 0 1 36 22 6 4 2 5 7 3 1 0 14 4 8 3 6 1 0 0 1 12 10 1 0 1 0 2 1 4 2 2 3 0 1 0 1

  12. Encoding • To encode an image, we replace each pixel value by its corresponding bit encoding. • For example, the first row of the image shown is encoded as follows: 10011010000001110 Table of Bit Encodings Image

  13. Encoding (cont’d) i li f(i)=frequency Image Total # of bits:

  14. Decoding Start at the root of the encoding tree, and follow a left-branch for a 0, a right branch for a 1. 0 1 0 1 7 22 2 5 6 36 3 4 14 8 6 4 3 1 0 0 1 12 10 1 0 1 0 2 1 4 2 2 3 (first row) 10011010000001110 …. 0 1 0 1 1 3

  15. Generation of Coding Tree • Let's assume that each pixel value has an associated weight equal to the number of times the pixel value occurs in an image (i.e., frequency). frequency f(0) =1 f(1) =4 f(2)=2 f(3)=3 f(4)=2 f(5)=12 f(6)=10 f(7)=2

  16. Generation of Coding Tree Step 1. Begin with a forest of trees. All trees are one node, with the weight of the tree equal to the weight of the pixel value in the node. Pixel values that occur most frequently have the highest weights while pixel values that occur least frequently have the smallest weights. 0 1 2 3 4 5 6 7 1 4 2 3 2 12 10 2

  17. Generation of Coding Tree Min Priority Queue Step 2. Repeat this step until there is only one tree: Choose two trees with the smallest weights, call these trees T1 and T2. Create a new tree whose root has a weight equal to the sum of the weights T1 + T2 and whose left subtree is T1 and whose right subtree is T2. 0 1 2 3 4 5 6 7 1 4 2 3 2 12 10 2 T2 T1

  18. Generation of Coding Tree Result of merging T1 with T2 1 2 3 4 5 6 7 3 4 2 3 2 12 10 0 1 2

  19. Generation of Coding Tree Step 3. The single tree left after the previous step is an optimal encoding tree.

  20. Generation of Coding Tree - Example Note: trees are shown in sorted order for convenience; in practice, trees reside in a priority queue. 5 6 1 3 2 4 7 0 12 10 4 3 2 2 2 1

  21. Generation of Coding Tree - Example 0 5 6 1 2 4 7 3 7 5 6 1 3 2 4 0 3 3 2 2 12 10 4 3 Re-order: 2 1 12 10 4 3 2 2 2 1

  22. Generation of Coding Tree - Example 1 7 6 5 3 5 2 0 6 1 3 7 0 2 4 4 4 3 3 4 3 12 10 4 12 10 4 3 Re-order: 2 1 2 1 2 2 2 2

  23. Generation of Coding Tree - Example 5 6 1 3 7 0 2 4 3 4 6 12 10 4 2 1 2 2 3

  24. Generation of Coding Tree - Example Re-order: 5 7 3 0 2 1 6 4 4 3 6 4 12 10 2 1 2 2 3

  25. Generation of Coding Tree - Example 3 0 4 7 1 6 5 2 6 3 8 4 12 10 2 1 4 2 2 3

  26. Generation of Coding Tree - Example Re-order: 1 2 4 5 7 3 6 0 4 6 3 8 12 10 2 1 4 2 2 3

  27. Generation of Coding Tree - Example 5 6 4 3 7 0 2 1 14 6 3 4 8 12 10 2 1 4 2 2 3

  28. Generation of Coding Tree - Example Re-order: 1 5 4 2 7 3 6 0 14 8 4 6 3 12 10 2 1 4 2 2 3

  29. Generation of Coding Tree - Example 5 6 3 22 7 1 2 4 0 14 3 6 4 8 12 10 2 1 4 2 2 3

  30. Generation of Coding Tree - Example Re-order: 0 4 2 22 1 5 6 7 3 14 6 8 3 4 12 10 2 1 4 2 2 3

  31. Generation of Coding Tree - Example Final coding tree 1 4 2 36 0 5 6 22 7 3 14 6 8 3 4 12 10 2 1 4 2 2 3

  32. Generation of Coding Tree - Example Final coding tree with paths labeled 0 1 7 36 22 3 5 4 6 0 1 2 14 3 6 4 8 1 0 0 1 12 10 1 0 1 0 2 1 4 2 2 3 0 1 0 1

  33. Implementation • Add an extra option in driver.cpp, for compressing/uncompressing an image. • The following steps should be executed upon choosing this option:

  34. Implementation (cont’d) 1. Read the specified image and count the frequency of all pixels in the image. 2. Create the coding tree using a Min Priority Queue based on the pixel frequencies. 3. Create the table of bit encodings for each pixel from the coding tree. 4. Encode the image and output the encoded/compressed image. 5. Read the encoded/compressed file you just created, decode it and output the decoded image.

  35. Program Output • Your program must provide the following required output: (i) the pixel frequencies (i.e., visualize as a gray-scale image) (ii) the table of pixel values and their bit encoding (sorted from smallest to largest) and (iii) original image size and compressed image size. (vi) compressed image and uncompressed image.

  36. Comments • The Huffman coding tree is based on a binary tree. You may design and implement your own "Huffman Tree" class from scratch, but the Binary Tree class discussed in the lectures might make a good starting point. • Note that two passes of the original image are required. The first pass counts the frequency of each pixel while second pass performs the actual encoding.

  37. Comments (cont’d) • Storing coding tree • Use pre-order traversal. • Differentiate leaf nodes from non-leaf nodes (e.g., write a single bit for each node, say 1 for leaf and 0 for non-leaf.). • For leaf nodes, you will also need to write the pixel value stored. • For non-leaf nodes there's no information that needs to be written, just the bit that indicates there's a non-leaf node.

  38. Comments (cont’d) • Storing bit stream • Cannot store one bit at a time! • Store it in “chunks” of 8 bits (1 byte) at a time. • “Push” eight bits at a time into an unsigned char using bitwise operators. • Use “write” (e.g., see WriteImage.cpp) Example: 10011010000001110 10011010 00000111 0

  39. Comments (cont’d) • Reading bit stream • Read it in “chunks” of 8 bits (1 byte) at a time into an unsigned character using “read” (see readImage.cpp). • “Extract” bits using bitwise operators.

  40. Comments (cont’d) Alternatively, you can use C++ classes to read and write bit streams; here is an example: http://www.codeproject.com/Articles/332219/C-Classes-to-Read-and-Write-Bit-Stream

More Related