AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Canny edge algorithmus und Sobel Matrix

Ein Thema von Gutelo · begonnen am 26. Jul 2014 · letzter Beitrag vom 1. Aug 2014
Antwort Antwort
Gutelo

Registriert seit: 29. Sep 2013
152 Beiträge
 
#1

AW: Canny edge algorithmus und Sobel Matrix

  Alt 29. Jul 2014, 12:09
Mit 8 und 6/9 sollte es kein Problrm geben. 6 und 9 haben etwa gleiche Aenderungen. Hier muss man dann einen festen Startpunkt wählen, z.B. immer beim nördlichsten Punkt anfangen.

Ich muss erst noch die NMS, Hysteresis und Hough fertig machen dann kümmer ich mich um die OCR idee. Halte dich auf dem Laufenden
  Mit Zitat antworten Zitat
Gutelo

Registriert seit: 29. Sep 2013
152 Beiträge
 
#2

AW: Canny edge algorithmus und Sobel Matrix

  Alt 30. Jul 2014, 02:02
Hallo,

Non-Maximum Suppression (NMS) und Hysteresis arbeiten jetzt auch. Ich haenge ein kleines Demo-Projekt fuer Lazarus an dieses Post. Laeuft alles schnell genug, kann aber auch noch reichlich optimiert werden. Soll nur als ein Grundgeruest dienen fuer Leute die Aehnliches vor haben. Ich habe den Code reichlich kommentiert. Das Binary ist leider elendig gross geworden (28mb). Lazarus scheint noch mehr aufzublaehen als Delphi. Ferner nicht wundern wenn nach dem Verlassen des kompilierten Programms der Debugger meckert. Ein leidiges Lazarus Problem bei Verwendung von OpenDialog. Am besten einmal kompilieren und dann das Program ausserhalb der IDE aufrufen.

WICHTIG: >>> geht NUR mit *.bmp bitmaps, keine jpg, keine gif, ... <<<

Naechste Schritte:

1) Ich muss alle kurzen Kanten entfernen und nur die Langen ueberleben lassen, d.h. Kannten reduzieren.
2) Ich brauche Hough um Geraden und Ecken zu identifizieren.

Gutelo
Angehängte Grafiken
Dateityp: jpg Screenshot.jpg (196,2 KB, 56x aufgerufen)
Angehängte Dateien
Dateityp: zip Canny_Delphi_Praxis.zip (133,1 KB, 48x aufgerufen)

Geändert von Gutelo (30. Jul 2014 um 02:18 Uhr)
  Mit Zitat antworten Zitat
Gutelo

Registriert seit: 29. Sep 2013
152 Beiträge
 
#3

AW: Canny edge algorithmus und Sobel Matrix

  Alt 30. Jul 2014, 20:52
Mist gerade bei Hough gemerkt, dass etwas nicht 100% stimmt.

Erstmal muss in Canny.pas der Typ PixArray mit dem Array bei 0 beginnen und nicht bei 1. Bis zum Sobel ist alles okay.

Die NMS Berechnung und/oder Berechnung der Kantenrichtungen sind fehlerhaft. Bei exakt horizontalen Kanten verschwinden die Kanten fast komplett aus dem Bild bei der NMS Berechnung. Woran kann das liegen? An definition von Atan2 ?

Gleiches Problem bei exakt vertikalen Kanten.

Gutelo

Geändert von Gutelo (30. Jul 2014 um 21:08 Uhr)
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.679 Beiträge
 
Delphi 2007 Enterprise
 
#4

AW: Canny edge algorithmus und Sobel Matrix

  Alt 30. Jul 2014, 22:35
Ohne den Code zu deiner NMS (inkl. der Richtungsbestimmungen, falls die ausgelagert sein sollte) zu sehen schwer zu sagen. Ich hatte da eigentlich kein Problem. Du beachtest aber, dass du senkrecht zu den tatsächlichen Gradientenrichtungen vorgehen musst? Das würde mir so ad hoc als schnell gemachter Fehler einfallen.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Gutelo

Registriert seit: 29. Sep 2013
152 Beiträge
 
#5

AW: Canny edge algorithmus und Sobel Matrix

  Alt 30. Jul 2014, 22:47
Hallo Medium,

der Code ist in dem Zip-file des vorletzten Posts

Gutelo
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.679 Beiträge
 
Delphi 2007 Enterprise
 
#6

AW: Canny edge algorithmus und Sobel Matrix

  Alt 30. Jul 2014, 23:12
Oh, dachte da wäre die NMS noch nicht bei gewesen. Scusi! Werde ich heute und vermutlich auch morgen aber nicht mehr zu kommen leider
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Gutelo

Registriert seit: 29. Sep 2013
152 Beiträge
 
#7

AW: Canny edge algorithmus und Sobel Matrix

  Alt 30. Jul 2014, 23:20
Kein Problem, ich poste es hier auch noch mal:


Delphi-Quellcode:

// ############################################################################
// Build pixel array of gradient directions
// ############################################################################

Procedure MakeEdgeDirections(PA_Sx, PA_Sy : TPixelArray; var PA_Out : TPixelArray);
//
var rows, cols : Integer;
    Th : Double; // Angle Theta
//
begin
   // Set dimensions of output pixel array
   SetLength(PA_Out, Length(PA_Sx));
   For rows := 0 to High(PA_Out) do SetLength(PA_Out[rows], Length(PA_Sx[0]));
   // calculate output pixel array:
   For rows := 0 to High(PA_Sx) do
   For cols := 0 to High(PA_Sx[0]) do
   begin
      Th := (180/Pi) * ArcTan2(PA_Sy[rows,cols],PA_Sx[rows,cols]);
      // write output pixel array
      PA_Out[rows,cols] := Round(Th);
   end;
end;

Function FMod(x,y : Double) : Double;
begin
   If y = 0 then
   begin
     Showmessage('Error in function FMod: Cannot divide through 0');
     FMod := 0;
   end
   else
   begin
     FMod := x-Int(x/y)*y;
   end;
end;

// ############################################################################
// Perform Non-maximum Suppression (quantisized way)
// ############################################################################

// Symmetry => 180 degree cover the four main directions: 0,45,90,and 135 deg
// Corresponding equivalent directions: 180,225,270,and 315 deg

// Divide the 180 degree region into four quadrant sections
// (0) to (Pi/8) and (Pi-(Pi/8)) to (Pi) <= quadrant around 0 (or symmetry equivalent
// 180 deg,respectively)
// (1*Pi/4) +- Pi/8 <= quadrant around 45 deg
// (2*Pi/4) +- Pi/8 <= quadrant around 90 deg
// (3*Pi/4) +- Pi/8 <= quadrant around 135 deg

// Introduce 'dir' value: dir := (FMod(PA_ED[rows,cols]+180, 180) /180) * 8
// Used to classify the member quadrant for a particular gradient direction
//
// How 'dir' works:
// Example: Input angle at point (x,y) : PA_ED[x,y] = -135
// Shift to get positive angle: PA_ED[x,y] + 180 = 45
// Value on 'dir' scale: (FMod(45,180)/180)*8= (45/180)*8 = 2
//
// Integer 'dir' values correspond to the following angles:
// dir = 0 <=> Th = 0 = 0 { center of 1st quadrant
// dir = 1 <=> Th = Pi/8 = 1*Pi/8 <= border from 1st to 2nd quadrant
// dir = 2 <=> Th = Pi/4 = 2*Pi/8 { center of 2nd quadrant
// dir = 3 <=> Th = Pi/4 + Pi/8 = 3*Pi/8 <= border from 2nd to 3rd quadrant
// dir = 4 <=> Th = Pi/2 = 4*Pi/8 { center of 3rd quadrant
// dir = 5 <=> Th = Pi/2 + Pi/8 = 5*Pi/8 <= border from 3rd to 4th quadrant
// dir = 6 <=> Th = 3*Pi/4 = 6*Pi/8 { center of 4th quadrant
// dir = 7 <=> Th = 3*Pi/4 + Pi/8 = 7*Pi/8 <= border from 4th to 1st quadrant
// dir = 8 <=> Th = Pi = 8*Pi/8 { center of 1st quadrant

Procedure MakeNMS(PA_SO, PA_ED : TPixelArray; var PA_Out : TPixelArray);
//
var dir : Double;
    rows, cols : Integer;
//
begin
   // Set dimensions of output pixel array
   SetLength(PA_Out, Length(PA_SO));
   For rows := 0 to High(PA_Out) do SetLength(PA_Out[rows], Length(PA_SO[0]));
   // Calculate output pixel array:
   For rows := 1 to High(PA_SO)-1 do
   For cols := 1 to High(PA_SO[0])-1 do
   begin
      // Calculate 'dir' value to determine the right quadrant
      dir := (FMod(PA_ED[rows,cols]+180, 180) /180) * 8;
      //
      // Check membership in quadrant, keep maxima,or suppress minima
      //
      // 0 degree quadrant (EE <-> WW)
      If ((dir <= 1) or (dir > 7))
          and (PA_SO[rows,cols] > PA_SO[rows,cols+1]) // EE
          and (PA_SO[rows,cols] > PA_SO[rows,cols-1]) // WW
      then PA_Out[rows,cols] := PA_SO[rows,cols]
      //
      else
      // 45 degree quadrant (NW <-> SE)
      If ((dir > 1) or (dir <= 3))
          and (PA_SO[rows,cols] > PA_SO[rows-1,cols-1]) // NW
          and (PA_SO[rows,cols] > PA_SO[rows+1,cols+1]) // SE
      then PA_Out[rows,cols] := PA_SO[rows,cols]
      //
      else
      // 90 degree quadrant (NN <-> SS)
      If ((dir > 3) or (dir <= 5))
          and (PA_SO[rows,cols] > PA_SO[rows-1,cols]) // NN
          and (PA_SO[rows,cols] > PA_SO[rows+1,cols]) // SS
      then PA_Out[rows,cols] := PA_SO[rows,cols]
      //
      else
      // 135 degree quadrant (NE <-> SW)
      If ((dir > 5) or (dir <= 7))
          and (PA_SO[rows,cols] > PA_SO[rows-1,cols+1]) // NE
          and (PA_SO[rows,cols] > PA_SO[rows+1,cols-1]) // SW
      then PA_Out[rows,cols] := PA_SO[rows,cols]
      //
      else
      // If no maximum -> Suppress Value
          PA_Out[rows,cols] := 0;
   end;
end;
Also ein Copy+Paste Fehler ist schonmal, dass es

If ((dir > 1) and (dir <= 3))
If ((dir > 3) and (dir <= 5))
((dir > 5) and (dir <= 7))

heissen muss. Da es alles verschlimmert stimmt wohl auch irgendwas mit den Richtungen nicht.

Geändert von Gutelo (30. Jul 2014 um 23:34 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:46 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