Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

31

28.06.2003, 19:25

Farben sind für die Bilderkennung ja bei dir ja net wichtig. Es reicht wenn du für ein Pixel ne eins hast und wenn an der Pos XY kein Pixel gesetzt ist, ist da eben ne NULL. Eine 4x4 Map könnte dann so ausehen
Orig gemalt
0110 0110
1001 0101
1001 1001
0110 0111
Das währe jetzt ein Kreis. Wenn jetzt die Mouse gedrückt wird setzt du in ein Feld immer eine EINS an den Koordinaten XY, Skallierst es in die Größe der zu vergleichenden Map und fängst dann einfach an zu Testen Byte für Byte. Dann haste eine Variable iFalse. Diese wird immer dann um eins erhöht wenn ein Byte falsch ist. Dann stellst Du folgende Rechnung an: float percent = (iFalse / (picWidth * picHeight)) * 100.0f;
Wenn percent > 30.0f dann nächstes Pic
Sonst Symbol gefunden.
Im Beispiel sind 2 Pixel falsch. Das sind dann 12,5f Prozent Falsch. Symbol gefunden.

Das ist natürlich jetzt eine sehr einfache Lösung und die 30 Prozentgrenze ist jetzt auch einfach mal so geraten. Aber auf diesem Ansatz kann man mal aufbauen. Schau einfach mal was dabei rauskommt.
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

Anonymous

unregistriert

32

28.06.2003, 21:07

EinJemand

@david

also in b&w ist das wirklich geil gemacht! du hast da verschiedene formen (teils ziemlich komplex) und wenn man diese "zeichnet" werden bestimmte zauber ausgeführt![/code]

42

Frischling

  • »42« ist der Autor dieses Themas
  • Private Nachricht senden

33

29.06.2003, 11:03

@DragonMaster: Geniale Idee! Vielen DAnk, ich habe jetzt in den letzten Tagen versucht das allgemeine Wissen vonWinApi nachzuholen und habe es meiner Meinung auch geschafft (Also GANZ einfache Sachen, allein die Logik dahinter eben.). Nur ist es mir bis jetzt immernoch ein Rätsel wie ich es schaffe diesesn Pixel zu setzten (SetPixel(Fenster_Handle, x,y,000000)) ich kriege zwar ein True bei wparam=MK_LBUTTON abe rich glaube das bei mir das Macro GET_Y_LPARAM nicht klapt...

Könntest du mir auch ein kleines Code Schnipselchen zeigen bei deinem Vergleich? Ich versteh das von der Idee aber wo speichere ich 0 oder 1 rein? (Um sie dann zu vergleichen) Die Idee ist wirklich ziemlich gut, jedenfalls ist das eine "einfache" Lösung und erweiterungsfreundlich.
Jedem sei ein Neuanfang gestatt...

34

29.06.2003, 15:14

Zitat

Nur ist es mir bis jetzt immernoch ein Rätsel wie ich es schaffe diesesn Pixel zu setzten (SetPixel(Fenster_Handle, x,y,000000)) ich kriege zwar ein True bei wparam=MK_LBUTTON abe rich glaube das bei mir das Macro GET_Y_LPARAM nicht klapt...
Die Funktion SetPixel ist ja nur für das Optische sehen. Sonst malt man ja im Dunkeln ;)

Das Original Symbol kann man ja schnell in Paint malen. Deine Zeichenfläche hat ja eine größe von z.B. 200x200 Pixeln. Du legst dann einfach ein Array an

Quellcode

1
2
unsigned char* pbyData = new unsigned char[200*200];
memset(pbyData, 0, 200*200); // Alles mit NULL füllen
So dein Array ist nun fertig. In dieses Array schreibst du deine 1 an den Positionen XY. Die Formel für den Zugriff ist x + (y * Zeilenbreite). Die Zeilenbreite ist die Breite des Image. Da wir hier mit unsigned char Arbeiten ist nichts weiter zu beachten. Ein Beispiel

Quellcode

1
2
3
int x = 5;
int y = 180;
pbyData[x + (y * 200)] = 1;
Dein Zeichenbereich ist ja 200 Pixel breit.

Zu den Mouse Koordinaten:
x steht im Low Bereicht (die unteren 16Bit)
y steht im Height Bereicht (die oberen 16Bit)

Quellcode

1
2
#define GET_X(dword)  ((DWORD)(dword & 0x0000FFFF))
#define GET_Y(dword)  ((DWORD)((dword & 0xFFFF0000) >> 16))
So in etwa müsten auch die WinAPI Makros aufgebaut sein. Hab ich jetzt net nachgeschaut.

Bis dahin war ja noch alles einfach. Jetzt geht es daran das Gemalten Symbol in pbyData zu finden und mit den Originalen Symbolen zu vergleichen. Ich würde das vieleicht so angehen

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#define MAX(a, b) (a) >= (b) ? (a) : (b)
#define MIN(a, b) (a) <= (b) ? (a) : (b)
// Finden des Symbols
int top = 200; // Max höhe des Zeichenbereichs
int left = 200; // Max breite des Zeichenbereichs
int bottom = 0;
int right = 0;
for(int y = 0; y < 200; ++y)
{
  for(int x = 0; x < 200; ++x)
  {
     if(pbyData[x + (y * 200)] == 1)
     {
        left = MIN(x, left);
        top = MIN(y, top);
        right = MAX(x, right);
        bottom = MAX(y, bottom);
     }
  }
}
Nun haben wir das Viereck in dem sich das gemalte Symbol befindet (Oben Links bis Unten Rechts). Wenn das gemalte Symbol nicht die selbe Größe hat wie das Original müssen wir das gemalte Symbol Stretchen. Dafür würd ich das gemalte Symbol wohl in eine DIB Sektion (DIBS1) kopieren, eine zweite DIB Sektion (DIBS2) mit der größe des Original Symbols erstellen und dann DIBS1 in DIBS2 Blitten. Die Blittfunktion übernimmt dann für uns die Arbeit des Dehnens ;) Die Funktionen heißen CreateDIBSection und StretchBlt. Es gibt für das Stretchen vieleicht auch noch eine andere Methode. Muste mal schaun.

Der Vergleich mit dem gedehnten gemalten Symbol und dem Original Symbol ist dann wieder nicht sehr schwer.

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Anahme das die beiden Symbole 20x20 Pixel groß sind
unsigned char pbyOrig; // Datenbereich des Original Symbols
unsigned char pbyTemp; // Datenbereich des gemalten Symbols
int iFalse = 0;
for(int y = 0; y < 20; ++y)
{
  for(int x = 0; x < 20; ++x)
  {
     if(pbyOrig[x + (y * 20)] != pbyTemp[x + (y * 20)])
       ++iFalse;
  }
}
float fPerc = (iFalse / (float)(20 * 20)) * 100.0f;
if(fPerc > 30.0f)
  // Nächstes Symbol
else
{
  // Symbol found
  // Ausgabe Name des Symbols
}
[/quote]
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

42

Frischling

  • »42« ist der Autor dieses Themas
  • Private Nachricht senden

35

29.06.2003, 16:32

GEILO!!! Kann ich dir irgendwie danken???
Jedem sei ein Neuanfang gestatt...

36

29.06.2003, 16:34

Zeig mir das Proc wenn es fertig ist ;)
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

37

29.06.2003, 16:39

@Stephan:
Das hört sich schön an, aber ich bezweifle, dass es so klappen wird. Wenn die Form nur ein wenig ungenau ist, werden fast keine Pixel mehr übereinstimmen. Man müsste das Ganze mehrfach "glätten".

Original:

Quellcode

1
2
3
4
5
6
7
XXXXXXXXXXXX
X..........X
X..........X
X..........X
X..........X
X..........X
XXXXXXXXXXXX


Gemalt:

Quellcode

1
2
3
4
5
6
7
8
XXXXXXXXXXXXX.
.X..........X.
.X..........X.
.X..........X.
.X..........X.
.X..........X.
.XXXXXXXXXXXXX
.X............


Wenn man jetzt die Größe des unteren Musters berechnet, so ist die ja größer als die des Originals. Und auch wenn man es wieder zurückrechnet, stimmt kaum noch was überein.

38

29.06.2003, 17:21

Stimmt schon. Wie gesagt ist ne sehr einfache Lösung. Eine mögliche Lösung währe es wenn man noch zu jedem Original Symbol jeweils ein etwas kleineres und ein etwas größeres Symbol beipackt. Dann hätte man einen Rahmen in dem sich die vermeindlich Richtigen Pixel bewegen können. Somit währen ein paar ungenauigkeiten, sofern sie sich im Rahmen halten, als Richtige Pixel anerkannt.

Edit:
Oder das Original bekommt einen dicken Pinselstrich. Dann stellt sich der Rahmen automatisch ein. Das gemalte Pixel muss sich dann auf dem Bereich des dickeren Pinsel Pixels befinden.
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

39

29.06.2003, 18:17

Zitat von »"DragonMaster"«

Oder das Original bekommt einen dicken Pinselstrich. Dann stellt sich der Rahmen automatisch ein. Das gemalte Pixel muss sich dann auf dem Bereich des dickeren Pinsel Pixels befinden.

Ja, das ist eine gute Idee! :)
So müsste es klappen. Je dicker die Linie, desto ungenauer darf der User zeichnen.
Jedoch muss man dann eine kleine Anpassung vornehmen und darf nicht einfach vergleichen, ob zwei Pixel gleich sind. Denn der User malt ja nur "dünn", und selbst bei einem perfekten Rechteck/Kreis wäre die Übereinstimmung dann noch sehr gering, weil er ja eben nicht alle Pixel abdeckt.
Man müsste es dann so machen: Wenn der User einen Pixel malt, wo im Original keiner ist, dann gibt es einen "Minuspunkt". Aber nicht umgekehrt!

Anonymous

unregistriert

40

29.06.2003, 19:08

:) Zeige das Proc gerne wird auch später ein Modul in einem Rollenspiel... SPÄTER... sehr viel SPÄTER.

Naja Auf jedenfall danke ich euch. Noch ne Frage wie kriege ich das (jetzt mit einem dicken Pinselstrich) gemalte Bild zum Vergleich... das mit dem Malen ist klar (da kommen die Werte durch die MousePosition) aber wie kriege ich in das Array das Template?

Werbeanzeige