SS4306 – Assignment 2

advertisement
Multimedia Lab – Source Coding Algorithms
The learning objective of this assignment is to apply source coding algorithms for
compression in multimedia applications. The assignment will allow you to understand the use
of compression in still images.
The Scenario:
Assuming that the wheel image shown in the above picture and as well as given as a GIF file,
you are required to perform the followings in order to apply source coding compression
algorithms of your choice.
Minimum Requirements:





Identify and assign colors for the wheel – 3 Marks
Use necessary C/CPP program segments given to upload the ASCII text files
of color codes assigned in the step above – 3 Marks
Write a C/CPP function to implement source code algorithm of your choice;
Runlength/Huffman/Arithmetic/LZW – 5 Marks
Prove the compression and decompression using the wheel – 4 Marks
Be creative and have fun with the assignment! – Priceless
HINT: Wherever applicable, use all source program segments given in order to do this
assignment unless otherwise you use your own programming language such as Java or
software package such as Matlab.
Handing in your Lab:
The lab is due Tuesday, 15th April 2014.
APPENDIX
HEADER FILE
#ifndef IMAGE_H
#define IMAGE_H
// a simple example - you would need to add more functions
class ImageType {
public:
ImageType();
ImageType(int, int, int);
ImageType(ImageType&);
~ImageType();
void getImageInfo(int&, int&, int&);
void setImageInfo(int, int, int);
void setPixelVal(int, int, int);
void getPixelVal(int, int, int&);
private:
int N, M, Q;
int **pixelValue;
};
#endif
SKELETON C/CPP FILES
1. Image.cpp
#include <stdlib.h>
#include "image.h"
ImageType::ImageType()
{
N = 0;
M = 0;
Q = 0;
pixelValue = NULL;
}
ImageType::ImageType(int tmpN, int tmpM, int tmpQ)
{
int i, j;
N = tmpN;
M = tmpM;
Q = tmpQ;
pixelValue = new int* [N];
for(i=0; i<N; i++) {
pixelValue[i] = new int[M];
for(j=0; j<M; j++)
pixelValue[i][j] = 0;
}
}
ImageType::ImageType(ImageType& oldImage)
{
int i, j;
N = oldImage.N;
M = oldImage.M;
Q = oldImage.Q;
pixelValue = new int* [N];
for(i=0; i<N; i++) {
pixelValue[i] = new int[M];
for(j=0; j<M; j++)
pixelValue[i][j] = oldImage.pixelValue[i][j];
}
}
ImageType::~ImageType()
{
int i;
for(i=0; i<N; i++)
delete [] pixelValue[i];
delete [] pixelValue;
}
void ImageType::getImageInfo(int& rows, int& cols, int& levels)
{
rows = N;
cols = M;
levels = Q;
}
void ImageType::setImageInfo(int rows, int cols, int levels)
{
N= rows;
M= cols;
Q= levels;
}
void ImageType::setPixelVal(int i, int j, int val)
{
pixelValue[i][j] = val;
}
void ImageType::getPixelVal(int i, int j, int& val)
{
val = pixelValue[i][j];
}
2. ReadImage.cpp
#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
#include "image.h"
int readImage(char fname[], ImageType& image)
{
int i, j;
int N, M, Q;
unsigned char *charImage;
char header [100], *ptr;
ifstream ifp;
ifp.open(fname, ios::in | ios::binary);
if (!ifp) {
cout << "Can't read image: " << fname << endl;
exit(1);
}
// read header
ifp.getline(header,100,'\n');
if ( (header[0]!=80) ||
/* 'P' */
(header[1]!=53) ) {
/* '5' */
cout << "Image " << fname << " is not PGM" << endl;
exit(1);
}
ifp.getline(header,100,'\n');
while(header[0]=='#')
ifp.getline(header,100,'\n');
M=strtol(header,&ptr,0);
N=atoi(ptr);
ifp.getline(header,100,'\n');
Q=strtol(header,&ptr,0);
charImage = (unsigned char *) new unsigned char [M*N];
ifp.read( reinterpret_cast<char *>(charImage), (M*N)*sizeof(unsigned
char));
if (ifp.fail()) {
cout << "Image " << fname << " has wrong size" << endl;
exit(1);
}
ifp.close();
//
// Convert the unsigned characters to integers
//
int val;
for(i=0; i<N; i++)
for(j=0; j<M; j++) {
val = (int)charImage[i*M+j];
image.setPixelVal(i, j, val);
}
delete [] charImage;
return (1);
}
3. Threshold.cpp
#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
#include "image.h"
int readImageHeader(char[], int&, int&, int&, bool&);
int readImage(char[], ImageType&);
int writeImage(char[], ImageType&);
int main(int argc, char *argv[])
{
int i, j;
int M, N, Q;
bool type;
int val;
int thresh;
// read image header
readImageHeader(argv[1], N, M, Q, type);
// allocate memory for the image array
ImageType image(N, M, Q);
// read image
readImage(argv[1], image);
cout << "Enter threshold: ";
cin >> thresh;
// threshold image
for(i=0; i<N; i++)
for(j=0; j<M; j++) {
image.getPixelVal(i, j, val);
if(val < thresh)
image.setPixelVal(i, j, 255);
else
image.setPixelVal(i, j, 0);
}
// write image
writeImage(argv[2], image);
return (1);
}
4. WriteImage.cpp
#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
#include "image.h"
int writeImage(char fname[], ImageType& image)
{
int i, j;
int N, M, Q;
unsigned char *charImage;
ofstream ofp;
image.getImageInfo(N, M, Q);
charImage = (unsigned char *) new unsigned char [M*N];
// convert the integer values to unsigned char
int val;
for(i=0; i<N; i++)
for(j=0; j<M; j++) {
image.getPixelVal(i, j, val);
charImage[i*M+j]=(unsigned char)val;
}
ofp.open(fname, ios::out | ios::binary);
if (!ofp) {
cout << "Can't open file: " << fname << endl;
exit(1);
}
ofp << "P5" << endl;
ofp << M << " " << N << endl;
ofp << Q << endl;
ofp.write( reinterpret_cast<char *>(charImage), (M*N)*sizeof(unsigned
char));
if (ofp.fail()) {
cout << "Can't write image " << fname << endl;
exit(0);
}
ofp.close();
delete [] charImage;
return(1);
}
Algorithm 1: Huffman Coding
Input: Array f [1...n] of numerical frequencies or probabilities.
Output: Binary coding tree with n leaves that has minimum expected code length
for f .
huffman(f [1...n])
T = empty binary tree
Q = priority queue of pairs (i, f [i]), i = 1...n, with f as comparison key
For each k = 1...n − 1
i = extractMin(Q)
j = extractMin(Q)
f [n + k] = f [i] + f [j]
insertNode(T, n + k) with children i, j
insertRear(Q, (n + k, f [n + k]))
return T
Download