?
Hallo,
ich versuche z.Z. den Algorithmus von Freeman in C++ zu erstellen, aber ich scheitere mehr oder weniger schon an der Implementierung.
Ich erhalte einfach nicht das gewünschte Ergebnis, obwohl ich meiner Meinung nach, den Algorithmus korrekt nach der Pseudo-Code Vorlage erstellt habe.
Hier eine Erklärung und am Ende der erwähnte Pseudo-Code:
http://www.fbmn.fh-darmstadt.de/home/heckenkamp/bv1/vorlesung/konturcode/bv1_6.html
A: Anfangspunkt (sicherer Konturpunkt)
P: aktueller Konturpunkt
Pj: Nachbarpunkt von P in Freeman-Richtung j
fp: aktueller Freeman-Code, der zum nächsten Konturpunkt führt
i: Freeman-Code der Blickrichtung ("Bewegungsrichtung")
i-1, i, i+1: Freeman-Codes der Suchrichtungen
B(P): ist 1, falls der Punkt P zum Objekt gehört, sonst 0
Übergabeparameter: A; Zeiger auf Bildvektor mit Binärwerten B aller Bildpunkte
Rückgabeparameter: A; Zeiger auf Liste mit Richtungscodes
START: i = 6, P = A
DO (FOREVER)
REPEAT UP TO 4 TIMES
BEGIN
IF(
B(Pi-1) = = 1 ) THEN
P = Pi-1; fp = i - 1; i = i - 2
BREAK
ELSE IF( B(Pi) = = 1 ) THEN
P = Pi; fp = i
BREAK
ELSE IF( B(Pi+1) = = 1 ) THEN
P = Pi+1; fp = i + 1
BREAK
ELSE
i = i + 2
END IF
END
Abspeichern von P und fp
IF ( P = = A ) BREAK
END
Hat jemand eine Idee, warum es nicht klappt?
Vielleicht hat ja selber schonmal wer mit diesem Algorithmus gearbeitet?
Ich bin jedenfalls extremst ratlos
Hier der gesamte Quellcode meines aktuellen Versuchs. Es ist zum Kompilieren außer SFML (und ein Testbild) nichts weiter notwendig.
#include <iostream>
#include <cmath>
#include <windows.h>
#include <SFML/Graphics.hpp>
const sf::Color BG_COLOR = sf::Color(255, 255, 255); // Hintergrundfarbe weiß
unsigned int match(sf::Image& img, unsigned int& x, unsigned int& y, unsigned int dir);
int main()
{
sf::RenderWindow app(sf::VideoMode(800, 600, 32), "Chaincode - Test");
sf::Image input;
if (!input.LoadFromFile("konturen.bmp"))
{
return 1;
}
/*
Dir:
3 | 2 | 1
----|---|----
4 | ! | 0
----|---|----
5 | 6 | 7
*/
unsigned int dir = 6;
for (unsigned int j = 0; j < input.GetHeight(); ++j)
{
for (unsigned int i = 0; i < input.GetWidth(); ++i)
{
if (input.GetPixel(i, j) != BG_COLOR)
{
// Startpunkt gefunden
input.SetPixel(i, j, sf::Color(255, 0, 0));
const unsigned int startX = i;
const unsigned int startY = j;
while (true)
{
for (unsigned int k = 0; k < 4; ++k)
{
if (match(input, i, j, (dir % 8) - 1) != 0)
{
dir -= 2;
break;
}
else if (match(input, i, j, dir % 8) != 0)
{
break;
}
else if (match(input, i, j, (dir % 8) + 1) != 0)
{
break;
}
else
{
dir += 2;
}
}
input.SetPixel(i, j, sf::Color(255, 0, 255)); // Debug
/*
Speichern etc.
*/
if (startX + 1 == i && startY + 1 == j)
{
break;
}
}
}
}
}
app.Draw(sf::Sprite(input));
app.Display();
sf::Sleep(2);
}
unsigned int match(sf::Image& img, unsigned int& x, unsigned int& y, unsigned int dir)
{
switch (dir)
{
case 0:
if (img.GetPixel(x + 1, y) != BG_COLOR)
{
x++;
return 1;
}
case 1:
if (img.GetPixel(x + 1, y - 1) != BG_COLOR)
{
x++;
y--;
return 1;
}
case 2:
if (img.GetPixel(x, y - 1) != BG_COLOR)
{
y--;
return 1;
}
case 3:
if (img.GetPixel(x - 1, y - 1) != BG_COLOR)
{
x--;
y--;
return 1;
}
case 4:
if (img.GetPixel(x - 1, y) != BG_COLOR)
{
x--;
return 1;
}
case 5:
if (img.GetPixel(x - 1, y + 1) != BG_COLOR)
{
x--;
y++;
return 1;
}
case 6:
if (img.GetPixel(x, y + 1) != BG_COLOR)
{
y++;
return 1;
}
case 7:
if (img.GetPixel(x + 1, y + 1) != BG_COLOR)
{
x++;
y++;
return 1;
}
}
return 0;
}
Vielen Dank im Voraus,
Ratloser