Opencv c++ Bild mit Maske kopieren
-
Hallo Dobi,
vielen Dank für deinen Post, schon habe ich wieder was gelernt, ich versuche generell immer noch meine Filter die ich bisher in Imagemagick vorliegen habe mit opencv zu realisieren im Moment laufen die Filter die ich fertig habe mit ca. 0.08 ms bis 0.5ms. Imagemagick im Gegensatz dazu mit 1.5s bis 3s und das obwohl Imagemgick mit mehreren CPUś arbeitet.
Gruß
-
Das ist interessant. Normalerweise würde man ja erwarten, dass Imagemagick schon ziemlich durchoptimiert ist. Kann es sein, dass du bei deiner Version nur die Filterei an sich mit deiner Stopuhr misst und bei Imagemagick alles, also Programm starten, Bilder laden, Filtern und Ergebnis speichern?
-
Ich mache mit Imagemagick die selben Arbeitsschritte wie mit opencv, sprich Bild laden, Maske laden, Maske an Bildgröße anpassen, Maske mit Bild verrechnen und Bild anschließend speichern.
Ich messe die Zeit mit dem "time" Befehl
loonix@ubuntu:~/opencv-2.4.5/test$ time ./mul
real 0m0.041s
user 0m0.036s
sys 0m0.004sIch habe mal deinen zweiten Programmcode kopiert und bei mir eingefügt.
Wenn ich den Modus der beiden Bilder von GRAYSCALE zu COLOR ändere und das ganz ausführe, wird zwar die Ausgabedatei erstellt aber das Bild ist nur zu einem drittel vorhanden der Rest ist Schwarz. Wo dran kann das liegen?Gruß
-
Du misst also die Zeit, die der Programmstart usw. dauert, mit. Das ist ungefähr so als wollten wir beide gucken, wer von uns beiden im 100m-Sprint schneller ist, aber die Zeitmessung incl. Zug-Anreise zum Sportplatz, umziehen, aufwärmen, hinterher duschen und wieder nach Hause fahren messen.
Ja, der von vom gepostete Code funktioniert nur für Bilder vom TYP CV_8UC1, weil ich
cv::Mat::at<unsigned char>(y, x)
benutze. Bei Farbbildern (meistens CV_8UC3) ist jeder Pixel aber 3 Byte groß. Du brauchst also entweder noch eine weitere Verschachtelung in den Schleifen in der Art von
for (int c = 0; c < img_c.channels(); ++c)
durch die Kanäle doppelst. Oder du liest die Pixel als cv::vec3b statt als unsigned char aus.
Schau dir mal die beiden Tutorials hier an. Da wird erklärt, wie Bilder im Speicher liegen usw:
Mat - The Basic Image Container
How to scan images, lookup tables and time measurement with OpenCV
-
Dobi schrieb:
Du misst also die Zeit, die der Programmstart usw. dauert, mit. Das ist ungefähr so als wollten wir beide gucken, wer von uns beiden im 100m-Sprint schneller ist, aber die Zeitmessung incl. Zug-Anreise zum Sportplatz, umziehen, aufwärmen, hinterher duschen und wieder nach Hause fahren messen.
real world metapher par excellence
-
Guter Vergleich ;-).
okay habe es hinbekommen :-).
Danke
-
-
Moin,
ich habe mal wieder ein kleines Problem und zwar... in Gimp kann ich als Ebenen Modus "Division" auswählen.
Die Formel dazu findet man auf http://docs.gimp.org/de/gimp-concepts-layer-modes.html
E = (256 * I) / (M + 1)
Mein C++ Code durchläuft jeden Pixel und Kanal und führt die Formel aus.
Nur sieht mein Bild welches ich erzeuge bei weitem nicht so aus wie das Ergebnis welches Gimp mir ausgibt.Mein Bild hat sehr viele bunte "pixelfehler". Ich kann gerne auch mal mein Bild hochladen vielleicht hilft das ja.
#include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include <stdio.h> #include <iostream> using namespace std; using namespace cv; char window_name1[] = "Fenster 1"; int main( int argc, char** argv ) { Mat src(imread(argv[1], CV_LOAD_IMAGE_COLOR)); cv::dilate(src,dest,Mat(Size(3, 3), CV_8UC1)); Mat img_c(src.size(), src.type()); typedef unsigned char byte; for (int y = 0; y < dest.rows; ++y) { for (int x = 0; x < dest.cols; ++x) { for(int c = 0; c < dest.channels(); c++) { byte a = src.at<Vec3b>(y, x)[c]; byte b = dest.at<Vec3b>(y, x)[c]; img_c.at<Vec3b>(y,x)[c] = ((256*a)/(b+1)); } } } imshow( window_name1, img_c ); waitKey(0); return 0; }
-
Loonix schrieb:
byte a = src.at<Vec3b>(y, x)[c]; byte b = dest.at<Vec3b>(y, x)[c]; img_c.at<Vec3b>(y,x)[c] = ((256*a)/(b+1));
Du multiplizierst ein Byte mit 256?
-
Schande über mein Haupt, habe den Fehler gefunden danke.
-
Ich möchte ebenfalls einen Bildausschnitt in ein anderes Bild kopieren. Zum Beispiel ein Bild mit einem Fussballer in ein Bild mit einem Fussballstadion. Ich möchte also den Fussballer herauskopieren und in ein anderes Bild einsetzen. Es soll aber nachher so aussehen als ob er in dieses Bild gehört. WIe kann ich das anstellen. Muss ich wirklich erst über verschiedene Algorithmen gehen wie: Kontrast, Cannyfilterung nd Kantenerkennung oder geht dies auch anders. Am besten möchte ich das über einen Gui machen, sodass Benutzer dies auch ausführen könnten. DIe Gui ist aber ertsmal hinten angestellt.
-
meinst du sowas wie poisson blending?