GDI+ Bitmap.SetPixel

  • Ich hab gerade nicht viel Zeit, deswegen in Kurzfassung:
    Folgendes Problem, in meinem Code habe ich folgende Zeile, wie im MSDN-Beispiel (http://msdn.microsoft.com/en-u…/ms536299%28VS.85%29.aspx):
    Status r=bmp.SetPixel(x,y,Color(255,0,0,0));
    Aber r wird zu "InvalidParameter", deswegen bräuchte ich eure Hilfe.
    Ich werde später noch den ganzen Code anhängen.
    Aufruf ohne Parameter (erster Aufruf):
    Status r=bmp.SetPixel(0,0,Color(255,0,0,0));


    EDIT:
    Code angehängt, wer sich über das LockBits wundert, das war mein erster Versuch, aber mitten im Bild gibt es einen Fehler beim Pixel auslesen... Deswegen versuch ich's jetzt erstmal mit SetPixel

  • Hi,
    wenn ich deinen Code richtig interpretiere, holst du dir doch schon per bmp.LockBits() einen Pointer auf die Bitmapdaten bzw Pixel. Wieso willst du dann noch mit dem (wesentlich langsameren) SetPixel()/Getpixel() arbeiten anstatt die 4 Byte direkt in den Speicher zu schreiben bzw zu lesen?
    Weiterhin bin ich nicht sicher, ob du so ein *.PNG benutzen kannst?!Funktioniert das mit einem *.BMP bzw *.JPG?

  • EDIT:
    Code angehängt, wer sich über das LockBits wundert, das war mein erster Versuch, aber mitten im Bild gibt es einen Fehler beim Pixel auslesen... Deswegen versuch ich's jetzt erstmal mit SetPixel


    Oh mann, danke, dass es an soetwas liegt hätte ich nie gedacht, er hat schließlich erfolgreich das Bild geladen
    Danke.. :D (Habs mit *.bmp jetzt)


    EDIT:
    Jetzt noch das LockBits-Problem (das ist geblieben).
    Immer bei x=108 und y=75 hat er in der Funktion GetPxl folgenden Fehler:
    Unbehandelte Ausnahme bei 0x00412dba in Bilderkennung.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x00aad000.
    Außerdem zeigt er eine Warnung an, die ich nicht deuten kann, für mich bedeutet es nur, dass ich etwas anders verwende:
    Zeile: int flag=ImageLockMode::ImageLockModeUserInputBuf;
    Warnung: "warning C4482: Nicht dem Standard entsprechende Erweiterung: Enumeration "Gdiplus::ImageLockMode" wird im qualifizierten Namen verwendet".


    Bitte um Hilfe und Danke für Hilfe :)


    EDIT:
    Anderes Bild genommen:
    X: 104, Y:78, Fehler: Unbehandelte Ausnahme bei 0x00412dba in Bilderkennung.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x00aff000.
    Bildgröße: 468x311

  • Hi,
    108x75x4Bpp = 32448 das liegt ziemlich nah an an 32768(2^15). Ggf musst du mehr Speicher freigeben, oder es werden immer nur bestimmte Speicherbereiche ge"lock"t. Da scheint irgendein Buffer zu klein zu sein....
    Hab aber ehrlich gesagt keine Ahnung^^
    Aber wenn du es hinbekommen hast, sag mal Bescheid wg der Geschwindigkeit, ich hatte für das ASM-Tut die AutoItfunktion_ColorConvertRGBtoHSL()in Assembler geschrieben, sogar anstatt mit (langsamen) Floats in Integer^^

  • Also ich mach es jetzt ersteinmal mit SetPixel, das klappt ja jetzt, RGBtoHSL braucht bei mir keine ganze Millisekunde @2GHz. Kleiner als ms kann ich noch nicht messen, habe aber schon etwas gefunden womit das gehen soll


    EDIT:
    Nächstes Problem bei der Bilderkennung:
    Run-Time Check Failure #2 - Stack around the variable 'colors' was corrupted.
    kommt am Funktionsende von Funktion Kernauswertung(kern,&bmp,w,h);
    (siehe Code, Anhang)
    BYTE colors[3][3];


    Anmerkung zum Code:
    algo ist leider nicht immer <= 255.


    Danke im Vorraus

  • Zitat

    Kleiner als ms kann ich noch nicht messen,

    in C++ solltest du eigentlich auch direkten Zugriff haben auf rdtsc, der gibt die anzahl derTAKTzyklen zurück seit dem letzen Rechnerstart. http://msdn.microsoft.com/en-us/library/twchhe95.aspx
    also pdeudocode:

    Code
    ticks_start=_rdtsc
    C-code
    ticks=_rdtsc-ticksstart ;anzahl der takte, die deine Funktion verbraten hat


    das sollte als Genauigkeit ausreichen fürs optimieren^^

  • hehe, langsam sollte ich mich vielleicht mal überwinden, auch mal eine Zeile C zu schreiben....wenigstens eine^^


    wg deinem Problem, ich vermute, dass es einen Überlauf gibt (exception) wenn du das Byte (colors) mit einem Wert von wegen mir 178 mit -2 (kern) multiplizierst....das ergibt mehr als 255 und daher ein Überlauf. Ich könnte mir gut vorstellen, dass es ein Compilerflag gibt, um das abzufangen...wenn das überhaupt den Fehler auslöst....
    0xB2 * 0xFFFFFFFE = 0xFFFFFE9C
    178 * -2 = -356 = 0xFFFFFE9C ....= 4294966940 ......shit happens^^
    /Edit/ sry, hab gerade gesehen ALGO ist INT, dann könnte es ja klappen, lass dir mal die algos als liste ausgeben bis der error kommt, im zweifelsfall MOD 255 oder algo direkt als byte dimensionieren

  • algo ist leider wirklich manchmal höher ^^ (das stört aber nur in der Zeile darunter)
    Das Problem ist nur, dass der Fehler am Ende der Funktion kommt, also nachdem alles fertig ist. Ich schätze eher dass es also eher wieder was mit Array löschen zu Tun hat. GDI+ macht mir ja ohne exit(0); auch am Ende von main() Probleme

  • Bei mir sieht das so aus:
    Nach einem RGB2HSV bekomme ich vom linken Teil des Orginalbildes aus deinem Link das hier:
    autoit.de/wcf/attachment/11523/
    Und nach 2x Sobel-Matrix (senkrecht und waagrecht) :
    autoit.de/wcf/attachment/11524/
    Wozu brauchst du die Kantenerkennung?

  • Ich wollte mal ein bisschen gucken wie das ist im Internet mit der Bild- und Texterkennung, da hab ich das Tutorial gefunden und das war ja eigentlich recht leicht, dachte ich mir, die RGBtoHSV Funktion war als Pseudocode schon drin. Naja leider war es dann doch nicht so leicht. In C++ ist irgendwie alles viel schwerer. Ich wollte also mal ein bisschen reinschnuppern, weiter als Kantenerkennung geht das Tut. ja nicht, also viel weiter würde ich dann auch erstmsl nicht kommen. Aber ich dachte immer das wär viiieeell komplizierter soetwas.


    Woher hast du denn deine HSV Funktion genommen? Von Autoit übersetzt? Werde ich jetzt auch einmal versuchen und dann gucke ich mal was mit der Kantenerkennung los ist, ich glaube nämlich ich weiß was da faul ist

  • Zitat

    Woher hast du denn deine HSV Funktion genommen? Von Autoit übersetzt?

    Ja, ich hatte für das Assemblertut eine Funktion gesucht, die man "einfach" 1:1 in Assembler übersetzen kann. Eigentlich war ich ziemlich begeistert, da nur relativ einfache Rechnerei umzusetzen war. Allerdings wurde die Umsetzung doch relativ umfangreich, so dass ich mich entschlossen habe, das Beispiel nicht im Tut zu verwenden.
    Übrigens hatte ich den ursprünglich mit Float-Zahlen werkelnden Algorithmus komplett in Integer umgesetzt! Zuerst in AutoIt, dann in Assembler. In AutoIt war natürlich kaum ein Geschwindigkeitszuwachs bemerkbar, in Assembler allerdings war der Schub gewaltig, unoptimiert (war ja fürs Tut geplant) schon Faktor 4! Ich denke, auch C++-Programmierer hätten von diesem Wink mit dem Zaunpfahl profitiert.


    Da auch die anschliessende Matrixmultiplikation extrem gut zu parallelisieren ist, habe ich "multithreating" - AutoIt benutzt. Prog@ndy hatte zu diesem Thema mal einiges gezeigt, aber mit AutoItcode kommt man nicht weiter, da AutoIt nicht threadsicher ist. Das ist der weitere Vorteil von Assembler, man weiss ziemlich genau, was der Prozessor (bzw ASM-code) macht oder auch nicht macht. Daher ist es kein Problem 3-4 Threads mit aufwendigen Berechnungen gleichzeitig zu starten und dann auf Ergebnisse zu warten. Leider bringt Multithreathing nicht sonderlich viel, solange die Threads nur auf einem Core laufen ^^. Allerdings ist es schon beeindruckend, wenn das AutoItscript 4 Threads anstösst und sofort mit dem Programmcode weitermacht. Für hochkomplexe und langwierige Berechnungen lohnt sich das sicher!

    Zitat

    Aber ich dachte immer das wär viiieeell komplizierter soetwas.

    Learning by doing! Bleib am Ball, du lernst jeden Tag etwas dazu!


    /edit/ Integerversion

  • So danke, aber hier jetzt nochmal die Bilder, wieder anders als deine.
    Oh ich sehe gerade, die Kernauswertung funktioniert noch nicht also nur das HSVbild:
    autoit.de/wcf/attachment/11528/


    EDIT: Achja, der Code natürlich noch:

  • Danke nochmal, und 2 Fragen noch:
    Warum unterscheiden sich meine Bildervon Andys (hautpsächlich an Andy :) )?
    Was kann ich mit soeinem Kantenbild jetzt anstellen? (vielleicht kennt ihr weitere Tutoriale)


    EDIT:
    Einen Fehler der Kernverarbeitung hab ich noch gefunden, also die erste Frage nur, warum sich das HSL/HSV Bild unterscheidet


    EDIT:
    Fehler beseitigt, ist aber immernoch anders