#include #include #include #include "dct_transform.h" #include "getopt.h" #include "LoadPPM.h" const long SCALE = 64; long sqr(long v) { return v*v; } // sqr int round(double v) { if((v - (double)((int)v)) >= 0.5) return (int)v+1; else return (int)v; } // round void DisplayImage(SDL_Surface *screen, int* p_gray_image, long img_width, long img_height, long scale) { SDL_LockSurface(screen); for(int y = 0; y < img_height; y++) { for(int x = 0; x < img_width; x++) { long gray = p_gray_image[x + y*img_width]; if(gray > 255) gray = 255; if(gray < -255) gray = -255; for(int dy = 0; dy < scale; dy++) { for(int dx = 0; dx < scale; dx++) { if(gray >= 0) { ((unsigned char*)screen->pixels)[(x*scale+dx)*3 + (y*scale+dy)*screen->pitch + 0] = gray; ((unsigned char*)screen->pixels)[(x*scale+dx)*3 + (y*scale+dy)*screen->pitch + 1] = gray; ((unsigned char*)screen->pixels)[(x*scale+dx)*3 + (y*scale+dy)*screen->pitch + 2] = gray; } // if else { ((unsigned char*)screen->pixels)[(x*scale+dx)*3 + (y*scale+dy)*screen->pitch + 0] = gray; ((unsigned char*)screen->pixels)[(x*scale+dx)*3 + (y*scale+dy)*screen->pitch + 1] = 0; ((unsigned char*)screen->pixels)[(x*scale+dx)*3 + (y*scale+dy)*screen->pitch + 2] = 0; } // else } // for } // for } // for } // for } // DisplayImage void ClearImage(int* p_gray_image, long img_width, long img_height) { for(int i = 0; i < img_width*img_height; i++) p_gray_image[i] = 0; } // ClearImage void PrintImage(int* p_gray_image, long img_width, long img_height) { cout << endl; for(int y = 0; y < img_height; y++) { for(int x = 0; x < img_width; x++) { cout << setw(5) << p_gray_image[x + y*img_width] << " " << flush; } // for cout << endl << endl; } // for } // ClearImage void PrintCoeffs(double* p_coeffs, long img_width, long img_height) { cout << endl; for(int y = 0; y < img_height; y++) { for(int x = 0; x < img_width; x++) { cout << setw(5) << p_coeffs[x + y*img_width] << " " << flush; } // for cout << endl << endl; } // for } // ClearImage // this function transforms img_width*img_height pixels from the image p_gray_image // into the same number of coefficients and stores them in p_coeff void ForwardDCT(int* p_gray_image, double *p_coeff, long img_width, long img_height) { double C_v, C_u, coefficient; for(int v = 0; v < img_width; v++) { cout << endl; C_v = 1.0; if(v == 0) C_v = 1.0/sqrt(2.0); for(int u = 0; u < img_height; u++) { C_u = 1.0; if(u == 0) C_u = 1.0/sqrt(2.0); coefficient = 0.0; for(int y = 0; y < img_height; y++) { for(int x = 0; x < img_width; x++) { coefficient += (double)p_gray_image[x + y*img_width] * cos((double)((2*x+1)*u)*M_PI/16.0) * cos(((double)(2*y+1)*v)*M_PI/16.0); } // for } // for p_coeff[u + v*img_width] = (C_v*C_u/4.0)*coefficient; // quantisize coefficients // p_coeff[u + v*img_width] /= 100; // p_coeff[u + v*img_width] *= 100; cout << setw(10) << p_coeff[u + v*img_width] << " "; } // for } // for cout << endl; } // ForwardDCT // this function transforms img_width*img_height coefficients from p_coeff // into the same number of pixels and stores them in p_gray_image void InverseDCT(double *p_coeff, int *p_gray_image, long img_width, long img_height) { double C_v, C_u, gray_value; for(int y = 0; y < img_height; y++) { cout << endl; for(int x = 0; x < img_width; x++) { gray_value = 0.0; for(int v = 0; v < img_width; v++) { C_v = 1.0; if(v == 0) C_v = 1.0/sqrt(2.0); double inner_gray = 0.0; for(int u = 0; u < img_height; u++) { C_u = 1.0; if(u == 0) C_u = 1.0/sqrt(2.0); inner_gray += (C_u/2.0)*(double)p_coeff[u + v*img_width]*cos((double)((2*x+1)*u)*M_PI/16.0)*cos((double)((2*y+1)*v)*M_PI/16.0); } // for gray_value += (C_v/2.0)*inner_gray; } // for cout << setw(5) << round(gray_value) << " " << flush; // cout << setw(5) << gray_value << " " << flush; p_gray_image[x + y*img_width] = (int)gray_value; } // for } // for cout << endl; } // InverseDCT void QuantisizeCoefficients(double* p_coeff, long img_width, long img_height) { const unsigned char static_quant[] = { 16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, 26, 58, 60, 55, 14, 13, 16, 24, 40, 57, 69, 56, 14, 17, 22, 29, 51, 87, 80, 62, 18, 22, 37, 56, 68, 109, 103, 77, 24, 35, 55, 64, 81, 104, 113, 92, 49, 64, 78, 87, 103, 121, 120, 101, 72, 92, 95, 98, 112, 100, 103, 99}; for(int i = 0; i < img_height*img_width; i++) { p_coeff[i] = (int)p_coeff[i] / static_quant[i]; p_coeff[i] *= static_quant[i]; } // for } // QuantisizeCoefficients int main(int argc, char** argv) { SDL_MouseMotionEvent current_cursor, cursor_cache; SDL_Surface *screen, *backup_screen; SDL_Event event; SDL_Rect dst_rect, full_image_rect, scrolled_rect, location; int window_width, window_height, phase; long size_line, img_width, img_height; char c; unsigned char *p_rgb_image; int *p_gray_image; bool fullscreen, dual_processor, left_button_pressed, redraw; double *p_coeff, factor, offset; long mat_location_x, mat_location_y; /* bool repaint, former_event, automatic_segmentation, first_interactive_move; long size_line; unsigned char* p_image = NULL, *p_color_image = NULL; long image_width, image_height; short x, y, last_x, last_y, reference_x, reference_y; Watershed* p_watershed; SPFTree* p_spf_tree; LoadPPM ppm_image(p_color_image, argv[1], image_width, image_height); OutlineContainer* p_outline_container = NULL, *p_temp_outline = NULL, *p_temp2_outline = NULL; double wire_error_threshold = 100.0; short segmentation_click_x[MAX_SEGMENTATION_CLICKS], segmentation_click_y[MAX_SEGMENTATION_CLICKS], segmentation_click_index; ofstream* p_cost_matrix; */ bool predefined_image = true; p_rgb_image = NULL; if(predefined_image) { img_width = img_height = 8; const unsigned char static_image[] = {185, 190, 195, 203, 190, 190, 186, 190, 137, 166, 178, 195, 190, 195, 190, 184, 104, 104, 104, 162, 182, 190, 190, 184, 131, 104, 104, 117, 159, 171, 182, 178, 141, 145, 150, 138, 146, 159, 169, 178, 150, 177, 152, 162, 152, 159, 169, 178, 126, 165, 157, 155, 159, 159, 164, 169, 78, 111, 163, 150, 152, 156, 162, 169}; p_gray_image = new int [img_width*img_height]; // allocated gray scale image p_coeff = new double [img_width*img_height]; // we need the same number of coefficients for(int i = 0; i < img_width*img_height; i++) p_gray_image[i] = static_image[i]; } // if else { LoadPPM test_image(p_rgb_image, argv[1], img_width, img_height); p_gray_image = new int [img_width*img_height]; // allocated gray scale image p_coeff = new double [img_width*img_height]; // we need the same number of coefficients // transform rgb to grayscale image for(int y = 0; y < img_height; y++) { for(int x = 0; x < img_width; x++) { p_gray_image[x + y*img_width] = ((long)p_rgb_image[(x + y*img_width)*3+0] + (long)p_rgb_image[(x + y*img_width)*3+0] + (long)p_rgb_image[(x + y*img_width)*3+0])/3; } // for } // for } // else if(p_rgb_image) delete[] p_rgb_image; p_rgb_image = NULL; window_width = 600; window_height = 550; fullscreen = false; if(SDL_Init(SDL_INIT_VIDEO) < 0) { cerr << "Could not initialize SDL video" << endl; exit(-1); } // if atexit(SDL_Quit); Uint32 flags = SDL_HWSURFACE; if(fullscreen) flags |= SDL_FULLSCREEN; screen = SDL_SetVideoMode(window_width, window_height, 24, flags); if(!screen) { cerr << argv[0] << "could not SetVideoMode() - abort" << endl; exit(-1); } // if DisplayImage(screen, p_gray_image, img_width, img_height, SCALE); PrintImage(p_gray_image, img_width, img_height); for(;;) { if((SDL_WaitEvent(&event) != 0)) { switch(event.type) { case SDL_MOUSEMOTION: break; case SDL_MOUSEBUTTONDOWN: // if(event.button.button == SDL_BUTTON_LEFT) left_button_pressed = true; break; case SDL_MOUSEBUTTONUP: break; case SDL_KEYDOWN: switch(event.key.keysym.sym) { case 27: case 'q': case 'Q': goto exit_app; case 'c': ClearImage(p_gray_image, img_width, img_height); DisplayImage(screen, p_gray_image, img_width, img_height, SCALE); break; case 'f': ForwardDCT(p_gray_image, p_coeff, img_width, img_height); break; case 'i': InverseDCT(p_coeff, p_gray_image, img_width, img_height); DisplayImage(screen, p_gray_image, img_width, img_height, SCALE); break; case 'u': QuantisizeCoefficients(p_coeff, img_width, img_height); PrintCoeffs(p_coeff, img_width, img_height); break; case 'm': cout << "Matrix X: " << flush; cin >> mat_location_x; cout << "Matrix Y: " << flush; cin >> mat_location_y; cout << "Faktor: " << flush; cin >> factor; cout << "Offset: " << flush; cin >> offset; p_coeff[mat_location_x + mat_location_y*img_height] *= factor; p_coeff[mat_location_x + mat_location_y*img_height] += offset; break; default: cout << "key: " << (int)event.key.keysym.sym << endl; break; } // switch } // switch } // if /* if(repaint) { redraw = true; repaint = false; } // if */ // if(redraw) { SDL_UnlockSurface(screen); SDL_UpdateRect(screen, 0, 0, window_width, window_height); // redraw = false; // } // if timespec waiting_time; waiting_time.tv_sec = 0; waiting_time.tv_nsec = 1000; nanosleep(&waiting_time, NULL); } // for exit_app: if(p_coeff) delete[] p_coeff; if(p_gray_image) delete[] p_gray_image; SDL_UnlockSurface(screen); SDL_FreeSurface(screen); } // main