Bitmap-Bilder einlesen, bearbeiten und erzeugen



  • Guten Tag liebe Community,

    ich bin grad an ein Programm dran mit dem ich ein Bitmap-Bild einlese und mit zwei weiteren Bitmap-Bildern sozusagen bearbeite um ein neues zu erhalten. Dieses Bild soll das erzeugt werden. Leider will das nicht funktionieren und mein Programm beendet direkt bei der Ausführung.

    Ich würde mich bei Unterstützung ziemlich freuen

    Hier ist mein Code:

    #include <stdio.h>
    #include <math.h>
    #include <stdlib.h>
    
    void getPixel();
    double getMittelwert();
    int array[100][150];
    
    int main () {
    
        FILE *weiss;
        FILE *schwarz;
        FILE *AS1;
        //FILE *AS2;
        //FILE *AS3;
        FILE *Erzeugung1;
    
        int PicWeiss[100][150];
    	int PicSchwarz[100][150];
    
    	int PicAS1[100][150];
    	//int PicAS2[100][150];
        //int PicAS3[100][150];
    
    	int PicProto1[100][150];
    	//int PicProto2[100][150];
    	//int PicProto3[100][150];
    
        char header[1078];
        char tmpString[12]={'0','0','0','0','k','o','r','r','.','b','m','p'};
    
        int i;
        int w;
        int h;
    
        double GrauStufenMittelwert = 0;
    
        printf("\n\t>Wilkommen den Astronomischen SW-Bildern<\n\n\n ");
    
        //Standartbildert Schwarz und Weiss
        weiss = fopen("white.bmp","r");
    	if (weiss == NULL) {
                printf("Die Datei White.bmp wurde NICHT gefunden!\n");
    	} else {
                printf("\n");
                printf("Die Datei white.bmp wurde gefunden.\n\n");
                getPixel(weiss);
                GrauStufenMittelwert = getMittelwert();
                memcpy(weiss, array, sizeof(weiss));
    	}
    
        schwarz = fopen("dark.bmp","r");
    	if (schwarz == NULL) {
                printf("Die Datei dark.bmp wurde NICHT gefunden!\n\n");
    	} else {
                printf("Die Datei dark.bmp wurde gefunden.\n\n");
                getPixel(schwarz);
                GrauStufenMittelwert = getMittelwert();
                memcpy(schwarz, array, sizeof(schwarz));
    	}
    
    	//Astronomische Bilder
        AS1 = fopen("0221.bmp","r");
    	if (AS1 == NULL) {
                printf("Das Astronomische Bild wurde nicht gefunden!\n\n");
    	} else {
                printf("Das 1. Astronomische Bild wurde gefunden.\n\n");
    	}
    
        AS2 = fopen("0344.bmp","r");
    	if (AS2 == NULL) {
                printf("Das Astronomische Bild wurde nicht gefunden!\n\n");
    	} else {
                printf("Das 2. Astronomische Bild wurde gefunden.\n\n");
    	}
    
    	    AS3 = fopen("3198.bmp","r");
    	if (AS3 == NULL) {
                printf("Das Astronomische Bild wurde nicht gefunden!\n\n");
    	} else {
                printf("Das 3. Astronomische Bild wurde gefunden.\n\n");
    	}
    
    //Einsatz !!!!!!!!
    
    		//@todo überprüfen der Eingaben
    
    		AS1=fopen(AS1,"r");
    		getPixel(AS1);
    		memcpy(PicAS1, array, sizeof(PicAS1));
    
    		for(h=0; h<150; h++){
    			for(w=0; w<100; w++){
    				 PicProto1[w][h] = PicAS1[w][h] - PicSchwarz[w][h];
    				 if (PicProto1[w][h] < 0 ) PicProto1[w][h] = 0;
    				 PicProto1[w][h] = round( (PicProto1[w][h] * GrauStufenMittelwert) / PicWeiss[w][h] );
    			}
    		}
    
    		strncpy(tmpString, AS1, 4);
    		printf("%s",tmpString);
    		Erzeugung1 = fopen( tmpString, "a+");
    
    		rewind(AS1);
    		printf("\n\n\n");
    		for(i=0;i<1078;i++){
    		//@todo UserFiles Header in das Header Array Schreiben
    			fputc(fgetc(AS1),Erzeugung1);
    		}
    
    		//fputs(header,PicTemp);
    		for(h=0; h<150; h++){
    			for(w=0; w<100; w++){
    				  fputc(PicProto1[w][h],Erzeugung1);
    			}
    		}
    		fputc(0,Erzeugung1);
    		fputc(0,Erzeugung1);
    
    		fclose(AS1);
    		fclose(Erzeugung1);
    
    	fclose(PicSchwarz);
    	fclose(PicWeiss);
    
    //Einsatz ENDE !!!!!!
    
         return 0 ;
     }
    
    void getPixel(FILE *bild){
    
    	int w, h;
    	fseek(bild,1078,SEEK_SET);
    	for(h=0; h<150; h++){
    		for(w=0; w<100; w++){
    			 array[w][h] = fgetc(bild);
    		}
    	}
    }
    
    double getMittelwert(){
    
    	int h,w;
    	double e = 0;
    	for(h=0; h<150; h++){
    		for(w=0; w<100; w++){
    			 e = e + array[w][h];
    		}
    	}
    	return e / (100*150);
    }
    


  • Aktiviere mal die Warnugen im compiler, bei mir sind es 11!

    AS1=fopen(AS1,"r");
    

    Da hast du wohl was verwechselt.



  • habe nun das den Bildnamen dort eingesetzt aber trotzdem wird mir ein Fehler angezeigt. Die mir als nicht ernsthaft angezeigten Fehler leuchten mir irgendwie nicht ein



  • 1. implicit declaration of function 'memcpy':
    Du hast string.h nicht eingebunden
    2. AS2 undeclared:
    Du hast AS2 auskommentiert
    3. implicit declaration of function 'strncpy':
    Auch string.h

    strncpy(tmpString, AS1, 4);
    

    Du kopierst einen filepointer in tmpString???

    fclose(PicSchwarz);
    fclose(PicWeiss);
    

    ??????

    char header[1078];
    

    header ist unused.



  • habe nun einige Sachen geändert aber mir wird nur eine leere Datei ausgegeben die den Namen "[5" trägt. Und ja hattest recht habe direkt die string.h eingebunden aber wieso sollte das denn falsch sein mit dem filepointer im string ?



  • Was gibt dir denn dieses printf in Zeile 116 aus?

    printf("%s",tmpString);
    


  • sie gibt "0000korr.bmp" aus. Also ich muss wie bereits erwähnt ein Bild bearbeiten mithilfe eines komplett weissen und schwarzen Bildes. Das bearbeitete Bild am ende soll dann unter korr.bmp abgespeichert werden. Deswegen auch meine Handlungsweise wenn es falsch habe ich es unabsichtlich gemacht.



  • Ich glaube dein Problem liegt hier:

    Erzeugung1 = fopen( tmpString, "a+");
    

    Cobain schrieb:

    Das bearbeitete Bild am ende soll dann unter korr.bmp abgespeichert werden.

    Warum speicherst du es dann nicht unter korr.bmp ab?

    Erzeugung1 = fopen("korr.bmp", "a+");
    


  • danke habe nun wenigstens eine Bitmap Datei, jedoch habe ich vergessen noch dazu zu erwähnen, dass der Namen der Datei die bearbeitet wird mit übernommen wird und vor dem korr.bmp eingesetzt wird.

    Z.b. heisst die Datei "blau" dann wird die erzeugte Datei "blaukorr" heissen.

    Was mir aber nun anhand der soeben erzeugten Bitmap-Datei auffiel ist, dass die Berechnung irgendwie falsch ist.

    Es wird mir ein fast schwarzes Bild angezeigt mit wirklich abzählbaren Weißpunkten. Das zu erzeugende Bild soll schon so aussehen als ob man nachts in den Himmel schaut und Sterne sieht.



  • Das ist übrigens die Aufgabe die ich realisieren muss anhand meines Programms.

    • Alle Bilder sind im Bitmap-Format (.bmp) gespeichert bzw. zu speichern. Die 150x100 Bildpixel sind im Anschluss an einen nicht näher betrachteten Vorspann ab Dateiposition 0x436 (1078 dezimal) zeilenweise gespeichert. Die Bytes 0 bis 0x435 (1077 dezimal) der astronomischen Rohbilddateien müssen unverändert in die Ausgabebilddatei übertragen werden. An die korrigierte Bildinformation sind zwei Füllbytes (Wert = 0) anzuhängen.



  • Cobain schrieb:

    danke habe nun wenigstens eine Bitmap Datei, jedoch habe ich vergessen noch dazu zu erwähnen, dass der Namen der Datei die bearbeitet wird mit übernommen wird und vor dem korr.bmp eingesetzt wird.

    char tmpString[13]={'0','0','0','0','k','o','r','r','.','b','m','p','\0'};
    /* String muss Null-terminiert werden. */
    char tmp[5]={'b','l','a','u','\0'};
    int i;
    
    for (i=0;i<4;i++)
        tmpString[i] = tmp[i];
    

    Ungetestet.
    edit: korrigiert.



  • Bitmapper schrieb:

    char tmpString[13]={'0','0','0','0','k','o','r','r','.','b','m','p','\0'};
    /* String muss Null-terminiert werden. */
    char tmp[5]={'b','l','a','u','\0'};
    int i;
    
    for (i=0;i<5;i++)
        tmpString = tmp[i];
    

    Ungetestet.*

    Ungetestet merkt man. So kannst du auch gleich strcpy benutzen, weil die '\0' mitkopiert wird. Und somit nur das [i]blau sichtbar isr
    Das strncpy ist schon in Ordnung.

    Sinnvoller ist allerdings, den Compiler die Arbeit machen zu lassen:

    char tmpString[] = "0000korr.bmp"
    


  • Hey Leute,

    Ich schreibe mal hier, weil ich exakt die gleiche Aufgabe Programmiere.

    Die Aufgabenstellung ist:

    Ihr Programm soll mit einer SW_Messkamera aufgenommene astronomische Pixelbilder verarbeiten, Zur astronmischen Auswertung müssen die aufgenommenen Rohbilder zunächst eine Fehlerkorrektur durchlaufen, d.h die Pixelfehler des CCD-Sensorchips müssen aus dem Rohbld herausgerechnet werden. Dazu werden ein sogennantes Dunkelbild und ein WeißBild benötigt.

    So hier mal mein Code zum einlesen der Werte:

    	unsigned char header[1078],pixeldark[150][100],pixelwhite[150][100],pixelraw[150][100];
    	double result[150][100];
    	double graustufenmittelwert=0;
    	int i=0,x=0,y=0;
    
    
    	if(argc <=5)
    		fprintf(stderr,"Keine Argumente!\n"),exit(0);
    	else
    		printf("Argumente wurden gefunden!\n");
    
    	AS1 = fopen(argv[1],"rb");
    	AS2 = fopen(argv[2],"rb");
    	white = fopen(argv[5],"rb");
    	dark = fopen(argv[4],"rb");
    
    
    	if(AS1 == NULL || white == NULL || dark == NULL || AS2 == NULL)
    		fprintf(stderr,"Datei konnte nicht geöffnet werden!\n"),exit(0);
    	else
    	 printf("Datei wurde geoffnet!\n");
    
    
    
    
    
    	getPixel(dark,header,&pixeldark[0][0]);
    	getPixel(white,header,&pixelwhite[0][0]);
    	getPixel(AS2,header,&pixelraw[0][0]);
    	graustufenmittelwert = getMittelwert(&pixelwhite[0][0]);
    
    void getPixel(FILE *bild,unsigned char *Vorspann,unsigned char *array)
    {
    	int i =0,x=0,y=0;
    	unsigned int width,height;
    
    	for(i = 0; i < 1078; ++i){
    		Vorspann[i] = fgetc(bild);}
    
    		if(Vorspann[0] != 'B' || Vorspann[1] != 'M'){
    			printf("Es ist keine BMP Datei!\n"),exit(0);}
    		else
    		{
    			printf("Es handelt sich um eine BMP Datei!\n");
    		}
    
    	width = (int)Vorspann[0x12];
    	height = (int)Vorspann[0x16];
    
    
    
    
    	fseek(bild,0x436,SEEK_SET);
    
    	for(x = 0; x < height; x++)
    	{
    		for(y = 0; y < width; y++)
    		{
    			*(array + x* width + y) = fgetc(bild);
    		}
    	}
    
    
    }
    
     ...EInlesen der Rohwerte und Trennung der Header …
    

    Als nächstes soll folgendes gemacht werden:

    1.das Dunkelbild vom astronomischen Rohbild pixelweise abziehen,

    2.das so korrigierte Bild Pixelweise durch das Weißbild dividieren und

    1. das so korrigierte Bild pixelweise mit dem Graustufenmittelwert des Weißbildes multipilzieren.

    Achten sie bei der Division durch das Weißbild sowie bei der Berechnung des Mittelwertes auf double Typ und runden sie mit round auf!

    	int x=0,y=0;
    
    	for(x = 0; x < 150; ++x)
    	{
    		for(y = 0; y < 100; ++y)
    		{
    			mittelwert += *(whitepic + x*100 +y);
    		}
    	}
    
    	mittelwert /= (100*150);
    
     ... Mittelwert ... 
    ```for(x = 0; x < 150; x++)
    	{
    		for(y = 0; y < 100; y++)
    		{
    			result[x][y] = pixelraw[x][y] - pixeldark[x][y];
    
    			result[x][y] /= (double)pixelwhite[x][y];
    			result[x][y] *= graustufenmittelwert;
    			result[x][y] = round(result[x][y]);
    
    			if(result[x][y] < 0) result[x][y] *=-1;
    		}
    	}
    
    ```Fehlerkorrektur
    ich bin vom Ergebnis nicht wirklich beindrucht. Kann mir jemand mal meine Fehler nennen oder ob überhaupt was falsch ist!
    
    Mit freundlichen Grüßen
    yberion45


  • ich bin vom Ergebnis nicht wirklich beindrucht

    Das beschreibt dein Problem ja sehr ausführlich...



  • @manni66
    Meine Frage ist ganz einfach.

    1. Ist das Einlesen richtig?
    2. Ist die Rechnung richtig, wenn nein, was ist falsch dran?

    Ich weiß nicht mal wie das Ergebnis aussehen soll. Habe lediglich ein White bild bekommen, ein dark bild und die Astronomischen Bilder und die Beschreibung was zu tun ist. Also bleibt mir nichts anderes übrig, als penibel die Arbeitsschritte umzusetzen. Deswegen frage ich ob diese Zwei Punkte richtig umgesetzt sind. Aus mehr besteht die Aufgabe nicht. Von dem Thread Hersteller ist der Code definitiv mal komplett falsch



  • Jetzt habe ich eine ganz konkrete Frage.

    Nach dem ich das Dunkelbild vom astronomischen Bild pixelweise abgezogen habe, was mache ich mit den entstehenden Minuswerten? Ich vermute sie werden invertiert. Benutzt man da , dass zweierkompliment?


  • Mod

    @yberion45 sagte in Bitmap-Bilder einlesen, bearbeiten und erzeugen:

    Nach dem ich das Dunkelbild vom astronomischen Bild pixelweise abgezogen habe, was mache ich mit den entstehenden Minuswerten? Ich vermute sie werden invertiert. Benutzt man da , dass zweierkompliment?

    Da gibt es keine programmiertechnische Antwort drauf, da muss man mitdenken, wie das Ding wohl funktioniert. Da das eine Übungsaufgabe ist und kein echtes Gerät, gibt es keine richtige Antwort. Wenn man aber mal überlegt, wie so ein Sensor wohl funktioniert, und mal auch damit vergleicht, wie handelsübliche Kameras funktionieren, dann: Nein, da sollte man gewiss nicht invertieren. Wenn du sagst, dass Werte unter 0 besonders hellen Werten entsprechen, dann hieße das ja, dass dein Sensor überlaufen kann. Hast du jemals eine Kamera gesehen, bei der eine Lichtquelle wieder schwarz wird, wenn sie zu hell ist? Ich nicht. Es wäre ziemlicher Unsinn, einen Kamerasensor so zu konstruieren.



  • @seppj so, da ich mich mit sowas nicht auskenne, heißt das Konkret? Werte unter 0 wird es nicht geben da die Farbe Schwarz 0 ist. Was mache ich mit den negativen Werten?

    oder habe ich mich verrechnet? oder kommt das durch falsches Einlesen?

    also ich habe zum Test die orginal Datei eingelesen und dann getrennt und wieder zusammen gesetzt und das Orginal Bild kam wieder raus. Daher denke ich, dass es richtig ist. Ich lese in ein char Array ein. Ich würde die negativen Werte alle zu 0 machen, was mir so einfällt.

    Muss man die ausgelesenen Werte in RGB Werte umwandeln um dann eventuell zu rechnen?

    {
    	int x=0,y=0;
    	double z1[150][100],z2[150][100];
    
    	for(x = 0; x < 150; x++)
    	{
    		for( y = 0; y < 100; y++)
    		{
    			z1[x][y] = *(pixeldark + x*100 + y);
    			z2[x][y] =*(pixelraw + x * 100 + y);
    			z2[x][y] -= z1[x][y];					// Überlegen was mit negativen Werten zu machen ist!
    
    		}
    	}
    
    	for(x = 0; x < 150; x++)
    	{
    		for( y = 0; y < 100; y++)
    		{
    			printf("%.2lf\t",z2[x][y]);
    
    		}
    		putchar('\n');
    	}
    
    
    }
    
    
     ...1 Rechnung ... 
    

    Das Würde ich drunter setzen:

     ... Code ... 
    if(z2[x][y] < 0) z2[x][y] =0;
    

    Ich habe grad mal geschaut, die Werte die er mir anzeigt sind RGB Werte, und es gibt keine Negativen Werte somit würde ich behaupten, dass die negativen Werte zu 0 werden. Das wäre mein logisches Mitdenken eventuell füge ich mal orginal Bild später ein und zeige mal was dabei rauskommt
    So würde meine Komplette Berechnung aussehen:

     ... Code ... 
    	for(x = 0; x < 150; x++)
    	{
    		for( y = 0; y < 100; y++)
    		{
    			z1[x][y] = *(pixeldark + x*100 + y);
    			z2[x][y] =*(pixelraw + x * 100 + y);
    			z2[x][y] -= z1[x][y];					// negative Werte werden zu 0, Rohbilddaten -Rohwerte schwarz
    			if(z2[x][y] < 0) z2[x][y] =0;
    
    		}
    	}
    
    	for(x = 0; x < 150; x++)
    	{
    		for(y = 0; y < 100; y++)
    		{
    			z2[x][y] /=(double)*(pixelwhite + x *100 +y); //division durch Rohwerte vom weißen Bild
    			z2[x][y] *= getMittelwert(pixelwhite);   //Mal den Mittelwert eventuell hier ein Fehler? alle Werte von weißen Rohbild addiert und durch 100*150 geteilt;
    			z2[x][y] = round(z2[x][y]);    //ganz Zahlen auf oder abrunden
    
    		}
    	}
    


  • So hab den Code mal fertig geschrieben und hoffe jetzt auf sachliche Hilfe.
    Ich füge auch die Bilder vom Orginal und der Erzeugten Datei hinzu. Bitte mir mögliche Fehler nennen. Ich wäre euch so dankbar!

     ... Code ... 
    int main(int argc,char *argv[])
    {
    	FILE *AS1,*white,*dark,*AS2;
    	unsigned  char header[1078];
    	unsigned char pixeldark[150][100],pixelwhite[150][100],pixelraw[150][100];
    	BYTE pixeledit[150][100];
    
    
    	if(argc <=5)
    		fprintf(stderr,"Keine Argumente!\n"),exit(0);
    	else
    		printf("Argumente wurden gefunden!\n");
    
    	AS1 = fopen(argv[1],"rb");
    	AS2 = fopen(argv[2],"rb");
    	white = fopen(argv[5],"rb");
    	dark = fopen(argv[4],"rb");
    
    
    	if(AS1 == NULL || white == NULL || dark == NULL || AS2 == NULL)
    		fprintf(stderr,"Datei konnte nicht geöffnet werden!\n"),exit(0);
    	else
    	 printf("Datei wurde geoffnet!\n");
    
    	getPixel(dark,header,&pixeldark[0][0]);
    	getPixel(white,header,&pixelwhite[0][0]);
    	getPixel(AS2,header,&pixelraw[0][0]);
    	ImageEdit(&pixelraw[0][0],&pixelwhite[0][0],&pixeldark[0][0],&pixeledit[0][0]);
    	createPic(&pixeledit[0][0],header);
    
    	fclose(AS1);
    	fclose(AS2);
    	fclose(white);
    	fclose(dark);
    	return 0;
    }
    
    void getPixel(FILE *bild, unsigned char *Vorspann,  unsigned char *array)
    {
    	int i =0,x=0,y=0;
    	unsigned int width,height;
    
    
    	for( i = 0; i < 1078; ++i){
    		Vorspann[i] = fgetc(bild);}
    
    		if(Vorspann[0] != 'B' || Vorspann[1] != 'M'){
    			printf("Es ist keine BMP Datei!\n"),exit(0);}
    		else
    		{
    			printf("Es handelt sich um eine BMP Datei!\n");
    		}
    
    	width = (int)Vorspann[0x12];
    	height = (int)Vorspann[0x16];
    
    
    
    	fseek(bild,0x436,SEEK_SET);
    
    	for(x = 0; x < height; x++)
    	{
    		for(y = 0; y < width; y++)
    		{
    
    			*(array + x* width + y) = fgetc(bild);
    		}
    	}
    
    
    
    
    
    
    
    }
    
    double getMittelwert(unsigned char *whitepic)
    {
    	double mittelwert=0;
    	int x=0,y=0;
    
    	for(x = 0; x < 150; ++x)
    	{
    		for(y = 0; y < 100; ++y)
    		{
    			mittelwert = mittelwert + *(whitepic + x*100 +y);
    		}
    	}
    
    	mittelwert = mittelwert/ (150*100);
    
    	return mittelwert;
    }
    
    void ImageEdit( unsigned char * pixelraw, unsigned char *pixelwhite,unsigned char *pixeldark,BYTE *pixeledit)
    {
    	int x=0,y=0;
    	double z1[150][100],z2[150][100];
    
    	for(x = 0; x < 150; x++)
    	{
    		for( y = 0; y < 100; y++)
    		{
    			z1[x][y] = *(pixeldark + x*100 + y);
    			z2[x][y] =*(pixelraw + x * 100 + y);
    			z2[x][y] -= z1[x][y];					// Überlegen was mit negativen Werten zu machen ist!
    			if(z2[x][y] < 0) z2[x][y] =0;
    			z2[x][y] /=(double)*(pixelwhite + x *100 +y);
    			z2[x][y] *= getMittelwert(pixelwhite);
    			z2[x][y] = round(z2[x][y]);
    			*(pixeledit + x*100 +y) = z2[x][y];
    
    		}
    	}
    
    
    
    
    }
    
    void createPic(BYTE *pixelraw,unsigned char *header)
    {
    	FILE *test;
    	int i =0,x=0,y=0;
    
    	test = fopen("test.bmp","wb");
    
    
    	fseek(test,0,SEEK_SET);
    
    	for(i = 0; i < 1078; ++i)
    		putc(header[i],test);
    
    	fseek(test,1078,SEEK_SET);
    
    	for(x = 0; x < 150; x++)
    	{
    		for(y = 0; y < 100; y++)
    		{
    			putc(*(pixelraw + x*100 +y),test);
    		}
    	}
    	putc(0,test);
    	putc(0,test);
    
    
    
    
    }
    
    

    Orginal Bild

    ausgabe bearbeitet

    und ich glaube nicht das die Ausgabe so richtig ist. hmm



  • Hey Leute
    ich habe es hinbekommen und habe den Compiler die Arbeit machen lassen.

    Der Knackpunkt bei der Rechnung ist, das man beim subtrahieren einfach unsigned char nimmt und der die Werte selbstständig subtrahiert und macht. Nach dem man subtrahiert hat und durch das Weiß Bild dividiert hat , sind die Werte alle zwischen 0 und 1. Dann nach der Multiplikation sind die alle 0 oder 249. Als Ergebnis kommt ein Sternenhimmel raus. Mal sehen ob das Ergebnis akzeptiert wird. Da ich anderen helfen will die zufällig diese Aufgabe in der Fachhochschule bekommen, poste ich mein Ergebnis hier. Ich möchte auch drauf hin weißen, dass der Code vom Cobain komplett falsch ist und vorne und hinten nicht funktionieren wird. Einfach zum Ende scrollen !

     ... main.c... 
    
    /*
     * Author		: yberion45
     * Name			: main.c
     * Datum		: 25.10.2018
     * Martriknr	: 
     * Beschreibung : Hier werden die Bilder eingelesen, verschiedene Kontrollen gemacht und dann an die Funktion zur Bildbearbeitung geschickt
     */
    
    #include "Bildbearbeitung.h"
    
    
    int main(int argc,char *argv[])
    {
    	FILE *Bild;											//Deklaration der Variablen
    	unsigned  char header[1078];
    	unsigned char pixeldark[150][100],pixelwhite[150][100],pixelraw[150][100];
    	char name[14],endung[9]={'k','o','r','r','.','b','m','p'};
    	int i=0,j=0,k=0,posdark=0,poswhite=0,pos=0,m=0;
    
    
    
    
    	if(argc <=5)		//Weniger als 5 Argumente Fehler!
    	{
    		fprintf(stderr,"Keine Argumente!\n"),exit(0);
    	}
    	else
    	{
    		printf("Argumente wurden gefunden!\n");
    	}
    
    
    		for(k = 1; k < argc; ++k)					//Schleife zum Suchen der dark.bmp und white.bmp
    		{
    				if((strcmp(argv[k],"dark.bmp")) == 0)			//Wenn findet hol die Pixel ab und speichere die Position des Arguments
    				{
    					Bild = fopen(argv[k],"rb");
    					getPixel(Bild,header,&pixeldark[0][0]);
    					posdark = k;
    				}
    				if((strcmp(argv[k],"white.bmp")) == 0)
    				{
    					poswhite = k;
    					Bild=fopen(argv[k],"rb");
    					getPixel(Bild,header,&pixelwhite[0][0]);
    
    				}
    		}
    
    
    
    		pos = argc-1;			//Anzahl der Arguemnte
    
    
    		if( posdark > 3 && poswhite > 3)		//wenn dark.bmp oder white.bmp hintere Pos laufe nur bis vor den beiden
    		{
    			if( posdark > poswhite)
    			{
    				pos = poswhite;
    			}
    			else if( posdark < poswhite)
    			{
    				pos = posdark;
    			}
    			m=0;
    		}
    		else if( posdark < 2 && poswhite <= 2)		//Wenn dark.bmp und white bmp vorne fange ab Position 2 an
    		{
    			m=2;
    		}
    
    
    	for( k = m; k < pos -1 ; ++k)					//Scheife für die Bildbearbeitung
    	{
    
    
    			if(k == posdark)		//Wenn dark.bmp und white bmp nicht den Platz ganz vorne oder ganz hinten haben
    				continue;
    			if(k == poswhite)
    				continue;
    
    			Bild = fopen(argv[k+1],"rb");			//Öffne Bild!
    
    			if(Bild == NULL)										//Konnte Bild geöffnet werden?
    				printf("Bild wurde nicht gefunden!\n"),exit(0);
    
    			getPixel(Bild,header,&pixelraw[0][0]);					//Hole die Pixel vom Rohbild und den Header
    			ImageEdit(&pixelraw[0][0],&pixelwhite[0][0],&pixeldark[0][0]);		//Bearbeite das Bild
    
    
    
    			strncpy(name,argv[k+1],4);				//Kopiere Name vom Argument bis vor den Punkt
    
    			for(i = 4,j=0; j < 9; ++j , ++i)		//Füge den Name für die Ausgabe Datei hinzu korr.bmp
    			{
    				name[i] = endung[j];
    			}
    
    				name[i] = '\0';
    
    
    
    			createPic(&pixelraw[0][0],header,name);		//Gebe Bild aus!
    
    	}
    
    	fclose(Bild);				//schließe Bild
    	return 0;
    }
    
    
     ... bildbearbeitung.c …
    
    /*
     * Author		: yberion45
     * Name			: Bildbearbeitung.c
     * Datum		: 25.10.2018
     * Martrikelnr	: 
     * Beschreibung : Hier sind die ganzen Funktion um das Bild zu bearbeiten und auszugeben!
     */
    
    #include "Bildbearbeitung.h"
    
    
    
    /*
     * Name			: getPixel
     * Datum		: 25.10.2018
     * Beschreibung	: Hier wird im ersten Schritt Der Vorspan der BMP Datei in ein Array gespeichert und
     * 				  anschließend werden die Pixel aus der BMP Datei ausgelesen
     */
    
    
    void getPixel(FILE *bild, unsigned char *Vorspann,  unsigned char *array)
    {
    	int i =0,x=0,y=0;
    	unsigned int width,height;
    
    	for( i = 0; i < 1078; ++i)			// Der Vorpann wird ausgelesen
    	{
    		Vorspann[i] = fgetc(bild);
    	}
    
    		if(Vorspann[0] != 'B' || Vorspann[1] != 'M')			//Ist es eine BMP Datei, wenn nicht exit
    		{
    			printf("Es ist keine BMP Datei!\n"),exit(0);
    		}
    		else
    		{
    			printf("Es handelt sich um eine BMP Datei!\n");
    		}
    
    	width = (int)Vorspann[0x12];								//Abholen der Spalten und Zeilen
    	height = (int)Vorspann[0x16];
    
    
    
    	fseek(bild,0x436,SEEK_SET);					//Positioniere Zeiger auf der Position 0x436
    
    	for(x = 0; x < height; x++)					// Spalten Schleife
    	{
    		for(y = 0; y < width; y++)				//Zeilen schleife
    		{
    
    		  *(array + x* width + y) = fgetc(bild);		//lese Pixel ein und speichere sie im 2D Array
    		}
    	}
    
    
    
    
    }
    
    /*
     * Name			: getMittelwert
     * Datum		: 25.10.2018
     * Beschreibung : Hier wird der Mittelwert der  WeißBild berechnet
     */
    
    double getMittelwert(unsigned char *whitepic)
    {
    	double mittelwert=0;
    	int x=0,y=0;
    
    	for(x = 0; x < 150; ++x)			//Spalten Schleife
    	{
    		for(y = 0; y < 100; ++y)		//Zeilen Schleife
    		{
    			mittelwert = mittelwert + *(whitepic + x*100 +y);
    		}
    	}
    
    	mittelwert = mittelwert/ (150*100);		//teilen durch die Gesamt Anzahl
    
    	return mittelwert;
    }
    
    /*
     * Name			: ImageEdit
     * Datum		: 25.10.2018
     * Beschreeibung: Hier wird das Bild bearbeitet. Erst wird Das SchwarzBild subtrahiert und dann das Weiß Bild dividiert und anschließend
     * 				 mit dem Mittelwert multipilziert und gerundet;
     */
    
    void ImageEdit( unsigned char * pixelraw, unsigned char *pixelwhite,unsigned char *pixeldark)
    {
    	int x=0,y=0;
    	double z1[150][100];
    	double graustufenmittelwert=0;
    
    	graustufenmittelwert = getMittelwert(pixelwhite);			//Abholen des Mittelwertes!
    
    			for(x = 0; x< 150; x++)					//Spaltenschleife
    			{
    				for(y = 0; y<100; y++)				//Zeilenschleife
    				{
    					*(pixelraw + x*100 +y) = *(pixelraw + x*100 +y) - *(pixeldark + x*100 +y);  // Rohbild - Dunkelbild
    					z1[x][y] = *(pixelraw + x*100+y) / (*(pixelwhite + x*100 +y));				//korrigiertes Rohbild/weißbild
    					z1[x][y] = z1[x][y] *graustufenmittelwert;									// korrigiertes Rohbild mal Mittelwert
    					z1[x][y] = round(z1[x][y]);													//Runden
    					*(pixelraw + x*100 +y) = z1[x][y];											//Speichern im Rohbild array
    				}
    			}
    
    
    
    }
    
    /*
     * Name			: createPic
     * Datum		: 25.10.2018
     * Beschreibung :  Hier wird das Bild ausgegeben mit dem neuen Dateinamen
     */
    
    void createPic(unsigned char *pixelraw,unsigned char *header,char *name)
    {
    	FILE *ausgabe;
    	int i =0,x=0,y=0;
    
    
    	ausgabe = fopen(name,"wb");			//öffnen der Datei mit dem neuen Namen.
    
    
    
    
    	fseek(ausgabe,0,SEEK_SET);			//Positioniere Zeiger auf Pos 0 in der Ausgabe Datei
    
    	for(i = 0; i < 1078; ++i)			// Schreibe den Vorspann der BMP Datei in die Ausgabe datei
    		fputc(header[i],ausgabe);
    
    	fseek(ausgabe,1078,SEEK_SET);		//Positioniere den Zeiger auf die Position 1078 in der Dati
    
    	for(x = 0; x < 150; x++)
    	{
    		for(y = 0; y < 100; y++)
    		{
    
    			fputc(*(pixelraw + x*100 +y),ausgabe);  		//Schreibe die korrigierten Pixel in die Datei
    
    		}
    	}
    	putc(0,ausgabe);										//Hänge die Füllbytes dran
    	putc(0,ausgabe);
    
    
    }
     
    
     ... Header.h... 
    /*
     * Bildbearbeitung.h
     *
     *  Created on: 25.10.2018
     *      Author: tiger
     */
    
    #ifndef BILDBEARBEITUNG_H_
    #define BILDBEARBEITUNG_H_
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    
    extern void getPixel(FILE *,  unsigned char *,unsigned char *);
    extern void ImageEdit( unsigned char *, unsigned char *,unsigned  char *);
    extern double getMittelwert(unsigned char *);
    extern void createPic(unsigned char *,unsigned char*,char *);
    
    #endif /* BILDBEARBEITUNG_H_ */
    
    

Anmelden zum Antworten