Zum Inhalt springen

Bilder filtern -> Helligkeitswerte auslesen?


Empfohlene Beiträge

Geschrieben

Hi, ich habe da ein Problemchen... ;)

Ich wollte mir mal selber nen Tiefpass Filter basteln, um genau zu sein soll der später eingesetzt werden, um die Bilder die eine Robotercam liefert zu filtern und anschließend eine Korrelationsanalyse zu liefern.

Nun will ich diesen Filter aber zuerst einmal an "normalen" Bildern ausprobieren, bevor ich mich an die Cam mache. Dazu benötige ich aber eine Matrix mit (Graustufen-) Helligkeitswerten, die dieses Bild beschreibt, damit ich die dann durch den Filter laufen lassen kann.

Ich hab aber leider noch keine Idee, wir ich an diese Matrix kommen :(

Das Format ist für den Anfang egal, meinetwegen kanns sogar .bmp sein :D

Ich hoffe ihr könnt mir da weiterhelfen.

//Edit: Oh, das wichtigste ganz vergessen, damit das ganze am Ende auf dem roboter läuft, muss ich mit ansi c arbeiten.

Geschrieben

Deine Fragen sind sehr allgemein.

Du musst eine Bilddatei einlesen. Wenn dies ein Graustufenbild ist, hast Du bereits quasi eine Matrix von Helligkeitswerten. Wenn es ein RGB-Bild ist, kannst Du Dir aus den RGB-Tripeln Helligkeitswerte errechnen und ein neues Graustufenbild aufbauen.

Geschrieben

Huch, scheint als wäre meine Frage sogar zu einfach... :eek

Wenn dies ein Graustufenbild ist, hast Du bereits quasi eine Matrix von Helligkeitswerten.

Da ich meine Testbilder selber erstellen kann, kann ich auch festlegen, dass sie alle Graustufenbilder sind.

Die Frage die sich mir stellt ist nur:

WIE komm ich an diese Matrix ran? Wie schaff ich es, das Ding in ein z.B. 2D-Feld einzulesen?

Wenn es ein RGB-Bild ist, kannst Du Dir aus den RGB-Tripeln Helligkeitswerte errechnen und ein neues Graustufenbild aufbauen.

Das hatte ich natürlich im Hinterkopf, wobei folgende Gleichung verwendet werden kann:

grauwert=sqrt(rot*rot+blau*blau+gruen*gruen)/3

Nur nützt mir das Momentan eben wie gesagt recht wenig, wenn ich nicht weiß, wie ich an die Graustufenmatrix rankomme ;)

Geschrieben

WIE komm ich an diese Matrix ran? Wie schaff ich es, das Ding in ein z.B. 2D-Feld einzulesen?

Für gängige Bildformate gibt es fertige Funktionen oder Bibliotheken zum Lesen und Schreiben von Bildern in dem jeweiligen Format. Für einfache Bildformate kann man einen Reader aber auch ohne gewaltigen Aufwand selbst schreiben, wenn man eine genaue Beschreibung des Formats hat.

In ein 2D-Array, auf dessen Elemente Du mit zwei Paaren eckiger Klammern zugreifen kannst, wirst Du die Pixel nur bekommen, wenn Du Dich vorab auf eine Bildgröße festlegst.

Geschrieben

Hmm, OK, das heißt ich such einfach mal nach ner Bibliothek und hoffe das ich was finde... Klingt nach dem praktikablen Ansatz, danke :)

Wenn ich was gefunden hab, dann stell ichs hier als Link rein!

Geschrieben

Moin!

Erstmal zu Deiner Umrechnung in Grauwerte:

Spar Dir das Quadrieren der Farben und anschließende Teilen, das ist überflüssig. einfach (R + G + B)/3 tut es auch. Wenn Du es genau nehmen willst, dann gibt es Faktoren für RGB, die ich aber nicht aus dem Kopf weiß. Mit der einfachen Variante bekommst Du aber schon sehr gute ergebnisse.

Jetzt zu der 2D Matrix:

Mit welcher Entwicklungsumgebung arbeitest Du? Visual C++ mit MFC, .NET, Borland?

Wäre gut zu wissen um Dir zu sagen wie Du an die Pixeldaten rankommst.

Wenn Du deine BMP geladen hast kannst Du dann die Pixel einzeln auslesen und in ein 2D-Array schreiben(ist dann am einfachsten und die spätere Verarbeitung geht meist schneller als direkt im Bild (aufwändige get/set-Methoden). Außerdem kannst Du das Bild dann gleich in Grauwerte umrechnen.

Wenn Du Deine Pixelwerte als 24 oder 32Bit-RGB bekommst kannst Du dann einfach durch "shiften" an die einzelnen Farben kommen.

Um dem Ärger mit dynamischen 2d-Arrays aus dem Weg zu gehen, kannst du auch einfach ein 1D-Array nehmen und es dann dynamisch erstellen (Breite mal Höhe). Der Zugriff aus die Daten sieht dann so aus:

grauwertArray[YPos*Breite+Xpos] = was_auch_immer_an_Stelle_X,Y_kommen_soll

Bei weiteren Fragen helf ich gern weiter!

P.S.: Ist Dir schon klar wie das mit dem Tiefpass funktioniert, oder ist da Erklärungsbedarf?

Geschrieben
Hmm, OK, das heißt ich such einfach mal nach ner Bibliothek und hoffe das ich was finde...

Leider hast Du nicht das OS und den Compiler genannt, mit dem arbeitest. Für JPEG oder PNG gibt es z.B. Bibliotheken. Damit dürften für Dich die gänigsten Formate auch schon abgedeckt sein, vermutlich wirst Du Dich eh für eines entscheiden.

Geschrieben

Hey, sry. das es solange gedauert hat, war etwas im Stress...

Aaaaaalso:

Größtenteils werd ich wohl unter Windows XP arbeiten, der Compiler ist die Standartausführung von MS Visual C++ Studio 6...

C++, weil ich momentan nicht an eine gescheite C Oberfläche komme, aber die UNetrschiede werden nicht so gravierend ausfallen (hoffe ich zumindest :D) so dass ich am Ende flugs alles übersetzen kann.

@Pointerman: Wow, das klingt nach viel Erfahrung in dem Bereich! :)

Momentan hab ich zumindest nen Plan, die Fragen kommen 100-pro bald auch *g*

Vor allem vor der fastFFT hab ich ziemlichen Respekt. ;)

Geschrieben

Moin!

Wenn Du mit der MFC arbeitest solltest Du Dir mal CImage und CBitmap angucken. Ich habe da mal mit gearbeitet, aber fand es sehr umständlich. Ich kann dazu nicht viel weiterhelfen, aber im Netz oder hier im Forum gibts da bestimmt Hilfe.

Nun zur FFT:

Willst Du das Rad neu erfinden oder würdest Du auch eine fertige FFT nehmen?

Wenn letzteres der Fall ist, kann ich Dir die FFTW empfehlen. Schneller gehts fast nicht mehr!

FFTW Home Page

Da fällt mir ein: Wozu brauchst Du die FFT eigentlich? Um den Tiefpass im Frequenzbereich zu machen? Geht schon, aber warum nicht ein simpler Gauss-Filter? Da brauchst Du keine FFT und es funktioniert auch.

Willst Du die Bilder korrelieren um die Verschiebung der Bilder und damit Bewegungsrichtung zu ermitteln?

Mhhh, wenn ich das ganze so sehe überleg ich gerade, ob Du Dir nicht mal OpenCV angucken solltest. Das ist eine ImagingToolbox, die viele fertige Routinen mitbringt...

Gruß,

Pointerman

Geschrieben

Hehe, ich hab eigentlich zu Hause einen von den berüchtigten "Numerical Recepices in C" rumliegen, wo eine Umsetzung der FFT drin ist, allerdings muss ich gestehen, dass dieses FFTW nach flüchtigem Überfliegen seeeeehr interesannt aussieht. :D

Wozu brauch ich die FFT? Tja, mein Ziel ist es eigentlich, eine Art Zielerkennung für einen Roboter zu schreiben.

Das ganze soll so klappen, dass die Umgebung nach einem bestimmten Frequenzband durchsucht und alles, was verdächtig aussieht, mit dem eingespeicherten Ziel "vergleicht". (Dazu auch die Korrelation... ich muss gestehen, dass ich hier noch nicht allzu firm bin, da mich erstmal die Filterproblematik auf Trab gehalten hat, aber soweit ich weiß müsste ich so ganz gut fahren)

Die Idee mit Gauß'schen Filter kam mir auch. Allerdings hab ich mir mal angeschaut, wie das Ding sich auf Signale auswirkt und das hat mir nicht gefallen. Ich brauch die Daten innerhalb des Tiefpasses fast unverändert, damit ein sinnvolles Vergleichen möglich ist, und da hat der Gauß mMn zu viel verändert.

Geschrieben

ja, wenn du dann eh im Frequenzbereich bist, dann wärs natürlich praktisch da auch die Korrelatiob zu machen. Da kann ich aber nichts zu sagen, da ich da derzeit selber dran bin! Da kannst Du mir dann vielleicht ja noch was neues erzählen... :D

Wozu brauchst Du eigentlich den Tiefpass? Dochwohl nicht, um Rauschen zu unterdrücken... Da würd ich dann fast einen Medianfilter empfehlen: Einfach zu schreiben und eliminiert Rauschen besser als der Gauss, ohne viele Details kaputt zu machen.

Halt mich bitte auf dem laufenden, klingt alles sehr interessant!

Bin jetzt aber erstmal ein Bierchen trinken :floet:

Geschrieben

Größtenteils werd ich wohl unter Windows XP arbeiten, der Compiler ist die Standartausführung von MS Visual C++ Studio 6...

Diese Version ist inzwischen wirklich alt und Du solltest einen aktuellen Compiler verwenden. Die aktuelle Express Edition kannst Du Dir auch kostenlos runterladen.

MFC würde ich für Deine Anwendung nicht verwenden. Du könntest Dir aber überlegen, Deine Bildverarbeitungsrotinen als Plugin für eine Grafiksoftware umzusetzen, wodurch sie sich unter Umständen einfacher testen lassen.

Wozu brauch ich die FFT? Tja, mein Ziel ist es eigentlich, eine Art Zielerkennung für einen Roboter zu schreiben.

Warum willst Du dies im Frequenzraum tun?

Geschrieben
Diese Version ist inzwischen wirklich alt und Du solltest einen aktuellen Compiler verwenden. Die aktuelle Express Edition kannst Du Dir auch kostenlos runterladen.

Naja, ich hab gerade gemerkt, dass das so sowieso nicht klappen wird. Ich muss ein paar Bibliotheken einbinden, die alle in C sind, also kann ich Visual C++ vergessen. Werde mir da wohl ein Borland C runterladen, allerdings ist da nix mehr mit "aktuellem Compiler"... :(

Warum willst Du dies im Frequenzraum tun?

Tja, eine filterung im Ortsraum ist eine ziemlich komplexe und rechenaufwendige Sache. Das macht ein kleinr armer Robo nur schwerlich mit.

Im Frequenzraum dagegen ist das eine einfache multiplikation. Natürlich muss alles in den Frequenzraum übersetzt werden, aber das ist, soviel ich weiß, für den Rechner nicht so aufwendig wie das Filtern im Ortsraum.

@Pointerman:Mein Ziel werd ich so aufbauen, dass es ziemlich klar im Niederfrequenzbereich liegt, deswegen kann ich nicht nur Rauschen, sondern sogar alles, was über einer bestimmten Grenzfrequenz (die ich noch ermitteln muss *gg*) liegt wegfiltern. Ziemlich praktisch eigentlich :D

Viel Spaß übrigens mit dem Bierchen... =)

Geschrieben
Naja, ich hab gerade gemerkt, dass das so sowieso nicht klappen wird. Ich muss ein paar Bibliotheken einbinden, die alle in C sind, also kann ich Visual C++ vergessen.

Stimmt nicht. Mit Visual C++ kannst Du sowohl in C geschriebene Libraries verwenden (auch wenn Du den Rest in C++ programmierst), als auch in C programmieren, wenn es unbedingt sein muss.

Tja, eine filterung im Ortsraum ist eine ziemlich komplexe und rechenaufwendige Sache.

Es kommt immer darauf an, was Du tun willst (und wie Du es tun willst). Für ein komplettes Bild eine FT durchzuführen, kostet einiges an Rechenzeit. Wenn es nur darum geht einen Lowpass-Filter anzuwenden, dann braucht man keine FT.

Geschrieben
Stimmt nicht. Mit Visual C++ kannst Du sowohl in C geschriebene Libraries verwenden (auch wenn Du den Rest in C++ programmierst), als auch in C programmieren, wenn es unbedingt sein muss.

Achso?! Ich habs probierte, ehrlich! Zu aller aller erst mit ein paar typischen C befehlen die das C++ nicht mehr verstehen sollte...

Und bekam prompt einen Fehler über unbekannte Befehle.

Als ich dann die Bibiliotheken zu implementieren versucht habe, kamen so an die 200 Fehlermeldungen, obwohl da eigentlich alles soweit stimmen müsste.

Muss ich irgendwas besonders beachten, wenn ich die C biblios einfügen will? :confused:

Und naja, wie gesagt, außer dem lowpass will (muss) ich ja auch ne Korrelation ausführen, und da bietet sich der Frequnezbereich an. Ich bin mir relativ sicher, dass ich da nix falsches mache. (Aber trotzdem vielen Dank für die vielen Nachfragen, da weiß man sofort dass wirklich Lust bestehet zu helfen! :uli)

  • 2 Wochen später...
Geschrieben

Mhh, ich muss gestehen, das ich wieder beim Anfang des Threades angekommen bin... :(

Zwar bin ich mit der FFTW jetzt vertraut, allerdings musste ich zwischendurch auf Linux und den gcc 4.0 Compiler umsteigen.

Und damit kann ich leider kein OpenVC nutzen

#The current distribution of OpenCV (0.9.7 beta 5) does *NOT* work with GCC 4.0 or 4.1.

#

Building will fail on x86_64 platforms and GCC 4.0.2 ...

und, un ehrlich zu sein, ich hab beim Überfliegen der Anleitung nicht wirklich verstanden, wie mir das Open VC momentan helfen würde *rotwerd*

Hätte vlt. jemand nen Tipp für eine Bibiliotek die mir ermöglichen würde Graustufenbilder in (gerne auch dynamische) 2D Felder einzulesen?

Bisher konnte mir Onkel Google da nämlich auch nicht weiterhelfen :(

Geschrieben

Für einfache Bildformate (z.B. BMP mit festgelegter Bittiefe) kann man sich eine Ladefunktion leicht selbst schreiben.

Für verbreitete Formate wie JPEG, PNG, usw. gibt es fertige Bibliotheken (library).

Ich kann mir kaum vorstellen, dass eine Suche danach erfolglos ist.

Geschrieben

So, jetzt mal ne dumme frage! :D

Ich hab vorher noch nie mit dynamischer Speicherverwaltung gearbeitet...

 fftw_complex *in, *out;

 in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);

Heißt das soviel wie, das ein Feld erstellt wird, vom Typ fftw_complex, mit N speicherbaren Werten?

Kann ich dieses N im Verlauf des Programms verändern, so dass sich die Speicherreservierung sofort ändert? Oder muss ich es vor der deklaration mit malloc bestimmen?

Geschrieben

Moin!

Heißt das soviel wie, das ein Feld erstellt wird, vom Typ fftw_complex, mit N speicherbaren Werten?

Jau! Es wird ein Feld angelegt, daß N Elemente mit der Größe(Bytes) des Typs fft_complex enthält.

Kann ich dieses N im Verlauf des Programms verändern, so dass sich die Speicherreservierung sofort ändert?

Wenn Du meinst, daß Du 10 Zeilen später N einen neuen Wert gibst und sich das auf die Arraygröße auswirkt, dann ein klares nein!

das fftw_malloc reserviert Speicher und gibt einen Pointer auf dies Feld zurück. Dynamisch heißt in diesem zusammenhang nicht, daß sich die Arraygröße ständig ändern lässt, sondern, daß du nicht zur Compilezeit eine Größe vorgibst, sondern diese zur Laufzeit bestimmen kannst. In Deinem Fall, daß Du je nach Bildgröße Deine Array dimensionieren kannst.

Gruß!

Geschrieben

An mehrdimensionalen Arrays in c++ hab ich noch nicht so recht rumprobiert, das wurd mir dann immer zu frickelig. AFAIK gibts da keine direkte Unterstützung von der Sprachseite und man muss das "basteln". Gibts aber was dazu im Netz.

Wie irgendwo in diesem Thread erwähnt kannst Du aber auch einfach ein 1d-Array nehmen. In der FFTW-Hilfe steht auch was dazu.

Beispiel:


int *picArray = new int[imageHeight * imageWidth];
for(int y = 0; y < imageHeight; y++)
for(int x = 0; x < imageWidth; x++)
picArray[y * imageWidth + x] = getPixel(x, y);
[/PHP]

Danach hast Du dann Dein eigenes "2D-Array".

Geschrieben

Hmm, anscheinend doch nicht...

Folgende Quelle hab ich zu rate gezogen: 6.4 Dynamische Felder mittels Zeigervariablen

Allerdings klappt der Quellcode so nicht :(

int zeile, spalte, i;

double **b;	

[B]	b=new (double*[zeile]); [/B]     // Allocate row pointers

  for (i = 0; i < zeile; i++)

   {

[I][B]     b[i]=new double[spalte]; [/B] [/I]  // Allocate rows

   }
Der Compiler gibt mir den Fehler: "syntax error bevor double" bei den fett markierten Zeilen sowie die Warnung "Zuweisung von inkompatiblen Zeigertyp" bei der kursiv markierten Zeile. Obwohl der Code für mich eigentlich ziemlich einleuchtend klang! :( //Edit: Hmm, ok, das könnte man auch nehmen, ich spiel mal n kleines Programm durch um zu schauen, ob ich das auch wirklich verstanden hab! *grübel* //Edit 2: Ahhh, ich hatte nicht beachtet, dass der Code in C++ war. In C sieht das ganze dann also so aus:

int zeile, spalte, i;

double **b;	

	b= (double*) malloc(zeile*sizeof(double));      // Allocate row pointers

  for (i = 0; i < zeile; i++)

   {

     b[i]=(double*) malloc(spalte*sizeof(double));    // Allocate rows [Hier sind die Warnungen]

   } 

Gibt allerdings immernoch die Warnung:

"Zuweisung von inkompatiblen Zeigertyp" und

"unverträgliche implizite Deklaration der eingebauten Funktion <malloc>"

Geschrieben

Wie gesagt, bin da kein Profi, aber nachdem ich das Netz konsultiert hab würd ich es mal so probieren:


int zeile, spalte, i;
double **b;
b= (double**) malloc(zeile*sizeof(double*)); // Allocate row pointers
for (i = 0; i < zeile; i++)
{
*(b+i)=(double*) malloc(spalte*sizeof(double)); // Allocate rows [Hier sind die Warnungen]
}
[/PHP]

Andererseits erinnert mich der Code ein bisl an das "Anti-Beispiel" im fftw-Handbuch. Guck Dir vielleicht mal Kapitel 3.2 an.

FFTW3-Handbuch

Geschrieben

Stimmt natürlich!

Ich sollte das nächste mal wohl nicht nur das lesen, was mir direkt unter die Augen kommt. *rotwerd*

Zumal die Umsetzung so und so irgendwo einen fehler aufweisen muss, die Warnungen bleiben und es klappt nicht...

Nun gut, also doch das 1d Feld :D

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...