Probleme mit Bildverarbeitungsalgorithmus

kanonenfutter90

Grünschnabel
Schönen guten Abend :)

Folgendes Problem. Ich möchte eine einfache Funktion entwerfen, die aus einer Menge leicht verschiedener Bilder die Pixel raussucht, die in allen Bildern am häufigsten vorkommen. Als Bsp.:

Bild 1 | Bild 2 | Bild 3

11000 | 00000 | 00100
00000 | 00001 | 10000
00001 | 00001 | 10001

Ergebnisbild

00000
00000
00001

Es werden also im Ergebnisbild nur die Bestandteile verwendet, die anteilig am meisten ohne Veränderung in den Bildern vorkommen.

Kurze Codebeschreibung:
Ich lade 5 Bilder in das Programm und greife auf die Grauwerte jeden Bildes an einem Punkt x,y zu. Die 5 erhaltenen Grauwerte werden in das Array "feld" geschrieben. Über eine Zählschleife von 0 bis 255 laufe ich quasi alle möglichen Grauwerte ab, und sobald in "feld" ein Wert steht der mit der aktuellen Zahl übereinstimmt, wird in einem weiteren Feld an der Stelle des aktuellen Grauwertes dessen Inhalt um 1 erhöht. Ich zähle somit also das Vorkommen jedes Grauwerts an der Stelle x,y über alle Bilder. Anschließend schaue ich, welcher Grauwert dabei am häufigsten vorkam. Dieser soll dann an die aktuelle x,y Position des Ergebnisbilds gesetzt werden. Fertig ;)

Hoffe das war verständlich, Code steht nachfolgend vollständig wie er jetzt ist. Das Problem: Mein Ergebnisbild wird nicht vollständig abgearbeitet. Es sieht aus als würde das programm beim durchlaufen der x,y-Koordinaten einfach abbrechen. Außerdem wird der bis dorthin bearbeitete Bereich falsch berechnet, da dort überall ein einziger Grauwert steht, obwohl die Bilder viel Struktur haben...

Bin momentan am Ende, Debugging hilft mir auch nicht mehr weiter. Wäre nett wenn mal jmd. drüberschauen würde :)

Code:
#include "CImg.h"
using namespace cimg_library;

int main()
{
	CImg<int>img1("pic1.jpg");                  //Bilder laden
	CImg<int>img2("pic2.jpg");
	CImg<int>img3("pic3.jpg");
	CImg<int>img4("pic4.jpg");
	CImg<int>img5("pic5.jpg");
	CImgList<int>bilder(img1, img2, img3, img4, img5);  //zusammenfassung in liste

	CImg<int>erg(img1.width(), img1.height(), 1, img1.spectrum(), 0);   //ergebnisbild

	int p, x, y, i, j, neu, max = 0;
	int werte[256] = {0};                  
	
	const int anzahl = 5;					//Bilderanzahl
	int *feld = 0;							//neues Feld
	feld = new int [anzahl];					//mit dynamischer groesse

	for(y=0; y<img1.height(); y++)
	{
		for(x=0; x<img1.width(); x++)
		{
			for(p=0; p<anzahl; p++)
			{
				feld[p] = bilder[p](x,y,0,0);	//Feld mit werten aller bilder füllen (x,y)
			}

			for(i=0; i<256; i++)                     //grauwerte der bilder zuordnen
			{
				for(j=0; j<anzahl; j++)
				{
					if(feld[j] == i)
					{
						werte[i]++;         //je nach vorkommen an entsprechender stelle zähler erhöhen
					}
				}
			}

			neu = max = 0;

			for(i=0; i<256; i++)
			{
				if(werte[i] > max)         //häufigsten grauwert ermitteln
				{
					max = werte[i];
					neu = i;
				}				
			}

			erg(x,y,0,0) = neu;				//an bild übergeben
		}
	}

	CImgList<int>list(img1, img2, img3, img4, img5, erg); //ausgabe
	list.display("Test", false, 'x', 'c');

	return 0;
}

mfg
 
Hallo,

du musst werte bei jedem Pixel neu mit Nullwerten initialisieren, sonst akkumulierst du ja die Häufigkeiten aller bisher verwendeten Pixel auf.

Gibt es einen Grund, warum du das ganze so umständlich machst? Das Kopieren der Werte in feld und die anschließende Schleife über alle Farbwerte ist doch unnötig. Du kannst auch direkt die Werte aus den Bildern in der ersten Schleife zählen und den häufigsten Wert bestimmen:
C++:
neu = max = 0;
std::fill_n(werte, 256, 0);
for(p=0; p<anzahl; p++)
{
	int wert = bilder[p](x,y);
	if (++werte[wert] > max)
	{
		max = werte[wert];
		neu = wert;
	}
}
erg(x,y) = neu;

Grüße,
Matthias
 
Zuletzt bearbeitet von einem Moderator:
Moin,

erstmal ist das was du machst höchst uneffizient^^ Je nach Auflösung sind das eine Menge Operationen...
Schau dir mal die OpenCV Bibliothek an, die ist frei und bringt auch einen ImageContainer mit, mit dem man relativ effizient auf Pixel zugreifen kann. Ich hab abver auch eine eigene Template Klasse die Bilder schnell verarbeiten kann und dir Operatoren zur Verfügung stellt ;-) Kann ich dir mal bei gelegenheit posten, wenn du willst.

Was du wohl machen willst ist ein Histogrammvergleich...

Wenn du Hilfe brauchst meld dich einfach hier ;-)

Viele Grüße
RuFF

EDIT: PS: Hatte keine Zeit über den Coe zu schauen...
 
Hallo Matthias. Danke erstmal für deine Anregung. Habe gestern erstmal versucht meine Gedankengänge in Code zu fassen, daher ist es wahrscheinlich etwas zu viel. Tatsächlich ist dein Codekonstrukt vollkommen das was ich suche. Funktioniert ohne Probleme, danke dafür :)

@Ruff: Danke für Idee, aber ich bin bereits an die CImg-Library gebunden, da diese Funktion nur Teil eines größeren Programms wird, welches bereits fast fertig ist... ;)

mfg
 
Zurück