Chaincode von Freeman



  • 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 👍


Anmelden zum Antworten