Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /********************************modul.h****************************************/
- #ifndef MODUL_H
- #define MODUL_H
- #define MAX 512
- typedef struct /*struktura do przechowywania danych o obrazie*/
- {
- int wymx, wymy, szarosci;
- int *tab;
- char numer[2];
- } dane;
- void wyswietl(char *) ;
- void assert (int, char *);
- int negatyw (dane *);
- int progowanie (dane *, int);
- int zmiana_poziomow (dane *,int, int);
- int konturowanie (dane *);
- int rozciaganie_histogramu (dane *);
- int konwersja_do_szarosci (dane *);
- #endif
- /*********************************modul.c*************************************/
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "modul.h"
- #define MAX 512
- #define DL_LINII 1024
- void wyswietl(char *n_pliku) {
- char polecenie[DL_LINII];
- strcpy(polecenie,"display ");
- strcat(polecenie,n_pliku);
- strcat(polecenie," &");
- printf("%s\n",polecenie);
- system(polecenie);
- }
- /*************************************************************************
- * *
- * Funkcja wyswietlajaca bledy asercji. Konczy dzialanie programu, jesli *
- * zostanie wywolana z innego miejsca programu *
- * *
- **************************************************************************/
- void assert (int warunek, char *komunikat)
- {
- if (warunek) /*Jesli warunek zostaje spelniony*/
- {
- printf("Blad asercji: %s\n",komunikat); /*Wyswietl komunikat*/
- printf("Program nie moze kontynuowac.");
- exit(-1); /*Wyjscie z programu*/
- }
- }
- /************************************************************************
- * *
- * Funkcja robiaca negatyw obrazu o zadanych wymiarach i skali szarosci *
- * *
- ************************************************************************/
- int negatyw (dane *obraz)
- {
- int a, b; /*Zmienne pomocnicze do wypelniania tablicy*/
- for(a=0; a<obraz->wymy; a++)
- {
- for(b=0; b<obraz->wymx; b++)
- {
- obraz->tab[obraz->wymx*a+b]=obraz->szarosci-obraz->tab[obraz->wymx*a+b];
- /*Zmiana wartosci odcieni dla poszczegolnych pikseli*/
- }
- }
- }
- /************************************************************************
- * *
- * Funkcja progujaca obraz o przez uzytkownika progu (liczba podana w *
- * procentach). *
- * *
- ************************************************************************/
- int progowanie (dane *obraz, int prog)
- {
- int a, b;
- prog=prog*obraz->szarosci/100; /*Zamien wartosc procentowa progu na liczbe w zaleznosci od stopnia szarosci*/
- for(a=0; a<obraz->wymy; a++)
- {
- for(b=0; b<obraz->wymx; b++) /*Dla kazdego piksela*/
- {
- if (obraz->tab[obraz->wymx*a+b]>prog) /*Jezeli wieksze niz prog*/
- {
- obraz->tab[obraz->wymx*a+b]=obraz->szarosci; /*Ustaw wartosc na maks*/
- }
- else
- {
- obraz->tab[obraz->wymx*a+b]=0; /*Jesli nie, min*/
- }
- }
- }
- }
- /***********************************************************************
- * *
- * Funkcja robiaca zmiane poziomow obrazu. Uzytkowanik podaje nowe *
- * wartosci czerni i bieli wyrazone w procentach. *
- * *
- ***********************************************************************/
- int zmiana_poziomow (dane *obraz,int czern, int biel)
- {
- czern=czern*obraz->szarosci/100; /*Zamiana wartosci czerni z procentow na liczbe zalezna od skali szarosci*/
- biel=biel*obraz->szarosci/100; /*Analogicznie dla wartosci czerni*/
- int a, b;
- for(a=0; a<obraz->wymy; a++)
- {
- for(b=0;b<obraz->wymx; b++)
- {
- if (obraz->tab[obraz->wymx*a+b]>czern && obraz->tab[obraz->wymx*a+b]<biel)
- { /*Jezeli znajduje sie w zakresie pomiedzy nowymi wartosciami*/
- obraz->tab[obraz->wymx*a+b]=(obraz->tab[obraz->wymx*a+b]-czern)*obraz->szarosci/(biel-czern);
- } /*Oblicz nowa wartosc korzystajac ze wzoru*/
- else
- {
- if(obraz->tab[obraz->wymx*a+b]<=czern) /*Jesli mniejszy/rowny czern*/
- {
- obraz->tab[obraz->wymx*a+b]=0; /*Ustaw wartosc na min*/
- }
- else
- {
- obraz->tab[obraz->wymx*a+b]=obraz->szarosci; /*Jesli nie, max*/
- }
- }
- }
- }
- }
- /**********************************************************************
- * *
- * Funkcja wykonujaca operacje konturowania *
- * *
- **********************************************************************/
- int konturowanie (dane *obraz)
- {
- int a,b;
- for (a=0; a<obraz->wymy; a++)
- {
- for (b=0; b<obraz->wymx; b++)
- {
- obraz->tab[obraz->wymx*a+b]=abs(obraz->tab[obraz->wymx*a+b+1]-obraz->tab[obraz->wymx*a+b])+abs(obraz->tab[obraz->wymx*(a+1)+b]-obraz->tab[obraz->wymx*a+b]); /*Oblicz nowa wartosc korzystajac ze wzoru*/
- }
- }
- }
- /*********************************************************************
- * *
- * Funkcja wykonujaca operacje rozciagniecia histogramu. Funkcja *
- * szuka najmniejszej i najwiekszej wartosci, po czym oblicza nowe *
- * wartosci korzystajac ze wzoru. *
- * *
- *********************************************************************/
- int rozciaganie_histogramu (dane *obraz)
- {
- int a, b;
- int min=obraz->tab[0]; /*Min jako pierwszy element*/
- int max=min; /*Max jako pierwszy element*/
- for(a=0; a<obraz->wymy; a++)
- {
- for(b=0; b<obraz->wymx; b++)
- {
- if (obraz->tab[obraz->wymx*a+b]<min)
- {
- min=obraz->tab[obraz->wymx*a+b]; /*Jesli mniejszy niz min: zamien min na nowa wartosc*/
- }
- if(obraz->tab[obraz->wymx*a+b]>max)
- {
- max=obraz->tab[obraz->wymx*a+b]; /*Analogicznie max*/
- }
- }
- for(a=0; a<obraz->wymy; a++)
- {
- for(b=0; b<obraz->wymx; b++)
- {
- obraz->tab[obraz->wymx*a+b]=(obraz->tab[obraz->wymx*a+b]-min)*obraz->szarosci/(max-min);
- } /*Korzystajac ze wzoru oblicz nowa wartosc*/
- }
- }
- }
- /************************************************************************
- * *
- * Funkcja wykonujaca operacje kowersji obrazu kolorowego do obrazu *
- * bialo-czarnego. Funkcja dla kazdego piksela, ktory sklada sie z *
- * trzech liczb (dlatego tablica do wypelnienia jest 3 razy wieksza) *
- * wyciaga srednia arytmetyczna z jego skladowych i kazdemu kolorowi *
- * przyporzadkowuje wartosc sredniej. *
- * *
- ************************************************************************/
- int konwersja_do_szarosci (dane *obraz)
- {
- int a, b;
- for(a=0; a<obraz->wymy; a++)
- {
- for(b=0; b<3*obraz->wymx; b=b+3) /*Dla tablicy, ktora ma 3 razy wiecej miejsca niz tablica .pgm*/
- { /*Skacze o 3 miejsca, gdyz tyle liczb sklada sie na jeden piksel*/
- obraz->tab[3*obraz->wymx*a+b]=(obraz->tab[3*obraz->wymx*a+b]+obraz->tab[3*obraz->wymx*a+b+1]+obraz->tab[3*obraz->wymx*a+b+2])/3; /*Wartosc pierwszej skladowej to teraz srednia wszystkich trzech*/
- obraz->tab[3*obraz->wymx*a+b+1]= obraz->tab[3*obraz->wymx*a+b];
- obraz->tab[3*obraz->wymx*a+b+2]= obraz->tab[3*obraz->wymx*a+b];
- } /*Przypisz pozostalym skladowym te sama wartosc*/
- }
- }
- /**************************************main.c***************************************/
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
- #include <string.h>
- #include "modul.h"
- #define MAX 512
- #define DL_LINII 1024
- /************************************************************************************************
- * Funkcja czytajaca obrazy i rozpoznajaca ich rozszerzenie. Numer magiczny zapisuje do tablicy *
- * numer[] w strukturze "dane", wymiary, liczbe odcieni i piksele zapisuje odpowiednio do *
- * wymx/wymy, szarosci, *tab. *
- * Funkcja zwraca ilosc pikseli *
- ************************************************************************************************/
- int czytaj(FILE *plik_we, dane *obraz) {
- char buf[DL_LINII];
- int znak;
- int koniec=0;
- int i,j;
- if (plik_we==NULL) {
- fprintf(stderr,"Blad: Nie podano uchwytu do pliku\n");
- return(0);
- }
- /* Sprawdzenie "numeru magicznego" - powinien być P2 lub P3*/
- if (fgets(buf,DL_LINII,plik_we)==NULL) /* Wczytanie pierwszej linii pliku do bufora */
- koniec=1; /* Nie udalo sie? Koniec danych! */
- if ( (buf[0]!='P') || ((buf[1]!='2')&&buf[1]!='3') || koniec) { /* Czy jest magiczne "P2" lub "P3"? */
- fprintf(stderr,"Blad: To nie jest plik PGM lub PPM\n");
- return(0);
- }
- obraz->numer[0]='P'; /*Pierwszy element tablicy jako P, drugi zalezny od wczytanego pliku*/
- obraz->numer[1]=buf[1];
- /* Pominiecie komentarzy */
- do {
- if ((znak=fgetc(plik_we))=='#') { /* Czy linia rozpoczyna sie od znaku '#'? */
- if (fgets(buf,DL_LINII,plik_we)==NULL) /* Przeczytaj ja do bufora */
- koniec=1; /* Zapamietaj ewentualny koniec danych */
- } else {
- ungetc(znak,plik_we); /* Gdy przeczytany znak z poczatku linii */
- } /* nie jest '#' zwroc go */
- } while (znak=='#' && !koniec); /* Powtarzaj dopoki sa linie komentarza */
- /* i nie nastapil koniec danych */
- /* Pobranie wymiarow obrazu i liczby odcieni szarosci */
- if (fscanf(plik_we,"%d %d %d",&(obraz->wymx),&(obraz->wymy),&(obraz->szarosci))!=3) {
- fprintf(stderr,"Blad: Brak wymiarow obrazu lub liczby stopni szarosci\n");
- return(0);
- }
- if (obraz->numer[1]=='2')
- {
- obraz->tab =(int *) malloc(obraz->wymx*obraz->wymy*sizeof(int)); /*alokacja pamieci dla tablicy pikseli*/
- /* Pobranie obrazu .pgm i zapisanie w tablicy tab*/
- for (i=0;i<obraz->wymy;i++) {
- for (j=0;j<obraz->wymx;j++) {
- if (fscanf(plik_we,"%d",&(obraz->tab[obraz->wymx*i+j]))!=1) {
- fprintf(stderr,"Blad: Niewlasciwe wymiary obrazu\n");
- return(0);
- }
- }
- }
- }
- if (obraz->numer[1]=='3')
- {
- obraz->tab =(int *) malloc(3*obraz->wymx*obraz->wymy*sizeof(int)); /*alokacja pamieci dla .ppm*/
- /* Pobranie obrazu .ppm i zapisanie w tablicy tab*/
- for (i=0;i<obraz->wymy;i++)
- {
- for (j=0;j<3*obraz->wymx;j++)
- {
- if (fscanf(plik_we,"%d",&(obraz->tab[3*obraz->wymx*i+j]))!=1)
- {
- fprintf(stderr,"Blad: Niewlasciwe wymiary obrazu\n");
- return(0);
- }
- }
- }
- }
- return obraz->wymx*obraz->wymy; /* Czytanie zakonczone sukcesem */
- } /* Zwroc liczbe wczytanych pikseli */
- /*****************************************************************************
- * *
- * Funkcja zapisujaca obraz do pliku o zadanej nazwie. Zaleznie od pobranego *
- * pliku zapisuje w formacie .pgm lub .ppm *
- * *
- *****************************************************************************/
- int zapisz(FILE *plik_wyjsciowy, dane *obraz)
- {
- int a, b; /*Zmienne pomocnicze do wypelniania tablicy*/
- if(obraz->numer[1]=='2')
- {
- fprintf(plik_wyjsciowy,"P2\n"); /*Zapisanie numeru magicznego */
- fprintf(plik_wyjsciowy,"%d %d %d\n",obraz->wymx,obraz->wymy,obraz->szarosci);
- /*Zapisanie rozmiaru obrazu i skali szarosci*/
- for(a=0;a<obraz->wymy;a++)
- {
- for(b=0;b<obraz->wymx; b++)
- {
- fprintf(plik_wyjsciowy,"%d ",obraz->tab[obraz->wymx*a+b]);
- /*Wypelnienie tablicy*/
- }
- }
- }
- if(obraz->numer[1]=='3')
- {
- fprintf(plik_wyjsciowy,"P3\n"); /*Zapisanie numeru magicznego */
- fprintf(plik_wyjsciowy,"%d %d %d\n",obraz->wymx,obraz->wymy,obraz->szarosci);
- /*Zapisanie rozmiaru obrazu i skali szarosci*/
- for(a=0;a<obraz->wymy;a++)
- {
- for(b=0;b<3*obraz->wymx; b++)
- {
- fprintf(plik_wyjsciowy,"%d ",obraz->tab[3*obraz->wymx*a+b]);
- /*Wypelnienie tablicy*/
- }
- }
- }
- }
- int przetwarzaj_opcje(int argc, char **argv) {
- int i, prog; /*Zmienne pomocnicze i-do sprawdzania argumentow, prog-prog do progowania, a-do menu*/
- char *nazwa_pliku_we, *nazwa_pliku_wy;
- int czern, biel; /*Zmienne pomocnicze do nowych progow czerni i bieli*/
- FILE *plik_we; /*Uchwyty do plikow wej i wyj*/
- FILE *plik_wy;
- int zapis=0; /*Zmienna pomocnicza, by zapisywac plik na koncu dzialania*/
- int wyswietlic=0; /*Zmienna pomocnicza, by wyswietlac plik na koncu dzialania*/
- int odczytano=0,a=0;
- char *nazwa;
- dane *obrazek;
- obrazek=(dane *)malloc(sizeof(dane)); /*alokacja pamieci na wskaznik na strukture danych*/
- plik_wy=stdout; /* na wypadek gdy nie podano opcji "-o" */
- for (i=1; i<argc; i++) {
- assert ((argv[i][0] != '-'),"To nie jest opcja!"); /* blad: to nie jest opcja - brak znaku "-" */
- switch (argv[i][1]) {
- case 'i': { /* opcja z nazwa pliku wejsciowego */
- if (++i<argc)
- { /* wczytujemy kolejny argument jako nazwe pliku */
- nazwa_pliku_we=argv[i];
- if (strcmp(nazwa_pliku_we,"-")==0) /* gdy nazwa jest "-" */
- plik_we=stdin; /* ustwiamy wejscie na stdin */
- else /* otwieramy wskazany plik */
- plik_we=fopen(nazwa_pliku_we,"r");
- }
- else
- {
- assert(1,"Brak nazwy pliku");
- } /* blad: brak nazwy pliku */
- czytaj(plik_we,obrazek);
- break;
- }
- case 'o':
- { /* opcja z nazwa pliku wyjsciowego */
- if (++i<argc)
- { /* wczytujemy kolejny argument jako nazwe pliku */
- nazwa_pliku_wy=argv[i];
- if (strcmp(nazwa_pliku_wy,"-")==0)
- { /* gdy nazwa jest "-" */
- plik_wy=stdout; /* ustwiamy wyjscie na stdout */
- }
- else
- { /* otwieramy wskazany plik */
- plik_wy=fopen(nazwa_pliku_wy,"w");
- }
- zapis=1;
- }
- else
- {
- assert(1,"Brak nazwy pliku");
- } /* blad: brak nazwy pliku */
- break;
- }
- case 'p': {
- if (++i<argc) { /* wczytujemy kolejny argument jako wartosc progu */
- if (sscanf(argv[i],"%d",&prog)==1)
- {
- progowanie(obrazek,prog); /*I uruchamiamy funkcje*/
- }
- }
- else
- assert(1,"Brak wartosci progu"); /* blad: brak wartosci progu */
- break;
- }
- case 'n': { /* mamy wykonac negatyw */
- negatyw(obrazek);
- break;
- }
- case 'k': { /* mamy wykonac konturowanie */
- konturowanie(obrazek);
- break;
- }
- case 'z':
- {
- if (++i<argc)
- {
- sscanf(argv[i],"%d",&czern)==1; /*Wczytanie nowej wartosci czerni*/
- }
- else
- {
- assert(1,"Brak nowej wartosci czerni.");
- }
- if (++i<argc)
- {
- if (sscanf(argv[i],"%d",&biel)==1) /*Analogicznie bieli*/
- {
- zmiana_poziomow(obrazek,czern,biel);
- }
- else
- {
- assert(1,"Brak nowej wartosci bieli.");
- }
- }
- break;
- }
- case 'h':
- {
- rozciaganie_histogramu(obrazek);
- break;
- }
- case 'm':
- {
- if(++i<argc)
- {
- if (argv[i][0]=='s') /*Jesli kolejny arument to s*/
- if (obrazek->numer[1]==3)
- {
- konwersja_do_szarosci(obrazek);
- }
- else
- {
- assert(1,"To nie jest plik .ppm");
- }
- }
- break;
- }
- case 'd': { /* mamy wyswietlic obraz */
- wyswietlic=1;
- break;
- }
- default: /* nierozpoznana opcja */
- assert(1,"Brak dozwolonej opcji.");
- } /*koniec switch */
- } /* koniec for */
- if (zapis==1) /*Jesli flaga na zapis jest postawiona, zapisz plik na koncu dzialania programu*/
- {
- zapisz(plik_wy,obrazek);
- }
- if (wyswietlic==1) /*Analogicznie wyswietlanie*/
- {
- if (zapis==0)
- {
- nazwa_pliku_wy="tmp";
- plik_wy=fopen(nazwa_pliku_wy,"w");
- zapisz(plik_wy,obrazek);
- fclose(plik_wy);
- }
- wyswietl(nazwa_pliku_wy);
- }
- if (argc==1)
- {
- while(a!=10) /*Wyswietlanie menu*/
- {
- printf("Dostepne opcje:\n");
- printf("1. Odczyt pliku.\n");
- printf("2. Zapis pliku.\n");
- printf("3. Negatyw.\n");
- printf("4. Wyswietlenie obrazu.\n");
- printf("5. Konturowanie.\n");
- printf("6. Progowanie.\n");
- printf("7. Zmiana poziomow.\n");
- printf("8. Rozciaganie histogramu.\n");
- printf("9. Konwersja do szarosci.\n");
- printf("10. Wyjscie z programu.\n");
- printf("Twoj wybor: ");
- scanf("%d", &a);
- switch (a) /*Menu*/
- {
- case 1:
- {
- printf("Podaj nazwe pliku do wczytania: ");
- scanf("%s",nazwa);
- plik_we=fopen(nazwa,"r");
- if(plik_we!=NULL)
- {
- odczytano=czytaj(plik_we,obrazek); /*Jezeli odczytano, czytaj zmienia wartosc*/
- }
- else
- {
- printf("Nie mozna wczytac pliku.");
- }
- }
- break;
- case 2:
- {
- if (odczytano!=0) /*Jezeli odczytano plik*/
- {
- printf("Podaj nazwe pliku do zapisu: ");
- scanf("%s",nazwa);
- plik_wy=fopen(nazwa,"w"); /*Otworz plik do pisania*/
- zapisz(plik_wy,obrazek); /*Funkcja zapisz*/
- fclose(plik_wy);
- }
- else
- {
- printf("Nie wczytano pliku!\n");
- }
- }
- break;
- case 3:
- {
- if (odczytano!=0)
- {
- negatyw(obrazek); /*Funkcja negatyw*/
- }
- else
- {
- printf("Nie wczytano pliku!\n");
- }
- }
- break;
- case 4:
- {
- if (odczytano!=0)
- {
- wyswietl(nazwa_pliku_wy); /*Funkcja wyswietl*/
- }
- else
- printf("Nie wczytano pliku!\n");
- }
- break;
- case 5:
- {
- konturowanie(obrazek);
- }
- break;
- case 6:
- {
- printf("Podaj procentowa wartosc progu (liczba od 0-100):\n");
- scanf("%d",&prog);
- progowanie(obrazek,prog);
- }
- break;
- case 7:
- {
- printf("Podaj procentowa wartosc czerni i bieli (liczba od 0-100):\n");
- scanf("%d%d",&czern,&biel);
- zmiana_poziomow(obrazek,czern,biel);
- }
- break;
- case 8:
- {
- rozciaganie_histogramu(obrazek);
- }
- break;
- case 9:
- {
- konwersja_do_szarosci(obrazek);
- }
- break;
- case 10:
- {
- printf("Koniec dzialania programu.\n");
- }
- break;
- default:
- {
- printf("Nie ma takiej opcji w menu.\n");
- }
- break;
- }
- }
- }
- }
- int main(int argc, char ** argv) {
- przetwarzaj_opcje(argc,argv); /*Uruchom fukncje przetwarzania*/
- return 0;
- }
- /*
- SPRAWOZDANIE
- Maciej Adamski, Przetwarzanie obrazów 2, 18.12.2016r.
- TESTY OPROGRAMOWANIA
- - przetestowanie kazdej z mozliwych opcji ([-p liczba],-n, -h itd) poprzez wywolanie programu
- Wynik: pozytywny
- - przetestowanie kazdej funkcji edycji obrazu (czy dziala poprawnie) poprzez wyswietlanie obrazu po edycji
- Wynik: pozytywny
- - przetestowanie opcji dot zapisu do pliku ze strumienia wejsciowego, wczytania z pliku na strumien wyjsciowy
- oraz obu opcji na raz
- Wynik: pozytywny
- - przetestowanie zachowania programu podczas podania zbyt duzego progu, bieli i czerni
- Wynik: pozytywny (Komunikat o bledzie asercji)
- - przetestowania opcji, ktora nie zostala zdefiniowana w kodzie zrodlowym
- Wynik: pozytywny
- - przetestowanie zachowania programu podczas braku wartosci progu, czerni i bieli
- Wynik: pozytywny (Komunikat o bledzie asercji)
- Wszystkie testy zakonczyly sie pozytywnie, wiec mozna uznac, ze program dziala poprawnie dla dowolnych danych
- wejsciowych.
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement