Verwendung von CImg und ImageMagick in C

kanonenfutter90

Grünschnabel
Abend.

Ich möchte mich in die Thematik der Bearbeitung von Bildern unter C/C++ einarbeiten. Bin diesbezgl. noch absoluter Neuling und habe daher erst mal die Suchmaschine bemüht. Bin dabei über "CImg" gestolpert, welches bereits einen Haufen an Funktionen bietet. Habe die entsprechenden Files also erstmal runtergeladen. Habe außerdem gelesen, dass ich, wenn ich Bilder in C mit Hilfe von CImg laden möchte, außerdem ImageMagick installieren muss. Hab ich also auch das erstmal getan.

Nun wollte ich mit einem Bsp.-Programm anfangen um in die Thematik reinzukommen. Dazu wollte ich folgenden Quellcode nutzen:
http://www.math.ucla.edu/~wittman/hyper/vick/Cimg_tutorial.pdf (Seite 3)

Bin nach der Anleitung (ab S. 2) vorgegangen. Zuerst also eine leere Konsolenanwendung erstellt, und dann die CImg.h eingefügt und eine neue CImg.cpp erstellt. In die .cpp habe ich dann den Quelltext aus dem Tutorial eingefügt (exakt so). beim compilen sagt er mir dann nach über 100 Errors, dass verschiedene Ausdrücke (memset, strcpy, getenv, etc...) "not a member of 'std'" sind.

Was mache ich falsch, oder habe ich vergessen? Auch nach includen der stdafx.h keine Änderung, steh leider grad echt aufm Schlauch.

Danke für Hilfe :)
 
Bin nach der Anleitung (ab S. 2) vorgegangen. Zuerst also eine leere Konsolenanwendung erstellt, und dann die CImg.h eingefügt und eine neue CImg.cpp erstellt. In die .cpp habe ich dann den Quelltext aus dem Tutorial eingefügt (exakt so). beim compilen sagt er mir dann nach über 100 Errors, dass verschiedene Ausdrücke (memset, strcpy, getenv, etc...) "not a member of 'std'" sind.
Welche Entwicklungsumgebung bzw. welchen Compiler verwendest du? Welche Fehlermeldungen erscheinen genau (bitte keine Prosa-Umschreibung sondern Zeichen für Zeichen die Ausgabe des Compilers)? Das Tutorial scheint nicht mehr ganz aktuell zu sein, die Methoden dimx() und dimy() heißen beispielsweise inzwischen width() und height(). Mit diesen Änderungen funktioniert folgender Quellcode mit meinem Visual Studio 2008 ohne Probleme:
C++:
#include "CImg.h" 
using namespace cimg_library; 
 
int main() {
  CImg<double> image("starwars.bmp");
  CImgDisplay main_disp(image,"Image",0);
  CImg<double> darkimage(image.width(),image.height(),1,3,0);

  for (int i=0;i<image.width();i++)
    for (int j=0;j<image.height();j++)
      for (int k=0;k<3;k++)
        darkimage(i,j,0,k)=image(i,j,0,k)/2;

  CImgDisplay dark_disp (darkimage,"Dark Image",0);
  while (!main_disp.is_closed())
    main_disp.wait();
  
  return 0; 
}

Grüße,
Matthias
 
Zuletzt bearbeitet von einem Moderator:
Danke für die Antwort.

Momentan verwende ich Visual Studio 6.0.

Hier mal die komplette Ausgabe nach den Kompilierungsversuch (mit deinem Quellcode):

Code:
Compiling...
CImg.cpp
...\test_3\cimg.h(1945) : error C2039: 'FILE' : is not a member of 'std'
...\test_3\cimg.h(1945) : error C2039: 'FILE' : is not a member of 'std'
...\test_3\cimg.h(3880) : error C2039: 'FILE' : is not a member of 'std'
...\test_3\cimg.h(3880) : error C2039: 'FILE' : is not a member of 'std'
...\test_3\cimg.h(3881) : error C2039: 'FILE' : is not a member of 'std'
...\test_3\cimg.h(3893) : error C2039: 'va_list' : is not a member of 'std'
...\test_3\cimg.h(3900) : error C2039: 'fprintf' : is not a member of 'std'
...\test_3\cimg.h(3915) : error C2039: 'memset' : is not a member of 'std'
...\test_3\cimg.h(3916) : error C2039: 'memset' : is not a member of 'std'
...\test_3\cimg.h(3929) : error C2039: 'system' : is not a member of 'std'
...\test_3\cimg.h(4055) : error C2039: 'fprintf' : is not a member of 'std'
...\test_3\cimg.h(4058) : error C2039: 'fprintf' : is not a member of 'std'
...\test_3\cimg.h(4061) : error C2039: 'fprintf' : is not a member of 'std'
...\test_3\cimg.h(4064) : error C2039: 'fprintf' : is not a member of 'std'
...\test_3\cimg.h(4066) : error C2039: 'fprintf' : is not a member of 'std'
...\test_3\cimg.h(4124) : error C2039: 'srand' : is not a member of 'std'
...\test_3\cimg.h(4124) : error C2660: 'srand' : function does not take 1 parameters
...\test_3\cimg.h(4125) : error C2039: 'rand' : is not a member of 'std'
...\test_3\cimg.h(4126) : error C2039: 'srand' : is not a member of 'std'
...\test_3\cimg.h(4126) : error C2039: 'rand' : is not a member of 'std'
...\test_3\cimg.h(4126) : error C2660: 'srand' : function does not take 1 parameters
...\test_3\cimg.h(4138) : error C2572: 'rol' : redefinition of default parameter : parameter 2
        ...\test_3\cimg.h(4138) : see declaration of 'rol'
...\test_3\cimg.h(4152) : error C2572: 'ror' : redefinition of default parameter : parameter 2
        ...\test_3\cimg.h(4152) : see declaration of 'ror'
...\test_3\cimg.h(4185) : error C2039: 'fabs' : is not a member of 'std'
...\test_3\cimg.h(4188) : error C2039: 'fabs' : is not a member of 'std'
...\test_3\cimg.h(4191) : error C2039: 'abs' : is not a member of 'std'
...\test_3\cimg.h(4202) : error C2039: 'log10' : is not a member of 'std'
...\test_3\cimg.h(4263) : error C2039: 'sin' : is not a member of 'std'
...\test_3\cimg.h(4320) : error C2039: 'rand' : is not a member of 'std'
...\test_3\cimg.h(4336) : error C2039: 'sqrt' : is not a member of 'std'
...\test_3\cimg.h(4336) : error C2039: 'log' : is not a member of 'std'
...\test_3\cimg.h(4342) : error C2039: 'sqrt' : is not a member of 'std'
...\test_3\cimg.h(4344) : error C2039: 'exp' : is not a member of 'std'
...\test_3\cimg.h(4368) : error C2039: 'sqrt' : is not a member of 'std'
...\test_3\cimg.h(4369) : error C2039: 'sqrt' : is not a member of 'std'
...\test_3\cimg.h(4392) : error C2039: 'sscanf' : is not a member of 'std'
...\test_3\cimg.h(4415) : error C2039: 'strlen' : is not a member of 'std'
...\test_3\cimg.h(4415) : error C2039: 'strlen' : is not a member of 'std'
...\test_3\cimg.h(4422) : error C2039: 'strlen' : is not a member of 'std'
...\test_3\cimg.h(4430) : error C2039: 'memmove' : is not a member of 'std'
...\test_3\cimg.h(4452) : error C2039: 'sscanf' : is not a member of 'std'
...\test_3\cimg.h(4455) : error C2039: 'sscanf' : is not a member of 'std'
...\test_3\cimg.h(4474) : error C2039: 'strchr' : is not a member of 'std'
...\test_3\cimg.h(4483) : error C2039: 'rand' : is not a member of 'std'
...\test_3\cimg.h(4484) : error C2039: 'rand' : is not a member of 'std'
...\test_3\cimg.h(4484) : error C2296: '%' : illegal, left operand has type 'double'
...\test_3\cimg.h(4484) : error C2039: 'rand' : is not a member of 'std'
...\test_3\cimg.h(4484) : error C2296: '%' : illegal, left operand has type 'double'
...\test_3\cimg.h(4484) : error C2039: 'rand' : is not a member of 'std'
...\test_3\cimg.h(4484) : error C2296: '%' : illegal, left operand has type 'double'
...\test_3\cimg.h(4494) : error C2039: 'strcpy' : is not a member of 'std'
...\test_3\cimg.h(4511) : error C2039: 'memset' : is not a member of 'std'
...\test_3\cimg.h(4512) : error C2039: 'strncpy' : is not a member of 'std'
...\test_3\cimg.h(4515) : error C2039: 'memset' : is not a member of 'std'
...\test_3\cimg.h(4518) : error C2039: 'FILE' : is not a member of 'std'
...\test_3\cimg.h(4520) : error C2039: 'getenv' : is not a member of 'std'
...\test_3\cimg.h(4521) : error C2039: 'getenv' : is not a member of 'std'
...\test_3\cimg.h(4522) : error C2039: 'fopen' : is not a member of 'std'
...\test_3\cimg.h(4522) : error C2039: 'fclose' : is not a member of 'std'
...\test_3\cimg.h(4522) : error C2039: 'remove' : is not a member of 'std'
...\test_3\cimg.h(4524) : error C2039: 'fopen' : is not a member of 'std'
...\test_3\cimg.h(4524) : error C2039: 'fclose' : is not a member of 'std'
...\test_3\cimg.h(4524) : error C2039: 'remove' : is not a member of 'std'
...\test_3\cimg.h(4525) : error C2039: 'fopen' : is not a member of 'std'
...\test_3\cimg.h(4525) : error C2039: 'fclose' : is not a member of 'std'
...\test_3\cimg.h(4525) : error C2039: 'remove' : is not a member of 'std'
...\test_3\cimg.h(4526) : error C2039: 'fopen' : is not a member of 'std'
...\test_3\cimg.h(4526) : error C2039: 'fclose' : is not a member of 'std'
...\test_3\cimg.h(4526) : error C2039: 'remove' : is not a member of 'std'
...\test_3\cimg.h(4527) : error C2039: 'fopen' : is not a member of 'std'
...\test_3\cimg.h(4527) : error C2039: 'fclose' : is not a member of 'std'
...\test_3\cimg.h(4527) : error C2039: 'remove' : is not a member of 'std'
...\test_3\cimg.h(4528) : error C2039: 'fopen' : is not a member of 'std'
...\test_3\cimg.h(4528) : error C2039: 'fclose' : is not a member of 'std'
...\test_3\cimg.h(4528) : error C2039: 'remove' : is not a member of 'std'
...\test_3\cimg.h(4529) : error C2039: 'fopen' : is not a member of 'std'
...\test_3\cimg.h(4529) : error C2039: 'fclose' : is not a member of 'std'
...\test_3\cimg.h(4529) : error C2039: 'remove' : is not a member of 'std'
...\test_3\cimg.h(4530) : error C2039: 'fopen' : is not a member of 'std'
...\test_3\cimg.h(4530) : error C2039: 'fclose' : is not a member of 'std'
...\test_3\cimg.h(4530) : error C2039: 'remove' : is not a member of 'std'
...\test_3\cimg.h(4531) : error C2039: 'fopen' : is not a member of 'std'
...\test_3\cimg.h(4531) : error C2039: 'fclose' : is not a member of 'std'
...\test_3\cimg.h(4531) : error C2039: 'remove' : is not a member of 'std'
...\test_3\cimg.h(4538) : error C2039: 'strncpy' : is not a member of 'std'
...\test_3\cimg.h(4539) : error C2039: 'fopen' : is not a member of 'std'
...\test_3\cimg.h(4539) : error C2039: 'fclose' : is not a member of 'std'
...\test_3\cimg.h(4539) : error C2039: 'remove' : is not a member of 'std'
...\test_3\cimg.h(4554) : error C2039: 'memset' : is not a member of 'std'
...\test_3\cimg.h(4555) : error C2039: 'strncpy' : is not a member of 'std'
...\test_3\cimg.h(4558) : error C2039: 'memset' : is not a member of 'std'
...\test_3\cimg.h(4562) : error C2039: 'getenv' : is not a member of 'std'
...\test_3\cimg.h(4563) : error C2039: 'strncpy' : is not a member of 'std'
...\test_3\cimg.h(4564) : error C2039: 'strcpy' : is not a member of 'std'
...\test_3\cimg.h(4580) : error C2039: 'memset' : is not a member of 'std'
...\test_3\cimg.h(4581) : error C2039: 'strncpy' : is not a member of 'std'
...\test_3\cimg.h(4584) : error C2039: 'memset' : is not a member of 'std'
...\test_3\cimg.h(4586) : error C2039: 'FILE' : is not a member of 'std'
...\test_3\cimg.h(4590) : error C2039: 'strcpy' : is not a member of 'std'
...\test_3\cimg.h(4591) : error C2039: 'fopen' : is not a member of 'std'
...\test_3\cimg.h(4591) : error C2039: 'fclose' : is not a member of 'std'
...\test_3\cimg.h(4591) : fatal error C1003: error count exceeds 100; stopping compilation
Error executing cl.exe.

test_3.exe - 102 error(s), 0 warning(s)

mfg
 
Hallo.

Habe es nun also mal mit Visual Studio 2010 probiert, klappt alles auch wunderbar, danke für den Tip :)

Nun gleich zur nächsten Frage. Kann ich die CImg Library nur für Konsolenanwendungen nutzen? Ich habe versucht diese in einer Windows Forms Anwendung einzubinden (möchte mit den Bildern in einem normalen Windows Fenster, mit Buttons etc., arbeiten). Dort bekomme ich allerdings Fehlermeldungen:

Code:
1>------ Erstellen gestartet: Projekt: test, Konfiguration: Debug Win32 ------
1>  test.cpp
1>...\test\CImg.h(7858): error C3641: "cimg_library::CImgDisplay::_handle_events": Ungültige Aufrufkonvention "__stdcall " für eine Funktion, die mit /clr:pure oder /clr:safe kompiliert wurde.
1>...\test\CImg.h(7968): error C3641: "cimg_library::CImgDisplay::_events_thread": Ungültige Aufrufkonvention "__stdcall " für eine Funktion, die mit /clr:pure oder /clr:safe kompiliert wurde.
1>...\test\CImg.h(8111): error C2664: 'CreateThread': Konvertierung des Parameters 3 von 'DWORD (__stdcall *)(void *)' in 'LPTHREAD_START_ROUTINE' nicht möglich
1>          Die Adresse einer Funktion liefert die __clrcall-Aufrufkonvention in /clr:pure und /clr:safe. Verwenden Sie evtl. __clrcall im Zieltyp.
========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========

Habe die CImg Headerdatei wie gewohnt dem Projekt hinzugefügt und diese in der Hauptprojektdatei (test.cpp) included.

Vllt. hab ich auch etwas übersehen oder falsch gemacht, da die 2010er Version erstmal etwas anders ist... ;)

Danke schonmal für Rückmeldungen :)

mfg
 
Hallo, sry das ich mich nicht immer sofort melde, hab nur unregelmäßigen Internetzugang zur Zeit...

Zum Thema: Also ich werde wohl auf eine grafische Oberfläche ala Windows Forms etc. verzichten und das ganze als Konsolenanwendung aufziehen. Da kann ich dank der CImg Bibliothek das ganze auch ganz gut grafisch aufbereiten.. ;)

Jedenfalls hab ich nun noch ein weiteres Problem:
Ich habe nun eine einfache Binarisierung realisiert. Heißt ich lade ein RGB Bild, wandel dieses in Graustufen um und Binarisiere dieses dann mit einem bis jetzt festen Schwellwert. Alle drei Bilder werden anschließend in einer ImgList ausgegeben.

Ich wollte nun noch ein weiteres Fenster erstellen, in dem ein Balken gezeigt wird mit dem man den Schwellwert während der Laufzeit ändern kann und sich das binarisierte Bild entsprechend aktualisiert. Die prinzipielle Idee habe ich von hier: http://cimg.cvs.sourceforge.net/cimg/CImg/examples/CImg_demo.cpp?view=markup (Zeile 149 bis 174).

Bei meiner bisherigen Implementierung des ganzen bekomme ich zwar meine 3 Bilder und den Balken etc., kann aber nicht die Grauwertschwelle anpassen, der Balken bleibt beim voreingestellten Grauwert. Wie ich anschließend nur das Binarisierte Bild aktualisieren kann, weiß ich bis jetzt auch nicht wirklich :/

Ach ja, hier mein bisheriger Code zur Thematik:
Code:
#include "CImg.h"
using namespace cimg_library;

/////////////////////////////////////////////////////////////////////////////////BINARISIERUNG///

int main()
{
	CImg<double> image("lena.jpg");
	CImg<double> greyimage(image.width(),image.height(),1,3,0);
	CImg<double> binimage(image.width(),image.height(),1,3,0);

	CImg<double>slider(600, 50, 1, 3, 0);
	
//	list_disp.resize(list_disp.screen_width()-20, (list_disp.screen_width()-20)*0.25, true); //Ausgabegröße an Bildschirm anpassen

	double	valR = 0;
	double	valG = 0;
	double	valB = 0;
	double	avg  = 0;
	int		gwin = 128;		//Grauwertgrenze

	const unsigned char white[] = {255,255,255};	
	const unsigned char blue[] = {0,0,255};	
	const unsigned char lblue[] = {0,0,192};	
	const unsigned char dblue[] = {0,0,128};

	CImgDisplay slide_disp(slider, "Grauwertschwelle einstellen");//, list_disp(bin_disp, "Binarisierung");

while(!slide_disp.is_closed() && !slide_disp.is_keyESC())// && !list_disp.is_closed())
{

	slider.fill(0).draw_text(10, 10, "%d", white, 0, 1, 32, gwin); //Grauwert ausgeben
	const int xb = 70 + (gwin*2); //Balkengröße umrechnen
	slider.draw_rectangle(68, 13, 582, 37, lblue, 1).draw_rectangle(69, 14, 581, 36, dblue, 1).draw_rectangle(70, 15, xb, 35, blue, 1); //Balken je nach Grauwert
	
	
	for(int x = 0; x < image.width(); x++)		//Schleife über x,y und Farbkanal
	{
		for(int y = 0; y < image.height(); y++)
		{
			for(int v = 0; v < image.spectrum(); v++)
			{
				valR = image(x,y,0,0);					// Read the red component
				valG = image(x,y,0,1);					// Read the green component
				valB = image(x,y,2);					// Read the blue component (Z


				avg = (valR + valG + valB)/3;			// Compute average pixel value.

				greyimage(x,y,0) = greyimage(x,y,1) = greyimage(x,y,2) = avg;	//Graubild
				
				if(avg>=gwin)			//Binarisierung
				{
					binimage(x,y,0) = binimage(x,y,1) = binimage(x,y,2) = 255;
				}
				else binimage(x,y,0) = binimage(x,y,1) = binimage(x,y,2) = 0;

			}
		}
	}			

//		slide_disp.resize(slide_disp, true).display(slider); //Aktualisierung
	if(slide_disp.button() && slide_disp.mouse_x()>=70 && slide_disp.mouse_x()<=580) // bei KLick in Balkenregion
	{
		gwin = (int)((slide_disp.mouse_x()-70) / 2); // neuer GW			
	}
		
	slide_disp.resize(slide_disp, false).display(slider);
	CImgList<unsigned char>bin_disp(image, greyimage, binimage);	//Ausgabe
	bin_disp.display("Test", false, 'x', 'c');
}

Vllt. kennt sich hier ja jmd. mit CImg aus oder hat auch so eine gute Idee :)

mfg
 
Zurück