Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   External: SIGEGV bei Rect() (https://www.delphipraxis.net/191082-external-sigegv-bei-rect.html)

F1r3man 6. Dez 2016 21:03

Delphi-Version: 5

External: SIGEGV bei Rect()
 
Hallöchen, ich habe ein kleines Problem:
ich kriege hier eine Exception: >>External: SIGSEGV<<
In Datei 'kennzeichenfinden.pas' in Zeile 178: DST:= Rect(0, 0, img.Width, img.Height);

ich werde nicht wirklich schlau aus dem fehler. währe nice, wenn ihr mir helfen könntet. :)
Vielen dank schon einmal im Vorraus.

Hier der betroffene Code-teil:
Delphi-Quellcode:
function TKennzeichenFinden.start (Pfad: String): TBitmap;
var
  img: TBitmap;
  kanten: TBitmap;
  blaueflaeche: TBitmap;
  width, height, i, j: Integer;
  DstRect, SrcRect: TRect;
  filterRad: integer;
begin
  filterRad:= 3;
  DstRect:= Rect.(0, 0, img.Width, img.Height);
  img.LoadFromFile(Pfad);
  kanten.Create;
  kanten.setSize(img.Width, img.Height);
  blaueflaeche.Create;
  blaueflaeche.setSize(img.Width, img.Height);
  kanten:= findeKanten(img, filterRad, 200, kanten);
  blaueflaeche:= findeBlau(img, filterRad, blaueflaeche);
  for i:=filterRad to img.Width-filterRad-1 do
  begin
    for j:=filterRad to img.Height-filterRad-1 do
    begin
      if(isObenLinks(kanten, i, j, 3) AND hatBlaueFlaeche(blaueflaeche, i, j, 3)) then
      begin
        SrcRect:= Rect(i, j, 300, 200);
        Result.Canvas.CopyMode:= cmSrcCopy;
        Result.Canvas.CopyRect(dstRect, img.Canvas, SrcRect);
        break;
      end;
    end;
  end;
end;

nahpets 6. Dez 2016 21:46

AW: External: SIGEGV bei Rect()
 
Wo wird img denn erstellt? Fehlt da nicht irgendwo ein
Delphi-Quellcode:
 img := TBitmap.Create;
Gilt auch für die anderen Bitmaps. Und am Ende das Freigeben nicht vergessen.

F1r3man 6. Dez 2016 21:57

AW: External: SIGEGV bei Rect()
 
ist mir eben auch aufgefallen, habs behoben, aber der Fehler bleibt gleich. ist auch aufgetreten, wenn ich das über eine Schleife mache, also ohne 'Rect'.

neuer Quelltext
Delphi-Quellcode:
begin
  filterRad:= 3;
  durchschnitt:= (filterRad*2)-1;
  DstRect:= Rect(0, 0, img.Width, img.Height);
  img.Create;
  img.LoadFromFile(Pfad);
  kanten.Create;
  kanten.setSize(img.Width, img.Height);
  blaueflaeche.Create;
  blaueflaeche.setSize(img.Width, img.Height);
  kanten:= findeKanten(img, filterRad, 200, kanten);
  blaueflaeche:= findeBlau(img, filterRad, blaueflaeche);
  for x:=filterRad to img.Width-filterRad-1 do
  begin
    for y:=filterRad to img.Height-filterRad-1 do
    begin
      if(isObenLinks(kanten, x, y, 3) AND hatBlaueFlaeche(blaueflaeche, x, y, 3)) then
      begin
        SrcRect:= Rect(x, y, 300, 200);
        Result.Canvas.CopyMode:= cmSrcCopy;
        Result.Canvas.CopyRect(dstRect, img.Canvas, SrcRect);
        break;
      end;
    end;
  end;
end;

nahpets 6. Dez 2016 22:11

AW: External: SIGEGV bei Rect()
 
Siehst Du den Unterschied zwischen meinem
Delphi-Quellcode:
img := TBitmap.Create;
und Deinem
Delphi-Quellcode:
img.Create;
? Und das Create muss natürlich vor dem ersten Zugriff auf img stehen.

F1r3man 6. Dez 2016 22:17

AW: External: SIGEGV bei Rect()
 
ups xD mein Fehler, aber das ist ja nicht einmal der Fehler den ich habe, der Fehler liegt laut Debugger bei dem DstRect:= Rect(0, 0, img.Width, img.Height).
auch nachdem ich das andere angepasst habe.

nahpets 6. Dez 2016 22:27

AW: External: SIGEGV bei Rect()
 
Wo steht denn jetzt das Create, immer noch hinter der vom Debugger bemängelten Zeile?

Ohne Gewähr für irgendwas:
Delphi-Quellcode:
begin
  img := TImage.Create;
  kanten := TImage.Create;
  blaueflaeche := TImage.Create;
  filterRad := 3;
  durchschnitt := (filterRad * 2) - 1;
  img.LoadFromFile(Pfad);
  DstRect := Rect(0, 0, img.Width, img.Height);
  kanten.setSize(img.Width, img.Height);
  blaueflaeche.setSize(img.Width, img.Height);
  kanten := findeKanten(img, filterRad, 200, kanten); // <- wie sieht denn diese Funktion aus, was hat sie für 'nen Rückgabewert?
  blaueflaeche := findeBlau(img, filterRad, blaueflaeche);
  for x := filterRad to img.Width - filterRad - 1 do
  begin
    for y := filterRad to img.Height - filterRad - 1 do
    begin
      if (isObenLinks(kanten, x, y, 3) AND hatBlaueFlaeche(blaueflaeche, x, y, 3)) then
      begin
        SrcRect := Rect(x, y, 300, 200);
        Result.Canvas.CopyMode := cmSrcCopy;
        Result.Canvas.CopyRect(dstRect, img.Canvas, SrcRect);
        break;
      end;
    end;
  end;
  FreeAndNil(img);
  FreeAndNil(kanten);
  FreeAndNil(blaueflaeche);
end;

F1r3man 6. Dez 2016 22:43

AW: External: SIGEGV bei Rect()
 
Klappt. ist jetzt nur noch ein Pfad Fehler. den kriege ich geklärt. und hier die Funktion. Ich schreibe grad als ein Schulprojekt eine Kennzeichenerkennung für eine Tankstelle :D wenn du lust hast dich da reinzulesen, hier die Funktion, die du wolltest. Ich habe das format auf TBitmap gesetzt, weil das das Format von img ist.... n bissle dumme bezeichnung ich weiß xD bin nur zu faul das zu ändern, aber wie gesagt funktioniert jetzt alles.
Ty.
Lg Simon


Delphi-Quellcode:
function TKennzeichenFinden.findeKanten(img: TBitmap; filterRad: integer; tolleranzschwelle: integer; saveOn: TBitmap): TBitmap;
var
  farbe: TColor;
  mittelwert: array of integer;
  x, y, i, j, g, buffx, buffy: integer;
  durchschnitt: integer;
  felder: array of array of integer;
begin
  durchschnitt:= (filterRad*2)-1;
  setLength(mittelwert, 4);
  setLength(felder, durchschnitt);
  for i:= 0 to Length(felder)-1 do
  begin
    setLength(felder[i], durchschnitt);
  end;
  //echte Korrdinaten
  for x:=filterRad to img.Width-filterRad-1 do
  begin
    for y:=filterRad to img.Height-filterRad-1 do
    begin
      //durchgehen des Filterbereiches
      for i:= 0 to durchschnitt-1 do
      begin
        for j:= 0 to durchschnitt-1 do
        begin
          //aktuelle Filterposition  (start oben links)
          buffx:= x-filterRad+i;
          buffy:= y-filterRad+j;
          farbe:= img.Canvas.Pixels[buffx, buffy];
          felder[buffx][buffy]:=round((Red(farbe)+Green(farbe)+Blue(farbe))/3);
        end;
      end;
      //berechnen des Durschschnitts Pro Sektor
      for i:= 0 to Length(felder)-1 do
      begin
        for j:= 0 to Length(felder[i])-1 do
        begin
          if(i<=filterRad) then
          begin
            //sektor 1
            if(j<=filterRad) then
            begin
              mittelwert[0]:= mittelwert[0]+felder[i][j];
            end;
            //sektor 2
            if(j>=filterRad) then
            begin
              mittelwert[1]:= mittelwert[1]+felder[i][j];
            end;
          end;
          if(i>=filterRad) then
          begin
            //sektor 3
            if(j<=filterRad) then
            begin
              mittelwert[2]:= mittelwert[2]+felder[i][j];
            end;
            //sektor 4
            if(j>=filterRad) then
            begin
              mittelwert[3]:= mittelwert[3]+felder[i][j];
            end;
          end;
        end;
      end;
      //durschschnitte final berechnen
      for g:= 0 to Length(mittelwert)-1 do
      begin
        mittelwert[g]:= Round(mittelwert[g]/(filterRad*filterRad));
      end;
      //Bitmaps setzen
      if (mittelwert[0]<tolleranzschwelle) AND (mittelwert[1]<tolleranzschwelle) AND (mittelwert[2]>=tolleranzschwelle) AND (mittelwert[3]>=tolleranzschwelle) then
      begin
        saveOn.Canvas.Pixels[x, y]:=TopBorder;
      end;
      if (mittelwert[0]<tolleranzschwelle) AND (mittelwert[1]>=tolleranzschwelle) AND (mittelwert[2]<tolleranzschwelle) AND (mittelwert[3]>=tolleranzschwelle) then
      begin
        saveOn.Canvas.Pixels[x, y]:=LeftBorder;
      end;
      if (mittelwert[0]>=tolleranzschwelle) AND (mittelwert[1]>=tolleranzschwelle) AND (mittelwert[2]<tolleranzschwelle) AND (mittelwert[3]<tolleranzschwelle) then
      begin
        saveOn.Canvas.Pixels[x, y]:=BottomBorder;
      end;
      if (mittelwert[0]>=tolleranzschwelle) AND (mittelwert[1]<tolleranzschwelle) AND (mittelwert[2]>=tolleranzschwelle) AND (mittelwert[3]<tolleranzschwelle) then
      begin
        saveOn.Canvas.Pixels[x, y]:=Rightborder;
      end
      else
      begin
        saveOn.Canvas.Pixels[x, y]:=RGBToColor(0, 0, 0);
      end;
    end;
  end;
  result:= saveOn;
end;
kann vielleicht noch verbessert werden, aber ist OK, das ist ja der Spaß an dem Projekt. xD

F1r3man 7. Dez 2016 00:00

AW: External: SIGEGV bei Rect()
 
btw, ist hiermit abgeschlossen.

himitsu 7. Dez 2016 01:38

AW: External: SIGEGV bei Rect()
 
Die markierte Zeile im Debugger liegt manchmal eine Zeile einen "Befehl" nach dem Fehler.

Im Prinzip werden bei einem CALL (Assembler) die Rücksprungadressen gespeichert und aus der bestimmt der Debugger die Fehlerstelle ... nur kann er das halt nicht immer auf den Befehl davor zurückrechnen.
Ein Delphibefehl besteht ja nahezu immer aus mehreren Assemblerbefehlen und somit liegt die Fehlerstelle praktisch zwischen zwei Befehlsanfangspunkten im Code, die sich der Compiler/Linker gemerkt hat.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:13 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz