Autor Beitrag
Heider
Hält's aus hier
Beiträge: 11

WinXP Prof. SP2
Delphi 7, Vis. C++ 6
BeitragVerfasst: So 20.08.06 16:56 
Sorry aber ich wußte nicht wie ich den Titel nennen sollte, aber das Problem ist ein bischen umfangreich und ich bräuchte mal paar Ideen um auf Fehlersuche zu gehen.
Nun zur eigentlichen Problembeschreibung. Ich hab ein Programm was ein Bild in ausliest und in eine Matrix schreibt. In dieser Matrix werden nun jeweils zwei untereinanderliegende Zeilen genommen, in den Fourierraum transformiert, eine davon Complex conjugiert, dann miteinander multipliziert und wieder zurücktransformiert. Das ganze hat den Sinn das man die Kreuzkorrelation der beiden Zeilen erhält, also bei welcher Verschiebung der beiden Zeilen sie sich am meisten ähneln.
Hier erstmal der Quellcode
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
function TfrmMain.DelVibrac(): Boolean;

var
  I,J, AddLength, Height, Width, NewLength,NewPos : Integer;
  line1vecG : array of TJmComplexRect;  //Vektor der Grauwerte des Bildes
  line2vecG : array of TJmComplexRect;
  line : TRGBArray;
  sl: TStringList; //Stringlisten nur für externe Ausgabe zur Überprüfung der Berechnung
  sl1: TStringList;
  sl2: TStringList;
begin
  sl:=TStringList.Create;
  sl1:=TStringList.Create;
  sl2:=TStringList.Create;
  try
    Width := Length(imagematrix[0]);
    Height := High(imagematrix);
    NewLength := Width + (Width mod 2); //geradzahlig machen
    AddLength := Width div 2;
    AddLength := AddLength - (AddLength mod 2);
    NewLength := NewLength + AddLength;
    SetLength(line1vecG,NewLength); //Beide Zeilenvektoren auf neue Länge bringen
    SetLength(line2vecG,NewLength);
    Setlength(line,Width);
    progrbar.Max := Height -1;
    progrbar.Visible := True;
    for J:=0 to (Height - 1do begin
        for I:=0 to Width - 1 do begin
          line1vecG[AddLength + I].Re := (imagematrix[J][I].R*0.299 + imagematrix[J][I].G*0.587 + imagematrix[J][I].B*0.114); //Grauwerte zwecks Rechenaufwand
          line1vecG[AddLength + I].Im := 0.0;
          line2vecG[I].Re := (imagematrix[J+1][I].R*0.299 + imagematrix[J+1][I].G*0.587 + imagematrix[J+1][I].B*0.114);
          line2vecG[I].Im := 0.0;

          line[I] := imagematrix[J+1][I];
          lblstat.Caption := 'Zeile: ' + IntToStr(J);
        end;
        {*for I:= 0 to High(line1vecG) do begin
          sl1.Add(FloatToStr(line1vecG[I].Re)+ 'r');
          sl2.Add(FloatToStr(line2vecG[I].Re)+ 'r');
        end;*}

        NewPos := GetMovePos(line1vecG,line2vecG);
        sl.Add(IntToStr(NewPos));
        NewPos := NewPos - AddLength;
        sl.Add('reel: ' + IntToStr(NewPos));
        MoveLine(line,NewPos,J+1);
        lblstat.Caption := 'Zeile: ' + IntToStr(J+1);
        progrbar.Position := J;
        Application.ProcessMessages;
    end;
    progrbar.Visible := False;
    DrawImageMatrix();
    stretch(400,400,TResamplingFilter(1),0,imgWork.Picture.Bitmap,imgPreview.Picture.Bitmap);
    DelVibrac:=True;
    sl.SaveToFile('c:\test\test.txt');
    sl.Free;
    sl1.SaveToFile('c:\test\vector1.txt');
    sl1.Free;
    sl2.SaveToFile('c:\test\vector2.txt');
    sl2.Free;
  except
    DelVibrac:=False;
    sl.Free;
  end;
end;

function TfrmMain.GetMovePos(var vec1,vec2 : array of TJmComplexRect): Integer;

var
  Len,I : Integer;
  multivec1 : array of TJmComplexRect;
  multivec2 : array of TJmComplexRect;
  resvec : array of TJmComplexRect;
  resvec1 : array of TJmComplexRect;
  resvec2 : TDoubleArray;
begin
  vectormiddle(vec1);
  vectormiddle(vec2);
  Len := Length(vec1);
  SetLength(multivec1,Len);
  SetLength(multivec2,Len);
  SetLength(resvec,Len);
  SetLength(resvec1,Len);
  SetLength(resvec2,Len);
  ForwardFFT(vec1,multivec1,Len);
  ForwardFFT(vec2,multivec2,Len);
  for I:= Low(multivec2) to High(multivec2) do begin
    multivec2[I] := CConjugateRect(multivec2[I]);
    resvec[I] := CMultRect(multivec1[I],multivec2[I]);
  end;
  InverseFFT(resvec,resvec1,Len); // Bis hier her die Berechnung der Kreuzkorrelation
  for I:= Low(resvec1) to High(resvec1) do resvec2[I] := (resvec1[I].Re);
  result := FindMaxIndex(resvec2); // Position der gößten Ahnlichkeit
end;

function TfrmMain.FindMaxIndex(const vector : TDoubleArray): Integer;
var
  I,Index : Integer;
  maxval : double;
begin
  Index := Low(vector);
  maxval := 0.0;
  for I := Low(vector) to High(vector) do begin
    If maxval < vector[I] then begin
      maxval := vector[I];
      Index := I;
      end;
    end;
  result:= Index;
end;

procedure TfrmMain.MoveLine(linevec : TRGBArray;X,linenr : Integer);
var
  I : Integer;
begin
  if X > 0 then begin
     for I := Low(imagematrix[linenr]) to High(imagematrix[linenr]) do begin
     if I > (X-1then imagematrix[linenr][I] := linevec[I-X]
      else begin
        imagematrix[linenr][I].R := 0;
        imagematrix[linenr][I].G := 0;
        imagematrix[linenr][I].B := 0;
       end;
      end;
    end
  else if X<0 then begin
     for I := Low(imagematrix[linenr]) to High(imagematrix[linenr]) do begin
      if I<(High(linevec)+X+1then imagematrix[linenr][I] := linevec[I-X]
      else begin
        imagematrix[linenr][I].R := 0;
        imagematrix[linenr][I].G := 0;
        imagematrix[linenr][I].B := 0;
      end;
     end;
  end;
end;


Wie ihr euch denken könnt, ist "imagematrix" eine globale matrix die ich vorher eingelesen hab.
Das Problem ist nun das die Berechnete Verschiebung innerhalb meines Programms von der abweicht die ich extern über "Mathematica" ausgerechnet habe. Obwohl ich mit denselben Werten rechne(deswegen die Ausgabe). Ich hab den Verdacht das sich imagematrix, während des Schleifendurchlaufs nicht "updated", oder das ich irgendwo nen Indexfehler hab den ich nicht seh.

Ich bitte um etwas Brainstorming um weiterzukommen

Vielen Dank im Vorraus
Mario

_________________
"Zwei Dinge sind undendlich, das Universum und die Menschliche Dummheit, obwohl ich mir beim Universum nicht sicher bin." Albert Einstein
Heider Threadstarter
Hält's aus hier
Beiträge: 11

WinXP Prof. SP2
Delphi 7, Vis. C++ 6
BeitragVerfasst: So 20.08.06 17:06 
Eine Idee die mir gerade selber gekommen ist, wäre die Verschiebungen die für jede Zeile notwendig ist in einen Vektor zu schreiben und erst am Ende der Schleifen die Verschiebungen kumultativ auf die Matrix anzuwenden. So umgehe ich das Problem das die Matrix wähend des Schleifendurchlaufs verändert wird und so das Ergebnis eventuell beeinflußt wird.

_________________
"Zwei Dinge sind undendlich, das Universum und die Menschliche Dummheit, obwohl ich mir beim Universum nicht sicher bin." Albert Einstein
Heider Threadstarter
Hält's aus hier
Beiträge: 11

WinXP Prof. SP2
Delphi 7, Vis. C++ 6
BeitragVerfasst: So 20.08.06 19:33 
hab jetzt mal die Verschiebungen in nen Vektor geschrieben und hinterher auf die Matrix angewandt
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
function TfrmMain.DelVibrac(): Boolean;

var
  I,J, AddLength, Height, Width, NewLength,NewPos : Integer;
  line1vecG : array of TJmComplexRect;  //Vektor der Grauwerte des Bildes
  line2vecG : array of TJmComplexRect;
  line : TRGBArray;
  movevec : array of Integer;
  sl: TStringList;
  sl1: TStringList;
  sl2: TStringList;
begin
  sl:=TStringList.Create;
  sl1:=TStringList.Create;
  sl2:=TStringList.Create;
  try
    Width := Length(imagematrix[0]);
    Height := High(imagematrix);
    NewLength := Width + (Width mod 2); //geradzahlig machen
    AddLength := Width div 2;
    AddLength := AddLength - (AddLength mod 2);
    NewLength := NewLength + AddLength;
    SetLength(line1vecG,NewLength); //Beide Zeilenvektoren auf neue Länge bringen
    SetLength(line2vecG,NewLength);
    SetLength(movevec,Height);
    Setlength(line,Width);
    progrbar.Max := Height -1;
    progrbar.Visible := True;
    for J:=0 to (Height - 1do begin
        for I:=0 to Width - 1 do begin
          line1vecG[AddLength + I].Re := (imagematrix[J][I].R*0.299 + imagematrix[J][I].G*0.587 + imagematrix[J][I].B*0.114); //Grauwerte zwecks Rechenaufwand
          line1vecG[AddLength + I].Im := 0.0;
          line2vecG[I].Re := (imagematrix[J+1][I].R*0.299 + imagematrix[J+1][I].G*0.587 + imagematrix[J+1][I].B*0.114);
          line2vecG[I].Im := 0.0;

          //line[I] := imagematrix[J+1][I];
          //lblstat.Caption := 'Zeile: ' + IntToStr(J);
        end;
        {*for I:= 0 to High(line1vecG) do begin
          sl1.Add(FloatToStr(line1vecG[I].Re)+ 'r');
          sl2.Add(FloatToStr(line2vecG[I].Re)+ 'r');
        end;*}

        NewPos := GetMovePos(line1vecG,line2vecG);
        //sl.Add(IntToStr(NewPos));
        NewPos := NewPos - AddLength;
        If(J>0then begin
          movevec[J] := NewPos; //+ movevec[J-1];
        end
        else movevec[J] := NewPos;
        sl.Add(IntToStr(NewPos));
        sl.Add('reel: ' + IntToStr(movevec[J]));
        //MoveLine(line,NewPos,J+1);
        //lblstat.Caption := 'Zeile: ' + IntToStr(J+1);
        progrbar.Position := J;
        Application.ProcessMessages;
    end;
    for J:=Low(movevec) to High(movevec) do begin
       for I:=0 to Width - 1 do begin
          line[I] := imagematrix[J+1][I];
       end;
       lblstat.Caption := 'Zeile: ' + IntToStr(J+1);
       MoveLine(line,movevec[J],J+1);
       progrbar.Position := J;
       Application.ProcessMessages;
    end;
    progrbar.Visible := False;
    DrawImageMatrix();
    stretch(400,400,TResamplingFilter(1),0,imgWork.Picture.Bitmap,imgPreview.Picture.Bitmap);
    DelVibrac:=True;
    sl.SaveToFile('c:\test\test.txt');
    sl.Free;
    sl1.SaveToFile('c:\test\vector1.txt');
    sl1.Free;
    sl2.SaveToFile('c:\test\vector2.txt');
    sl2.Free;
  except
    DelVibrac:=False;
    sl.Free;
    sl1.Free;
    sl2.Free;
  end;
end;


leider wird das Ergebnis nicht besser sondern eher noch unsinniger, deshalb die Frage. Hat jemand Erfahrungen mit "Jedimath", denn das verwende ich für die Fouriertransformation. oder hat jemand ne bessere Idee für Kreuzkorrelation. Oder irgendwelche Ideen wie ich etwas an dem Algorithmus verbessern oder anders machen kann. Mir gehen die Ideen aus, bitte um Hilfe

_________________
"Zwei Dinge sind undendlich, das Universum und die Menschliche Dummheit, obwohl ich mir beim Universum nicht sicher bin." Albert Einstein