By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
429,365 Members | 3,095 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 429,365 IT Pros & Developers. It's quick & easy.

having trouble with Discrete Cosine Transform program

P: n/a
anyone could point me out where did i do wrong? it seems that i can't
get back the original Lena image after the IDCT(inverse discrete cosine
transform) process. the output raw image is nothing more than a grey
colored canvas ...

//Header files declarations
#include <iostream.h>
#include <fstream.h>
#include <math.h>
#include <stdlib.h>

//Global declarations
const int pixel=256;
unsigned char impix[pixel][pixel];
double dctblock[pixel][pixel];
double idctblock[pixel][pixel];
static const double pi = 3.141593;

//Functions declarations
void copypixel();
void openfile();
void dct();
void idct();
void printdct();
void imageblock();
void printidct();
void printdctimage();
void printidctimage();
double c(int);
void main()
{
openfile();
imageblock();
dct();
printdct();
printdctimage();
idct();
printidct();
printidctimage();
}

void openfile()
{

ifstream rawimage("lena.raw", ios::in|ios::binary);
if(!rawimage)
{
cerr<<"Error in reading file\n";
exit(1);
}

for(int i=0; i<pixel; i++)
{
for(int j=0; j<pixel; j++)
{
rawimage>>impix[i][j];
}
}
}

void imageblock()
{

ofstream rawimagetxt("rawimage.txt", ios::out|ios::binary);
if(!rawimagetxt)
{
cerr<<"Error in reading file\n";
exit(1);
}

for(int i=0; i<pixel; i++)
{
for(int j=0; j<pixel; j++)
{
rawimagetxt<<int(impix[i][j])<<" ";
}
}
}

void dct()
{
for(int u=0;u<pixel;u++) {
for(int v=0;v<pixel;v++) {
double temp = 0.0;

for(int x=0;x<8;x++) {
for(int y=0;y<8;y++) {
temp += impix[x][y] * cos(pi *
(2 * x + 1) * u / 16) *
cos(pi * (2 * y + 1) * v / 16);
}
}

dctblock[u][v] = temp * (c(u) / 2) * (c(v) /
2);
}
}
}

void printdct()
{

ofstream dct("dct.txt", ios::out|ios::binary);
if(!dct)
{
cerr<<"Error in reading file\n";
exit(1);
}

for(int i=0; i<pixel; i++)
{
for(int j=0; j<pixel; j++)
{
dct<<dctblock[i][j]<<" ";
}
}
}

void printidct()
{

ofstream idct("idct.txt", ios::out|ios::binary);
if(!idct)
{
cerr<<"Error in reading file\n";
exit(1);
}

for(int i=0; i<pixel; i++)
{
for(int j=0; j<pixel; j++)
{
idct<<idctblock[i][j]<<" ";
}
}
}

void printdctimage()
{

ofstream dctimage("dct.raw", ios::out|ios::binary);
if(!dctimage)
{
cerr<<"Error in reading file\n";
exit(1);
}

for(int i=0; i<pixel; i++)
{
for(int j=0; j<pixel; j++)
{
dctimage<<dctblock[i][j];
}
}
}

void idct()
{
for(int x=0;x<pixel;x++) {
for(int y=0;y<pixel;y++) {
double temp = 0.0;

for(int u=0;u<8;u++) {
for(int v=0;v<8;v++) {
temp += (c(u) / 2) * (c(v) / 2)
* dctblock[u][v] * cos(pi * (2 *
x + 1) * u / 16) * cos(pi * (2 * y + 1) * v / 16);
}
}

idctblock[x][y] = temp;
}
}
}

void printidctimage()
{

ofstream idctimage("idct.raw", ios::out|ios::binary);
if(!idctimage)
{
cerr<<"Error in reading file\n";
exit(1);
}

for(int i=0; i<pixel; i++)
{
for(int j=0; j<pixel; j++)
{
idctimage<<idctblock[i][j];
}
}
}
double c(int number)
{
if(number == 0)
{
return 1/sqrt(2);
}
else
{
return 1;
}
}

Mar 24 '06 #1
Share this Question
Share on Google+
1 Reply


P: n/a
kh**************@gmail.com wrote:
anyone could point me out where did i do wrong? it seems that i can't
get back the original Lena image after the IDCT(inverse discrete cosine
transform) process. the output raw image is nothing more than a grey
colored canvas ...
The DCT is off-topic here. Try in comp.dsp or comp.compression or
similar. If you have C++ language questions, feel free to ask them
here. See below for some source code problems that I spotted on a
cursory reading.
//Header files declarations
#include <iostream.h>
#include <fstream.h>
Deprecated. Use <iostream> and <fstream>. You'll also need to add:

using namespace std;
#include <math.h>
#include <stdlib.h>
Prefer <cmath> and <cstdlib>.

//Global declarations
const int pixel=256;
unsigned char impix[pixel][pixel];
double dctblock[pixel][pixel];
double idctblock[pixel][pixel];
Prefer to declare things as locally as possible, and pass parameters
into functions that need them. Global variable make for unreadable and
hard-to-debug code.
static const double pi = 3.141593;
This is ok as a global, but static to indicate the object is restricted
to file scope is also deprecated. Use an anonymous namespace instead.

//Functions declarations
void copypixel();
void openfile();
void dct();
void idct();
void printdct();
void imageblock();
void printidct();
void printdctimage();
void printidctimage();
double c(int);
Since you only have one file, you could just put main() at the end and
avoid the need for these prototypes altogether.


void main()
int main()

See http://www.parashift.com/c++-faq-lit....html#faq-29.3
{
openfile();
imageblock();
dct();
printdct();
printdctimage();
idct();
printidct();
printidctimage();
}

void openfile()
{

ifstream rawimage("lena.raw", ios::in|ios::binary);
if(!rawimage)
{
cerr<<"Error in reading file\n";
exit(1);
}

for(int i=0; i<pixel; i++)
{
for(int j=0; j<pixel; j++)
{
rawimage>>impix[i][j];
Stream inserters and extractors (i.e. the >> and << operators) are
intended only for formatted text I/O, not binary I/O. You need to use
istream::read() and ostream::write().
}
}
}

void imageblock()
{

ofstream rawimagetxt("rawimage.txt", ios::out|ios::binary);
I suspect you didn't want the ios::binary here.
if(!rawimagetxt)
{
cerr<<"Error in reading file\n";
exit(1);
}

for(int i=0; i<pixel; i++)
{
for(int j=0; j<pixel; j++)
{
rawimagetxt<<int(impix[i][j])<<" ";
}
}
}

void dct()
{
for(int u=0;u<pixel;u++) {
for(int v=0;v<pixel;v++) {
double temp = 0.0;

for(int x=0;x<8;x++) {
for(int y=0;y<8;y++) {
temp += impix[x][y] * cos(pi *
(2 * x + 1) * u / 16) *
cos(pi * (2 * y + 1) * v / 16);
}
}

dctblock[u][v] = temp * (c(u) / 2) * (c(v) /
2);
}
}
}

void printdct()
{

ofstream dct("dct.txt", ios::out|ios::binary);
Not binary.
if(!dct)
{
cerr<<"Error in reading file\n";
exit(1);
}

for(int i=0; i<pixel; i++)
{
for(int j=0; j<pixel; j++)
{
dct<<dctblock[i][j]<<" ";
}
}
}

void printidct()
{

ofstream idct("idct.txt", ios::out|ios::binary);
Not binary.
if(!idct)
{
cerr<<"Error in reading file\n";
exit(1);
}

for(int i=0; i<pixel; i++)
{
for(int j=0; j<pixel; j++)
{
idct<<idctblock[i][j]<<" ";
}
}
}

void printdctimage()
Inaptly named function: you're not printing (which generally implies
text mode).
{

ofstream dctimage("dct.raw", ios::out|ios::binary);
if(!dctimage)
{
cerr<<"Error in reading file\n";
exit(1);
}

for(int i=0; i<pixel; i++)
{
for(int j=0; j<pixel; j++)
{
dctimage<<dctblock[i][j];
}
}
}

void idct()
{
for(int x=0;x<pixel;x++) {
for(int y=0;y<pixel;y++) {
double temp = 0.0;

for(int u=0;u<8;u++) {
for(int v=0;v<8;v++) {
temp += (c(u) / 2) * (c(v) / 2)
* dctblock[u][v] * cos(pi * (2 *
x + 1) * u / 16) * cos(pi * (2 * y + 1) * v / 16);
}
}

idctblock[x][y] = temp;
}
}
}

void printidctimage()
Inaptly named function: you're not printing (which generally implies
text mode).
{

ofstream idctimage("idct.raw", ios::out|ios::binary);
if(!idctimage)
{
cerr<<"Error in reading file\n";
exit(1);
}

for(int i=0; i<pixel; i++)
{
for(int j=0; j<pixel; j++)
{
idctimage<<idctblock[i][j];
Don't use the << operator. See comments above.
}
}
}
double c(int number)
{
if(number == 0)
{
return 1/sqrt(2);
}
else
{
return 1;
}
}


Cheers! --M

Mar 24 '06 #2

This discussion thread is closed

Replies have been disabled for this discussion.