Salut,
je dois transformé une image à l'aide de la DFT (par ligne grosseur 256*256)
voici mon Algorithme mais elle ne functionne pas bien
svp pouvez vous m'aider?
#include <math.h>
#include "FrameGrabber.h"
#include "definitionen.h"
#include "dft_1.h"
#ifndef PI
#define PI 3.1415926536
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
double raw[MAX_SPALTE];
double sinus[MAX_SPALTE];
double cosinus[MAX_SPALTE];
double dft[MAX_SPALTE];
double idft[MAX_SPALTE];
int graph_dft[MAX_SPALTE];
int graph_idft[MAX_SPALTE];
//extern bool bLineDft = FALSE;
//extern bool bLineDftF = FALSE;
extern FrameGrabber *fg;
extern HINSTANCE myinstance;
BYTE DftLine[768];
char *szDftName = "DFT";
bool bDftClass = FALSE;
const int offset = 48;
HWND dfthwnd; // Fensterhandle
WNDCLASS dftwc; // Fensterklassenstruktur
LRESULT CALLBACK DftProc(HWND, UINT, WPARAM, LPARAM);
void LineDft(int y) {
char *szFensterTitle = "Zeilenweise DFT";
int i;
/* Initialisieren des Zielarrays */
//for(i = 0; i < 768; i++)
for(i = 0; i < 768; i++)
DftLine[i] = 0;
/* Einlesen der Zeile */
fg->LeseZeile(y, DftLine);
/* Fensterklasse anlegen */
if(bDftClass == FALSE) {
dftwc.style = CS_BYTEALIGNWINDOW|CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS;
dftwc.lpfnWndProc = DftProc;
dftwc.cbClsExtra = 0;
dftwc.cbWndExtra = 0;
dftwc.hInstance = myinstance;
dftwc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
dftwc.hCursor = LoadCursor(NULL, IDC_ARROW);
dftwc.hbrBackground= (HBRUSH) GetStockObject(WHITE_BRUSH);
dftwc.lpszMenuName = NULL;
dftwc.lpszClassName= szDftName;
if (!RegisterClass(&dftwc))
{
MessageBox(NULL,
TEXT("Programm arbeitet mit Unicode und setzt Windows NT voraus !"), szDftName, MB_ICONERROR);
return ;
}
else
bDftClass = TRUE;
}
// ein Fenster erzeugen
dfthwnd = CreateWindow(
szDftName, // Klassenname
TEXT("Zeilenweise DFT"),
WS_SYSMENU|WS_CAPTION|WS_OVERLAPPED|WS_BORDER|WS_MINIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT,
800+offset, 300+offset,
NULL, // kein parent Window
NULL,
myinstance, // Instanz zu der das Fenster gehoert
NULL);
// Fenstererzeugung erfolgreich?
if (dfthwnd == NULL)
{
MessageBox(NULL, TEXT("Fenster konnte nicht geoeffnet werden!"),
szDftName, MB_ICONERROR);
return;
}
ShowWindow(dfthwnd, SW_SHOW);
UpdateWindow(dfthwnd);
}
LRESULT CALLBACK DftProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
RECT ClientRect;
POINT pt;
static TEXTMETRIC tm;
char psText[16];
int i, x;
HDC hdc;
PAINTSTRUCT ps;
HPEN PenDft, PenIdft;
switch (message)
{
// wird beim Erzeugen des Fensters verschickt
case WM_CREATE:
hdc = GetDC(hwnd);
GetTextMetrics(hdc, &tm);
ReleaseDC(hwnd, hdc);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
/* Abmessung der Clientarea holen */
GetClientRect(hwnd, &ClientRect);
/* Koordinatensystem einzeichnen */
MoveToEx(hdc, offset, ClientRect.bottom - offset, NULL);
LineTo(hdc, offset, 0);
MoveToEx(hdc, offset, ClientRect.bottom - offset, NULL);
LineTo(hdc, ClientRect.right, ClientRect.bottom - offset);
/* Pfeil zeichnen Y-Achse*/
MoveToEx(hdc, offset, 0, NULL);
LineTo(hdc, offset - 6, 8);
MoveToEx(hdc, offset, 0, NULL);
LineTo(hdc, offset + 6, 8);
/* Pfeil zeichnen X-Achse*/
MoveToEx(hdc, ClientRect.right, ClientRect.bottom - offset, NULL);
LineTo(hdc, ClientRect.right - 6, ClientRect.bottom - offset - 6);
MoveToEx(hdc, ClientRect.right, ClientRect.bottom - offset, NULL);
LineTo(hdc, ClientRect.right - 6, ClientRect.bottom - offset + 6);
/* Skala Y-Achse einzeichnen */
MoveToEx(hdc, offset, ClientRect.bottom - offset - 255, NULL);
LineTo(hdc, offset - 6, ClientRect.bottom - offset - 255);
MoveToEx(hdc, offset, ClientRect.bottom - offset - 128, NULL);
LineTo(hdc, offset - 6, ClientRect.bottom - offset - 128);
strcpy(psText,"g(x)");
TextOut(hdc, offset - (strlen("g(x) ") * tm.tmAveCharWidth), ClientRect.bottom - offset - 276, psText, strlen(psText));
strcpy(psText,"255");
TextOut(hdc, offset - (strlen("255 ") * tm.tmAveCharWidth), ClientRect.bottom - offset - 255, psText, strlen(psText));
strcpy(psText,"128");
TextOut(hdc, offset - (strlen("128 ") * tm.tmAveCharWidth), ClientRect.bottom - offset - 128, psText, strlen(psText));
/* Skala X-Achse einzeichnen */
MoveToEx(hdc, offset + 128, ClientRect.bottom - offset, NULL);
LineTo(hdc, offset + 128, ClientRect.bottom - offset + 6);
MoveToEx(hdc, offset + 256, ClientRect.bottom - offset, NULL);
LineTo(hdc, offset + 256, ClientRect.bottom - offset + 6);
MoveToEx(hdc, offset + 384, ClientRect.bottom - offset, NULL);
LineTo(hdc, offset + 384, ClientRect.bottom - offset + 6);
MoveToEx(hdc, offset + 512, ClientRect.bottom - offset, NULL);
LineTo(hdc, offset + 512, ClientRect.bottom - offset + 6);
MoveToEx(hdc, offset + 640, ClientRect.bottom - offset, NULL);
LineTo(hdc, offset + 640, ClientRect.bottom - offset + 6);
MoveToEx(hdc, offset + 768, ClientRect.bottom - offset, NULL);
LineTo(hdc, offset + 768, ClientRect.bottom - offset + 6);
strcpy(psText,"x");
TextOut(hdc, ClientRect.right - tm.tmAveCharWidth, ClientRect.bottom - offset + tm.tmHeight - 16, psText, strlen(psText));
strcpy(psText,"128");
TextOut(hdc, ClientRect.left - (int)(tm.tmAveCharWidth * 1.5) + 128 + offset, ClientRect.bottom - offset + tm.tmHeight - 16, psText, strlen(psText));
strcpy(psText,"256");
TextOut(hdc, ClientRect.left - (int)(tm.tmAveCharWidth * 1.5) + 256 + offset, ClientRect.bottom - offset + tm.tmHeight - 16, psText, strlen(psText));
strcpy(psText,"384");
TextOut(hdc, ClientRect.left - (int)(tm.tmAveCharWidth * 1.5) + 384 + offset, ClientRect.bottom - offset + tm.tmHeight - 16, psText, strlen(psText));
strcpy(psText,"512");
TextOut(hdc, ClientRect.left - (int)(tm.tmAveCharWidth * 1.5) + 512 + offset, ClientRect.bottom - offset + tm.tmHeight - 16, psText, strlen(psText));
strcpy(psText,"640");
TextOut(hdc, ClientRect.left - (int)(tm.tmAveCharWidth * 1.5) + 640 + offset, ClientRect.bottom - offset + tm.tmHeight - 16, psText, strlen(psText));
strcpy(psText,"768");
TextOut(hdc, ClientRect.left - (int)(tm.tmAveCharWidth * 1.5) + 768 + offset, ClientRect.bottom - offset + tm.tmHeight - 16, psText, strlen(psText));
/* Grauwertdiagramm einzeichnen */
MoveToEx(hdc, offset, ClientRect.bottom - offset, NULL);
GetCurrentPositionEx(hdc, &pt);
x = pt.x;
for(i = 0; i < MAX_SPALTE; i++) {
x++;
LineTo(hdc, x, ClientRect.bottom - offset - DftLine[i]);
}
/* DFT einzeichnen */
for(i = 0; i < MAX_SPALTE; i++) {
raw[i] = DftLine[i];
}
do_dft(false);
PenDft = CreatePen(PS_SOLID, 0, 0x00AA0000L);
SelectObject(hdc, PenDft);
MoveToEx(hdc, offset, ClientRect.bottom - offset, NULL);
GetCurrentPositionEx(hdc, &pt);
x = pt.x;
for(i = 0; i < MAX_SPALTE; i++) {
x++;
LineTo(hdc, x, ClientRect.bottom - offset - (int) dft[i]);
}
/* inv.DFT einzeichnen */
do_idft();
PenIdft = CreatePen(PS_SOLID, 0, 0x0000FF00L);
SelectObject(hdc, PenIdft);
MoveToEx(hdc, offset, ClientRect.bottom - offset, NULL);
GetCurrentPositionEx(hdc, &pt);
x = pt.x;
for(i = 0; i < MAX_SPALTE; i++) {
x++;
LineTo(hdc, x, ClientRect.bottom - offset - (int) idft[i]);
}
/* Ende aller Zeichenoperationen */
DeleteObject(PenDft);
DeleteObject(PenIdft);
EndPaint(hwnd, &ps);
return(0);
default: // Nachrichten weiterleiten
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
/******************************************************************/
/** Diskrete Fourier Transformation **/
/******************************************************************/
void do_dft(bool flag)
{
int i,j;
double sum, faktor;
for(i = 0; i < MAX_SPALTE; i++) {
if(flag == TRUE) {
/* flag = TRUE -> (-1.0^x)
flag = FALSE -> 1.0
*/
if( (i % 2) == 0)
faktor = 1.0;
else
faktor = -1.0;
}
else
faktor = 1.0;
/* Cosinus-Term berechnen - Realteil */
sum = 0.0;
for(j = 0; j < MAX_SPALTE; j++) {
sum += faktor * raw[j] * cos(2*PI*i*j/((double)(MAX_SPALTE)));
}
cosinus[i] = (1.0/MAX_SPALTE) * sum;
/* Sinus-Term berechnen - Imaginärteil */
sum = 0.0;
for(j = 0; j < MAX_SPALTE; j++) {
sum += faktor * raw[j] * sin(2*PI*i*j/((double)(MAX_SPALTE)));
}
sinus[i] = (1.0/MAX_SPALTE) * sum;
}
/* Betrag von cosinus[i] + i*sinus[i] berechnen */
for(i = 0; i < MAX_SPALTE; i++) {
dft[i] = sqrt( sinus[i] * sinus[i] + cosinus[i] * cosinus[i]);
}
scale(dft, graph_dft);
}
/******************************************************************/
/** Inverse diskrete Fourier Transformation **/
/******************************************************************/
void do_idft(void)
{
int i,j;
double sum;
for(i = 0; i < MAX_SPALTE; i++) {
/* Cosinus-Term berechnen - Realteil */
sum = 0.0;
for(j = 0; j < MAX_SPALTE; j++) {
sum += cosinus[j] * cos(2*PI*i*j/((double)(MAX_SPALTE)));
sum += sinus[j] * sin(2*PI*i*j/((double)(MAX_SPALTE)));
}
idft[i] = sum;
}
}
void scale(double *src, int *dest)
{
int i;
double max = 0.0;
double scalevalue = 0.0;
double temp[MAX_SPALTE];
for(i = 0; i < MAX_SPALTE; i++) {
temp[i] = log(1.0 + fabs(src[i]));
}
for(i = 0; i < MAX_SPALTE; i++) {
if(temp[i] > max)
max = temp[i];
}
scalevalue = 255.0 / max;
for(i = 0; i < MAX_SPALTE; i++) {
dest[i] = (int) (temp[i] * scalevalue);
}
}
Merci
Afficher la suite