Bildausschnitt im Bild suchen?
-
Hallo,
ich habe 2 Images auf meiner Form und möchte prüfen ob Image2 in Image1 vorhanden ist, in Image2 befindet sich nur ein ausschnitt von Image1 und möchte prüfen ob diese in Image1 vorhanden ist, wenn ja, dann möchte ich die X und Y Position zurückgeben.Kann mir da vielleicht jemand helfen?
Ich bedanke mich schonmal im Voraus.
MfG
-
Hi,
das müsste mit TBitmap::ScanLine[int Row] gehen.
mfg
kpeter
-
Danke DIr.
Ich weiss leider nicht wie ich das hinbekommen soll, die funktion sollte schnell genug sein um das gesuchte Bild zu finden.
Kann mir vielleicht jemand einen Beispiel Code posten?
MfG
-
Hallo
Du wirst keinen kurzen und schnellen Code dafür hier so einfach gepostet bekommen. Ein Brute-Force-Algo wäre zwar mit nur 4 verschachtelte Schleifen erledigt, aber sehr langsam. Und halbwegs optimierte Algos sind sicher schon komplex.
bis bald
akari
-
Danke.
Ich bekomme es irgendwie nicht hin, bei mir gehen die 4 Schleifen, die ich Verschachtelt hatte, in die Hose und hab alles wieder gelöscht.
Hier mal mein Code, ich lade von einem externen Fenster ein Bild:
wnd = FindWindow(NULL,"Unbenannt - Paint"); //Handle vom Paint-Fenster HDC dc = GetDC(wnd); c = GetPixel(dc, 0, 0); red = GetRValue(c); green = GetGValue(c); blue = GetBValue(c);
Und das was bei Image2 ist, lasse ich in ein Bitmap laden:
//Bitmap erzeugen für die Bildausschnitt Graphics::TBitmap *tempBMP = new Graphics::TBitmap(); tempBMP = new Graphics::TBitmap; tempBMP = Image2->Picture->Bitmap; Farbe = tempBMP->Canvas->Pixels[0][0]; Farbe = ColorToRGB(Farbe); r = GetRValue(Farbe); //Rotanteil g = GetGValue(Farbe); //Grünanteil b = GetBValue(Farbe); //Blauanteil
Wie kann ich das jetzt ambesten mit der for-Schleife Prüfen lassen ob das Bild im Bild vorhanden ist?
Vielen Dank schonmal.
MfG
-
Ich hab das mal in Delphi geschrieben, wie könnte ich diesen Code:
function CheckBitmap(const Main: TBitmap; const Check: TBitmap): Boolean; var p1: PByteArray; p2: PByteArray; x: Integer; y: Integer; i: Integer; pfm: Integer; //Pixelformatmodificator const PixelFormatValues : array[TPixelformat] of Integer = (0, 0, 0, 8, 0, 16, 24, 32, 0); begin Result := false; Assert(Main.PixelFormat in [pf8Bit, pf16Bit, pf24Bit, pf32Bit]); Assert(Check.PixelFormat in [pf8Bit, pf16Bit, pf24Bit, pf32Bit]); Assert(Main.PixelFormat = Check.PixelFormat); pfm := PixelFormatValues[Main.PixelFormat] div 8; p2 := Check.ScanLine[0]; for y := 0 to Main.Height-1 do begin p1 := Main.ScanLine[y]; for x:= 0 to Main.Width-1 do begin if CompareMem(p1, p2, pfm) then for i:=0 to Check.Height-1 do if ((x + Check.Width) <= Main.Width) and ((y + Check.Height) <= Main.Height) then begin p1 := Main.ScanLine[y+i]; Inc(PByte(p1), x * pfm); p2 := Check.ScanLine[i]; if not CompareMem(p1, p2, Check.Width * pfm) then Break else if i = Check.Height-1 then begin Result := true; Exit; end; end; Inc(PByte(p1), pfm); end; end; end;
in C++ Builder umschreiben?
Sry, aber manche befehle in Delphi sind anders als in C++, ich wäre euch sehr dankbar, wenn mir das einer in C++ Builder umschreiben könnte.
MfG
-
bruce85 schrieb:
Sry, aber manche befehle in Delphi sind anders als in C++, ich wäre euch sehr dankbar, wenn mir das einer in C++ Builder umschreiben könnte.
Warum programmierst du dann C++? Wenn du das in Delphi programmiert hast, dann kennst du ja sicherlich auch den Algorithmus, den du dabei benutzt hast, was hält dich davon ab, diesen dann auch in C++ umzusetzen? So schwierig ist das nun wirklich nicht...
Im übrigen finde ich solche Wünsche ausgesprochen dreist. Ich helfe gern konkrete Probleme zu lösen, aber bei Dingen wie "bitte serviert mir eine Lösung meines Problems auf einem Silbertablett, damit ich selber nichts tun muss" hörts auf.
-
DocShoe schrieb:
Warum programmierst du dann C++? Wenn du das in Delphi programmiert hast, dann kennst du ja sicherlich auch den Algorithmus, den du dabei benutzt hast, was hält dich davon ab, diesen dann auch in C++ umzusetzen? So schwierig ist das nun wirklich nicht...
Überdies ist es vollkommen überflüssig. Erstelle ein Delphi-Unit, mit obiger Funktion, füge die Unit deinem C++Builder-Projekt hinzu, und schon kannst du die Funktion auch von C++ aus benutzen.
-
audacia schrieb:
Überdies ist es vollkommen überflüssig. Erstelle ein Delphi-Unit, mit obiger Funktion, füge die Unit deinem C++Builder-Projekt hinzu, und schon kannst du die Funktion auch von C++ aus benutzen.
Irgendwann kommt ihr dafür in die Hölle
-
und alles nur um in einem Spiel mit captcha zu cheaten!
-
Hi,
vielleicht sucht er nach einer digitalen Signatur
Nachfolgender Schnipsel zeigt, wie ScanLines funktioniert und löst natürlich nicht dein Problem.
Du brauchst nur ein TForm und ein TButton.//--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "ScanLine.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- // BeginExample: ScanLine // Property: Graphics.TBitmap.ScanLine // Property: Graphics.TGraphic.Height // Property: Graphics.TGraphic.Width // Property: Graphics.TBitmap.PixelFormat // BeginCode /* This example shows how to draw directly to a Bitmap. It loads a bitmap from a file and then copies it to another bitmap twice it's size. Then the two bitmaps are displayed on the form canvas. */ #include <memory> //for STL auto_ptr class void __fastcall TForm1::Button1Click(TObject *Sender) { std::auto_ptr<Graphics::TBitmap> Bitmap(new Graphics::TBitmap); std::auto_ptr<Graphics::TBitmap> BigBitmap(new Graphics::TBitmap); TRGBTriple *ptr, *bigPtr; // use a (byte *) for pf8bit color TPixelFormat pixForm, bigpixForm; try { Bitmap->LoadFromFile("../littlefac.bmp"); pixForm = Bitmap->PixelFormat; bigpixForm = BigBitmap->PixelFormat; Bitmap->PixelFormat = pf24bit; BigBitmap->PixelFormat = pf24bit; BigBitmap->Height = Bitmap->Height * 2; BigBitmap->Width = Bitmap->Width * 2; for (int y = 0; y < Bitmap->Height; y++) { ptr = reinterpret_cast<TRGBTriple *>(Bitmap->ScanLine[y]); for (int x = 0; x < Bitmap->Width; x++) { int bx = x * 2; int by = y * 2; bigPtr = reinterpret_cast<TRGBTriple *>(BigBitmap->ScanLine[by]); bigPtr[bx] = ptr[x]; bigPtr[bx + 1] = ptr[x]; bigPtr = reinterpret_cast<TRGBTriple *>(BigBitmap->ScanLine[by + 1]); bigPtr[bx] = ptr[x]; bigPtr[bx + 1] = ptr[x]; } } Canvas->Draw(0, 0, Bitmap.get()); Canvas->Draw(200, 200, BigBitmap.get()); } catch (...) { ShowMessage("Could not load or alter bitmap"); } } // EndCode // EndExample: ScanLine //---------------------------------------------------------------------------
Die Quelle fällt mir mom nicht ein...
mfg
kpeter
-
DocShoe schrieb:
Irgendwann kommt ihr dafür in die Hölle
Für das Untergraben deines pädagogischen Ansinnens? In dem Punkt bin schon hinreichend sündig für eine halbe Ewigkeit Fegefeuer
Deinem Kritikpunkt stimme ich ja in vollem Umfang zu. Würdest du es also bevorzugen, wenn ich den nächsten, der mit "convert teh code plz" kommt, ins Messer laufen (<=> alles in C++ umschreiben) ließe?
-
audacia schrieb:
DocShoe schrieb:
Irgendwann kommt ihr dafür in die Hölle
Für das Untergraben deines pädagogischen Ansinnens? In dem Punkt bin schon hinreichend sündig für eine halbe Ewigkeit Fegefeuer
Deinem Kritikpunkt stimme ich ja in vollem Umfang zu. Würdest du es also bevorzugen, wenn ich den nächsten, der mit "convert teh code plz" kommt, ins Messer laufen (<=> alles in C++ umschreiben) ließe?
Weder noch, sondern für das bunte Mischen von C++ und Delphi Zeugs.
Ob du jetzt anderer Leute Probleme löst oder nicht ist mir eigentlich egal, denn früher oder später bestrafen sich die Faulenzer selbst durch ihre fehlenden Fertigkeiten (die sie hätten würden sie ihre Probleme selber lösen).Übrigens: Wie lang ist eigentlich eine halbe Ewigkeit?
-
PS:
Es gibt übrigens keine Fegefeuer mehr, das hat Papst Benefiz XVI. letztes Jahr mit dem neuen Standard abgeschafft. War wohl buggy oder liess sich nicht nach Gesellschaft 2K portieren.
-
DocShoe schrieb:
Weder noch, sondern für das bunte Mischen von C++ und Delphi Zeugs.
Hm, bei RTL-/VCL-spezifischem Code (er wollte, soweit ich mich nicht täusche, ohnehin auf TBitmaps operieren) finde ich das unbedenklich. Und auch ansonsten kann die Kombination von Delphi und C++ überaus produktiv sein. In Delphi muß ich dank der intelligenteren IDE (-> Class Completion) im Schnitt nur die Hälfte tippen, und durch Error Insight und die Refactorings kommt man der Produktivität einer Java-IDE manchmal recht nahe. Auch sind durch die zusätzlichen Sprachfeatures (message, safecall, implements, dispinterface, $METHODINFO, benutzerdefinierte Varianttypen, resourcestring, anonyme Methoden) viele Szenarien, z.B. Komponentenentwicklung oder COM-Server und -Clients, signifikant einfacher als in C++. Andererseits ist die Anbindung an 3rd-Party-Bibliotheken, selten verwendete Windows-Header und plattformunabhängigen Code sowie der eine oder andere Low-level-Eingriff in C++ deutlich einfacher.
Zurzeit arbeite ich nebenher an einem kleinen IDE-Plugin für C++Builder, das das Detouring einiger Funktionen erfordert. Ich entschied mich, den funktionellen Teil in Delphi zu schreiben und den Hacking-Teil in C++. Bis jetzt hat sich dieser Ansatz als überaus produktiv erwiesen - und durch die strikte Trennung ist er auch einfacher zu testen.
DocShoe schrieb:
Übrigens: Wie lang ist eigentlich eine halbe Ewigkeit?
Die Angaben dazu schwanken umstandsbedingt. Besonders einfach haben es dabei die Glaubensgemeinschaften, die einen Weltuntergang in naher Zukunft prophezeien
-
DocShoe schrieb:
PS:
Es gibt übrigens keine Fegefeuer mehr, das hat Papst Benefiz XVI. letztes Jahr mit dem neuen Standard abgeschafft. War wohl buggy oder liess sich nicht nach Gesellschaft 2K portieren.Er hat den Limbus abgeschafft (Ort für ungetaufte Kinder). Das Fegefeuer ist nach dem gültigen Katechismus noch existent.
-
Braunstein schrieb:
DocShoe schrieb:
PS:
Es gibt übrigens keine Fegefeuer mehr, das hat Papst Benefiz XVI. letztes Jahr mit dem neuen Standard abgeschafft. War wohl buggy oder liess sich nicht nach Gesellschaft 2K portieren.Er hat den Limbus abgeschafft (Ort für ungetaufte Kinder). Das Fegefeuer ist nach dem gültigen Katechismus noch existent.
Zum Glück habe ich jemanden, auf den ich die Schuld abschieben kann: Hab nur das Programm von Hagen Rether gehört, und der hat das so behauptet. Bin da selbst eher gesagt wenig interessiert und demnach auch schlecht informiert, bitte also um Entschuldigung für Verbreitung nicht recherchierter Behauptungen.
-
Nochmals Entschuldigung für das Thread-Hijacking, also von mir aus kanns jetzt gerne mit dem Originalthema weitergehen,
-
Danke euch für die antworten.
audacia schrieb:
DocShoe schrieb:
Warum programmierst du dann C++? Wenn du das in Delphi programmiert hast, dann kennst du ja sicherlich auch den Algorithmus, den du dabei benutzt hast, was hält dich davon ab, diesen dann auch in C++ umzusetzen? So schwierig ist das nun wirklich nicht...
Überdies ist es vollkommen überflüssig. Erstelle ein Delphi-Unit, mit obiger Funktion, füge die Unit deinem C++Builder-Projekt hinzu, und schon kannst du die Funktion auch von C++ aus benutzen.
Ich habe das jetzt so gemacht und die Unit2 mit eingebunden, nun bekomme ich diese fehlermeldung:
[C++ Fehler] Unit1.cpp(82): E2268 Aufruf der undefinierten Funktion 'CheckBitmap'
Danke schonmal.
MfG
-
bruce85 schrieb:
nun bekomme ich diese fehlermeldung:
[C++ Fehler] Unit1.cpp(82): E2268 Aufruf der undefinierten Funktion 'CheckBitmap'
Na in den Header rein damit (mit der Deklaration)...