Image Problem
-
Hallo,
ich hab ein Problem mit Images:
Ich lasse eine Objekterkannung zu einem Bild machen und kopiere jeweils den Bereich des erkannten Objektes in ein neues, zur Laufzeit erzeugtes Image. In dem Originalbild sind mehrere Objekte enthalten. Das klappt ohne Probleme. In den neuen Images wird das Bild jeweils beginnend an Position 0/0 gemalt. Nun will ich es aber proportional dargestellt haben. Zuerst beim Erzeugen der neuen Images definiere ich die Größe des Objektes, wie ich es aus dem Original ausgelesen habe. Wenn ich es nach dem Malen verändere auf meine gewünschte Größe, dann macht er das aber nicht (trotz proportional und stretch). Auch der Versuch das Image zu speichern, ein weiteres neu zu erzeugen in meiner Wunschgröße und dann das gespeicherte reinzuladen klappt nicht.
Was übersehe ich da bzw. mache ich falsch ???
Danke !
-
Richtig schlau werde ich aus deiner Beschreibung nicht, aber bei Gössenänderungen an TImage sollte immer auch explizit die Grösse der internen Bitmap-Property angepasst werde, das erfolgt nicht automatisch.
-
Hi,
mein Image zur Weiterverarbeitung ist 169x169 groß. Das zu ladende bmp aber meist größer, selten kleiner. z. B. 600x450. Da ich das Bild pixelweise bearbeite und einige Pixel auf ein neues Image übertrage muss ich es also auf meine gewünschte Größe skalieren.
imgAnalyse->Width = 169; imgAnalyse->Height = 169; imgAnalyse->Picture->Bitmap->Height = 169; imgAnalyse->Picture->Bitmap->Width = 169;
Irgendwie komm ich leider überhaupt nicht damit weiter.
-
Wenn du einfach die Grösse änderst, wird nicht skaliert sondern beschnitten.
Zum Skalieren könntest du z.B. TCanvas::StretchDraw verwenden.Wenn du etwas mehr Code zeigst kann dir aber sicher besser geholfen werden.
-
Hallo,
ich hab was im Forum gefunden und eingebaut. Von der Anzeige her klappt es, nur gibt es in der folgenden Verarbeitung einen Fehler, den ich nicht habe wenn ich das Bild vorher mit gimp zu 169*169 skaliere.
Ich teste die Pixel entwender nach den rgb-Werten oder HSV-Werten. Ersteres hab ich unten gepostet.
Bei verkleinerten Bildern krieg ich einen Stack-Überlauf in der FloodCheck Funktion. Die x/y Parameter sind aber korrekt (z. B. 18/56 oder 26/119).
[EDIT] Hat nichts mit den verkleinerten Bildern zu tun. Der Stack-Überlauf kommt wenn es ein sehr großer Bereich ist, der durch die Rekursion geschickt wird. Wie kann ich das beheben ? Denn es geht darum, dass Bereiche ab einer bestimmten Größe angezeigt werden sollen, andere nicht.
Load: objOpen->Execute(); TRect ARect; Graphics::TBitmap *bmp = new Graphics::TBitmap(); TJPEGImage *jpg = new TJPEGImage(); jpg->LoadFromFile(objOpen->FileName); // gewünschte neue Abmessungen festlegen bmp->Width = 169; bmp->Height = 169; // Rect mit den gleichen Abmessungen definieren und das per // StretchDraw vergrösserte JPEG auf das Bitmap zeichnen ARect = Rect(0, 0, 169, 169); bmp->Canvas->StretchDraw(ARect, jpg); // Inhalt des Bitmap auf das JPEG übertragen, speichern jpg->Assign(bmp); jpg->ProgressiveEncoding = true ; jpg->ProgressiveDisplay = true ; jpg->Smoothing = true ; jpg->CompressionQuality = 100 ; jpg->SaveToFile("test2.jpg"); delete jpg; delete bmp; TJPEGImage* jpimg = new TJPEGImage(); jpimg->CompressionQuality = 90; jpimg->Grayscale = false; jpimg->Performance = jpBestQuality; jpimg->ProgressiveDisplay = false; jpimg->ProgressiveEncoding = false; jpimg->Scale = jsFullSize; jpimg->Smoothing = true; // jpimg->PixelFormat = TJPEGPixelFormat::jf24Bit; jpimg->LoadFromFile("test2.jpg"); // ZwischenBitmap Graphics::TBitmap* pBmp = new Graphics::TBitmap(); // pBmp->SetSize(169, 169); pBmp->Assign(jpimg); imgAnalyse->Picture->Assign(pBmp); delete jpimg; delete pBmp; void FloodCheck(int x, int y) { if (HDC_Check(x, y, StrToInt(frmPix->txtRGB->Text)) == false) { frmPix->imgDummy->Canvas->Pixels[x][y] = frmPix->imgAnalyse->Canvas->Pixels[x][y]; frmPix->imgAnalyse->Canvas->Pixels[x][y] = clBlack; iPix++; } // Aktueller + alle umliegenden schwarz -> Ende if (HDC_Check(x, y, StrToInt(frmPix->txtRGB->Text)) == true && HDC_Check(x + 1, y, StrToInt(frmPix->txtRGB->Text)) == true && HDC_Check(x - 1, y, StrToInt(frmPix->txtRGB->Text)) == true && HDC_Check(x, y - 1, StrToInt(frmPix->txtRGB->Text)) == true && HDC_Check(x, y + 1, StrToInt(frmPix->txtRGB->Text)) == true) { return; } // rechts daneben kein schwarz if (HDC_Check(x + 1, y, StrToInt(frmPix->txtRGB->Text)) == false) { FloodCheck(x + 1, y); } // links daneben kein schwarz if (HDC_Check(x - 1, y, StrToInt(frmPix->txtRGB->Text)) == false) { FloodCheck(x - 1, y); } // drunter kein schwarz if (HDC_Check(x, y + 1, StrToInt(frmPix->txtRGB->Text)) == false) { FloodCheck(x, y + 1); } // drüber kein schwarz if (HDC_Check(x, y - 1, StrToInt(frmPix->txtRGB->Text)) == false) { FloodCheck(x, y - 1); } } bool HDC_Check(int x, int y, int iSchwelle) { HDC test; int r; int g; int b; r = GetRValue(frmPix->imgAnalyse->Canvas->Pixels[x][y]); g = GetGValue(frmPix->imgAnalyse->Canvas->Pixels[x][y]); b = GetBValue(frmPix->imgAnalyse->Canvas->Pixels[x][y]); if (r + g + b <= iSchwelle) { return true; } else { return false; } }
-
Die Rekursionstiefe kannst du durch Erhöhen des Stacks bei den Projektoptionen einstellen.
Aber deine FloodCheck-Funktion solltest du noch mal überarbeiten (performancetechnisch), denn du wertest ja jedesmal den Ausdruck "StrToInt(frmPix->txtRGB->Text)" neu aus - das Pixelsetzen müßte man ja zuschauen können...
-
Danke, hab ich beides gemacht.
Eine letzte Nachfrage. Ich hab in der FloodCheck Funktion try catch eingebaut und geb eine Meldung aus, wenn der Fehler auftritt. Nach der MessageBox wird das gesamte Programm aber beendet. Kann ich das verhindern ?
void FloodCheck(int x, int y) { try { if (HDC_Check(x, y, StrToInt(frmPix->txtRGB->Text)) == false) ... catch (...) { Application->MessageBoxA("Bild nicht geeignet !", "Fehler"); }
-
hp_stern schrieb:
Ich hab in der FloodCheck Funktion try catch eingebaut und geb eine Meldung aus, wenn der Fehler auftritt. Nach der MessageBox wird das gesamte Programm aber beendet.
Ach beim Programmstart ausserhalb der IDE?
-
Ja, darauf bin ich nicht reingefallen
-
Dann solltest du dich wohl mal damit befassen, welche Exception konkret auftritt und warum.
catch (Exception *e) { ... e->Message ...; // usw. }
-
"StrToInt(frmPix->txtRGB->Text)" hast du ja immer noch in deiner Flood-Funktion stehen...