Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <math.h>
- #define DL_LINII 1024
- typedef struct
- {
- FILE* plik;
- char* nazwa;
- int typ;
- char** komentarze;
- int ilosc_komentarzy;
- int wysokosc;
- int szerokosc;
- int skala;
- int*** piksele_wejsciowe;
- int*** piksele_wyjsciowe;
- int*** piksele_tymczasowe;
- }zdjecie;
- /*SPRAWDZANIE POPRAWNOSCI*/
- int czy_plik_istnieje (FILE * plik); // Zwraca 0(tak) -1(nie)
- int czy_plik_jest_niepusty (FILE * plik); // Zwraca 0(tak) -1(nie)
- int czy_jest_typ (FILE * plik); // Zwraca [1;6](typ) -1(niepoprawny lub nie ma)
- int czy_sa_wymiary (FILE * plik); // Zwraca 0(tak) -1(niepoprawne) -2(nie ma podanych)
- int czy_jest_podana_skala (FILE * plik); // Zwraca 0(tak) -1(nie)
- int sprawdz_poprawnosc_metadanych_pliku (FILE * plik); // Zwraca 0(pli gotowy do dalszych dzialan) -1 nie rozpoczynac z nim pracy
- int czy_skala_jest_prawdziwa (int ** piksele, int skala, int wysokosc, int szerokosc);
- /*WCZYTYWANIE PLIKU*/
- int*** pobierz_piksele (FILE * plik, int wysokosc, int szerokosc, int typ);
- void pobierz_wymiary (FILE * plik, int * wysokosc, int * szerokosc);
- void pobierz_typ (FILE * plik, int * typ);
- char** pobierz_komentarze (FILE * plik, int * ilosc_komentarzy);
- void pobierz_skale (FILE * plik, int * skala);
- /*FUNKCJE POMOCNICZE*/
- void zwolnij_tablice_znakow (char ** tablica, int ilosc_wierszy);
- void zwolnij_tablice_liczb (int ** tablica, int ilosc_wierszy);
- void zwolnij_pamiec(zdjecie * obraz);
- int czy_jest_cyfra (char znak);
- int** normalizuj (int ** piksele, int skala, int wysokosc, int szerokosc);
- int czy_skala_jest_prawdziwa (int ** piksele, int skala, int wysokosc, int szerokosc);
- int znajdz_maksimum (int ** piksele, int wysokosc, int szerokosc);
- int znajdz_minimum (int ** piksele, int wysokosc, int szerokosc);
- /*OPERACJE NA POJEDYNCZYCH PIKSELACH*/
- int** negatyw (int ** piksele, int skala, int wysokosc, int szerokosc);
- int** progowanie (int ** piksele, int skala, int wysokosc, int szerokosc);
- int** polprogowanie_czerni (int ** piksele, int skala, int wysokosc, int szerokosc);
- int** polprogowanie_bieli (int ** piksele, int skala, int wysokosc, int szerokosc);
- int** korekcja_gamma (int ** piksele, int skala, int wysokosc, int szerokosc);
- int** zmiana_poziomow (int ** piksele, int skala, int wysokosc, int szerokosc);
- int** rozciagniecie_histogramu (int ** piksele, int skala, int wysokosc, int szerokosc);
- /* OPERACJE LOKALNE(NA KILKU PIKSELACH - NIE MASKI)*/
- int** konturowanie (int ** piksele, int wysokosc, int szerokosc);
- int** rozmycie_poziome (int ** piksele, int wysokosc, int szerokosc);
- int** rozmycie_pionowe (int ** piksele, int wysokosc, int szerokosc);
- /*OPERACJE Z UZYCIEM MASEK*/
- int ** operacje_z_uzyciem_masek (int ** piksele, int skala, int wysokosc, int szerokosc, int** maska);
- int ** wybor_maski();
- int ** zwroc_zaalokowana_maske (int maska[3][3]);
- /*FUNCKJE ELEMENTARNE*/
- int pobierz_zdjecie (zdjecie * obraz);
- void zapisz_plik (zdjecie * obraz);
- /*MENU*/
- void menu_glowne();
- void menu_zdjecia();
- int*** menu_pojedynczych (zdjecie * obraz);
- int*** menu_lokalnych (zdjecie * obraz);
- int*** menu_masek (zdjecie * obraz);
- int main()
- {
- menu_glowne();
- return 0;
- }
- void menu_glowne()
- {
- int wybor;
- while(1)
- {
- printf("MENU GLOWNE\n");
- printf("1. Wczytaj zdjecie\n");
- printf("2. Wyjdz\n");
- printf("Twoj wybor:");
- scanf("%d", &wybor);
- printf("|------------------------------------------------------|\n");
- if(wybor == 1)
- {
- menu_zdjecia();
- }
- else
- {
- exit(0);
- }
- }
- }
- void menu_zdjecia()
- {
- zdjecie obraz;
- int czy_wyjsc = pobierz_zdjecie(&obraz);
- if(czy_wyjsc == -1) return;
- printf("Obslugiwane typy to P1, P2 i P3\n"
- "Program operuje na liczbach calkowitych, wiec niektore operacje na P1 sa nieprzewidywalne\n"
- "Jednak dzialaja, wiec nic nie szkodzi by ich uzywac\n"
- "Na plikach typu P2 wszystkie algorytmy dzialaja poprawnie\n"
- "Na plikach P3 kazdy wybrany algorytm jest uzywany osobno dla wszystkich skladowych\n"
- "Np. negatywa na P3 oznacza zastosowanie go osobno na skladowych R, G i B\n"
- "Wszystkie inne operacje analogicznie.\n");
- // wybor operacji jaka chcemy wykonac
- char wybor_operacji[2] = " ";
- printf("Mozliwe do wykonania operacje\n");
- printf("1. Operacje na pojedynczych pikselach\n");
- printf("2. Operacje lokalne\n");
- printf("3. Operacje z uzyciem masek\n");
- printf("Twoj wybor: ");
- scanf("%1s", wybor_operacji);
- printf("|------------------------------------------------------|\n");
- if(wybor_operacji[0] == '1')
- {
- obraz.piksele_wyjsciowe = menu_pojedynczych(&obraz);
- }
- else if(wybor_operacji[0] == '2')
- {
- obraz.piksele_wyjsciowe = menu_lokalnych(&obraz);
- }
- else if(wybor_operacji[0] == '3')
- {
- obraz.piksele_wyjsciowe = menu_masek(&obraz);
- }
- while(1)
- {
- char menu_dalszej_obrobki_wyjsciowych[2] = " ";
- char menu_dalszej_obrobki_wejsciowych[2] = " ";
- char menu_operacji[2] = " "; // do wyboru opcji ponizej
- printf("| Co chcialbys zrobic? |\n"
- "|------------------------------------------------------|\n"
- "| Piksele wyjsciowe: |\n"
- "|1. Zapisac piksele wyjsciowe |\n"
- "|2. Wyswietlic piksele wyjsciowe |\n"
- "|3. Wykonac na pikselach wyjsciowych dalsze operacje |\n"
- "| (usuwa obecne wyjsciowe) |\n"
- "|4. Zapisac i wrocic do wyboru pliku |\n"
- "|5. Nie zapisywac i wrocic do wyboru pliku |\n"
- "|------------------------------------------------------|\n"
- "| Piksele wejsciowe: |\n"
- "|6. Wykonac na nich operacje (usuwa obecne wyjsciowe) |\n"
- "|7. Wyjsc bez zapisu |\n"
- "|------------------------------------------------------|\n"
- "Twoj wybor: ");
- scanf("%1s", menu_operacji);
- printf("|------------------------------------------------------|\n");
- switch(menu_operacji[0])
- {
- case '1':
- zapisz_plik(&obraz);
- break;
- case '2':
- //TODO
- break;
- case '3':
- // przygotuj pamiec
- zwolnij_tablice_liczb(obraz.piksele_wyjsciowe[0], obraz.wysokosc);
- zwolnij_tablice_liczb(obraz.piksele_wyjsciowe[1], obraz.wysokosc);
- zwolnij_tablice_liczb(obraz.piksele_wyjsciowe[2], obraz.wysokosc);
- zwolnij_tablice_liczb(obraz.piksele_wyjsciowe[3], obraz.wysokosc);
- free(obraz.piksele_wyjsciowe);
- // wybierz operacje
- printf("Mozliwe do wykonania operacje\n");
- printf("1. Operacje na pojedynczych pikselach\n");
- printf("2. Operacje lokalne\n");
- printf("3. Operacje z uzyciem masek\n");
- printf("Twoj wybor: ");
- scanf("%1s", menu_dalszej_obrobki_wejsciowych);
- printf("|------------------------------------------------------|\n");
- if(menu_dalszej_obrobki_wejsciowych[0] == '1')
- {
- obraz.piksele_wyjsciowe = menu_pojedynczych(&obraz);
- }
- else if(wybor_operacji[0] == '2')
- {
- obraz.piksele_wyjsciowe = menu_lokalnych(&obraz);
- }
- else if(wybor_operacji[0] == '3')
- {
- obraz.piksele_wyjsciowe = menu_masek(&obraz);
- }
- break; case '4':
- zapisz_plik(&obraz);
- zwolnij_pamiec(&obraz);
- return;
- case '5':
- zwolnij_pamiec(&obraz);
- return;
- break;
- case '6':
- /* przypisz piksele wejsciowe do tymczasowych
- w celu zmiany wskaznika wejsciowych na wskaznik wyjsciowych
- potem je odpowiedni przywroci tj
- Poczatek
- wejsciowe - jakies piksele 1
- tymczasowe - NULL
- wyjsciowe - jakies piksele 2
- Potem
- wejsciowe - jakies piksele 2
- tymczasowe - jakies piksele 1
- wyjsciowe - NULL
- Koniec
- wejsciowe - jakies piksele 1
- tymczasowe - NULL
- wyjsciowe - jakies piksele 3
- */
- obraz.piksele_tymczasowe = obraz.piksele_wejsciowe;
- obraz.piksele_wejsciowe = obraz.piksele_wyjsciowe;
- obraz.piksele_wyjsciowe = NULL;
- // wybierz i wykonaj operacje
- printf("Mozliwe do wykonania operacje\n");
- printf("1. Operacje na pojedynczych pikselach\n");
- printf("2. Operacje lokalne\n");
- printf("3. Operacje z uzyciem masek\n");
- printf("Twoj wybor: ");
- scanf("%1s", menu_dalszej_obrobki_wyjsciowych);
- printf("|------------------------------------------------------|\n");
- if(menu_dalszej_obrobki_wyjsciowych[0] == '1')
- {
- obraz.piksele_wyjsciowe = menu_pojedynczych(&obraz);
- }
- else if(wybor_operacji[0] == '2')
- {
- obraz.piksele_wyjsciowe = menu_lokalnych(&obraz);
- }
- else if(wybor_operacji[0] == '3')
- {
- obraz.piksele_wyjsciowe = menu_masek(&obraz);
- }
- // po zakonczeniu przywroc piksele wejsciowe z tymczasowych
- obraz.piksele_wejsciowe = obraz.piksele_tymczasowe;
- obraz.piksele_tymczasowe = NULL;
- break;
- case '7':
- exit(0);
- break;
- }
- }
- }
- void zapisz_plik(zdjecie * obraz)
- {
- /*
- Dzialanie:
- Zapisuje:
- typ pliku
- komentarze
- wymiary
- skale szarosci
- piksele wyjsciowe
- */
- char* nazwa = (char*)malloc(sizeof(char) * 100);
- printf("Pod jaka nazwa zapisac plik:\n");
- printf("Jesli istnieje plik o takiej samej nazwie to zostanie wymazany i nadpisany\n");
- printf("Nazwa powinna miec lacznie 10 znakow\n");
- scanf("%s", nazwa);
- printf("|------------------------------------------------------|\n");
- // otworz plik do zapisu
- FILE* plik = fopen(nazwa, "w+");
- // zapisz typ
- printf("Zapisuje typ\n");
- fprintf(plik, "P%d\n", obraz->typ);
- // zapisz komentarze jesli istnieja(zawieraja w sobie znak nowej linii to go nie dodajemy)
- if(obraz->ilosc_komentarzy > 0)
- {
- printf("Zapisuje komentarze\n");
- for(int i = 0; i < obraz->ilosc_komentarzy; i++)
- {
- fprintf(plik, "%s", obraz->komentarze[i]);
- }
- }
- // zapisz wymiary
- printf("Zapisuje wymiary\n");
- fprintf(plik, "%d %d\n", obraz->szerokosc, obraz->wysokosc);
- // zapisz skale jesli p23
- if(obraz->typ == 2 || obraz->typ == 3)
- {
- printf("Zapisuje skale szarosci\n");
- fprintf(plik, "%d \n", obraz->skala);
- }
- // zapisz piksele P12
- printf("Zapisuje piksele\n");
- if(obraz-> typ == 1 || obraz->typ == 2)
- {
- for(int wys = 0; wys < obraz->wysokosc; wys++)
- {
- for(int szer = 0; szer < obraz->szerokosc; szer++)
- {
- fprintf(plik,"%d ", obraz->piksele_wyjsciowe[3][wys][szer]);
- }
- fprintf(plik,"\n");
- }
- }
- // zapisz piksele P3
- if(obraz-> typ == 3)
- {
- for(int wys = 0; wys < obraz->wysokosc; wys++)
- {
- for(int szer = 0; szer < obraz->szerokosc; szer++)
- {
- fprintf(plik,"%d %d %d ",obraz->piksele_wyjsciowe[0][wys][szer],
- obraz->piksele_wyjsciowe[1][wys][szer],
- obraz->piksele_wyjsciowe[2][wys][szer]);
- }
- fprintf(plik,"\n");
- }
- }
- // zamknij plik
- fclose(plik);
- }
- int *** menu_masek(zdjecie * obraz)
- {
- int ** maska = wybor_maski(); // wybierz maske
- int *** piksele_wyjsciowe = NULL;
- // allokuj tablice kolorow
- piksele_wyjsciowe = (int***) malloc(sizeof(int**) * 4);
- // allokuj wiersze
- for(int i = 0; i < 4 ; i++)
- {
- piksele_wyjsciowe[i] = (int**) malloc(sizeof(int*) * obraz->wysokosc);
- }
- // allokuj kolumny
- for(int i = 0; i < obraz->wysokosc; i++)
- {
- piksele_wyjsciowe[0][i] = (int*)malloc(sizeof(int) * obraz->szerokosc);
- piksele_wyjsciowe[1][i] = (int*)malloc(sizeof(int) * obraz->szerokosc);
- piksele_wyjsciowe[2][i] = (int*)malloc(sizeof(int) * obraz->szerokosc);
- piksele_wyjsciowe[3][i] = (int*)malloc(sizeof(int) * obraz->szerokosc);
- }
- if(obraz->typ == 1 || obraz->typ == 2)
- {
- piksele_wyjsciowe[3] = operacje_z_uzyciem_masek(obraz->piksele_wejsciowe[3],
- obraz->skala,
- obraz->wysokosc,
- obraz->szerokosc,
- maska);
- }
- else if(obraz->typ == 3)
- {
- piksele_wyjsciowe[0] = operacje_z_uzyciem_masek(obraz->piksele_wejsciowe[0],
- obraz->skala,
- obraz->wysokosc,
- obraz->szerokosc,
- maska);
- piksele_wyjsciowe[1] = operacje_z_uzyciem_masek(obraz->piksele_wejsciowe[1],
- obraz->skala,
- obraz->wysokosc,
- obraz->szerokosc,
- maska);
- piksele_wyjsciowe[2] = operacje_z_uzyciem_masek(obraz->piksele_wejsciowe[2],
- obraz->skala,
- obraz->wysokosc,
- obraz->szerokosc,
- maska);
- }
- free(maska);
- // normalizuj
- piksele_wyjsciowe[0] = normalizuj(piksele_wyjsciowe[0], obraz->skala, obraz->wysokosc, obraz->szerokosc);
- piksele_wyjsciowe[1] = normalizuj(piksele_wyjsciowe[1], obraz->skala, obraz->wysokosc, obraz->szerokosc);
- piksele_wyjsciowe[2] = normalizuj(piksele_wyjsciowe[2], obraz->skala, obraz->wysokosc, obraz->szerokosc);
- piksele_wyjsciowe[3] = normalizuj(piksele_wyjsciowe[3], obraz->skala, obraz->wysokosc, obraz->szerokosc);
- return piksele_wyjsciowe;
- }
- int *** menu_lokalnych(zdjecie * obraz)
- {
- int *** piksele_wyjsciowe = NULL;
- // allokuj tablice kolorow
- piksele_wyjsciowe = (int***) malloc(sizeof(int**) * 4);
- // allokuj wiersze
- for(int i = 0; i < 4 ; i++)
- {
- piksele_wyjsciowe[i] = (int**) malloc(sizeof(int*) * obraz->wysokosc);
- }
- // allokuj kolumny
- for(int i = 0; i < obraz->wysokosc; i++)
- {
- piksele_wyjsciowe[0][i] = (int*)malloc(sizeof(int) * obraz->szerokosc);
- piksele_wyjsciowe[1][i] = (int*)malloc(sizeof(int) * obraz->szerokosc);
- piksele_wyjsciowe[2][i] = (int*)malloc(sizeof(int) * obraz->szerokosc);
- piksele_wyjsciowe[3][i] = (int*)malloc(sizeof(int) * obraz->szerokosc);
- }
- // wybrana_operacja[0] operacji
- char wybrana_operacja[2] = " ";
- printf("Prosze wybrac operacje, ktora chcialbys wykonac.\n");
- printf("1. Konturowanie\n");
- printf("2. Rozmycie poziome\n");
- printf("3. Rozmycie pionowe\n");
- printf("Twoj wybor to:");
- scanf("%1s", wybrana_operacja);
- printf("|------------------------------------------------------|\n");
- if(wybrana_operacja[0] == '1')
- {
- if(obraz->typ == 1 || obraz->typ == 2)
- {
- piksele_wyjsciowe[3] = konturowanie(obraz->piksele_wejsciowe[3], obraz->wysokosc, obraz->szerokosc);
- }
- else if(obraz->typ == 3)
- {
- piksele_wyjsciowe[0] = konturowanie(obraz->piksele_wejsciowe[0], obraz->wysokosc, obraz->szerokosc);
- piksele_wyjsciowe[1] = konturowanie(obraz->piksele_wejsciowe[1], obraz->wysokosc, obraz->szerokosc);
- piksele_wyjsciowe[2] = konturowanie(obraz->piksele_wejsciowe[2], obraz->wysokosc, obraz->szerokosc);
- }
- }
- if(wybrana_operacja[0] == '2')
- {
- if(obraz->typ == 1 || obraz->typ == 2)
- {
- piksele_wyjsciowe[3] = rozmycie_poziome(obraz->piksele_wejsciowe[3], obraz->wysokosc, obraz->szerokosc);
- }
- else if(obraz->typ == 3)
- {
- piksele_wyjsciowe[0] = rozmycie_poziome(obraz->piksele_wejsciowe[0], obraz->wysokosc, obraz->szerokosc);
- piksele_wyjsciowe[1] = rozmycie_poziome(obraz->piksele_wejsciowe[1], obraz->wysokosc, obraz->szerokosc);
- piksele_wyjsciowe[2] = rozmycie_poziome(obraz->piksele_wejsciowe[2], obraz->wysokosc, obraz->szerokosc);
- }
- }
- if(wybrana_operacja[0] == '3')
- {
- if(obraz->typ == 1 || obraz->typ == 2)
- {
- piksele_wyjsciowe[3] = rozmycie_pionowe(obraz->piksele_wejsciowe[3], obraz->wysokosc, obraz->szerokosc);
- }
- else if(obraz->typ == 3)
- {
- piksele_wyjsciowe[0] = rozmycie_pionowe(obraz->piksele_wejsciowe[0], obraz->wysokosc, obraz->szerokosc);
- piksele_wyjsciowe[1] = rozmycie_pionowe(obraz->piksele_wejsciowe[1], obraz->wysokosc, obraz->szerokosc);
- piksele_wyjsciowe[2] = rozmycie_pionowe(obraz->piksele_wejsciowe[2], obraz->wysokosc, obraz->szerokosc);
- }
- }
- // normalizuj
- piksele_wyjsciowe[0] = normalizuj(piksele_wyjsciowe[0], obraz->skala, obraz->wysokosc, obraz->szerokosc);
- piksele_wyjsciowe[1] = normalizuj(piksele_wyjsciowe[1], obraz->skala, obraz->wysokosc, obraz->szerokosc);
- piksele_wyjsciowe[2] = normalizuj(piksele_wyjsciowe[2], obraz->skala, obraz->wysokosc, obraz->szerokosc);
- piksele_wyjsciowe[3] = normalizuj(piksele_wyjsciowe[3], obraz->skala, obraz->wysokosc, obraz->szerokosc);
- return piksele_wyjsciowe;
- }
- int *** menu_pojedynczych(zdjecie * obraz)
- {
- int *** piksele_wyjsciowe = NULL;
- // allokuj tablice kolorow
- piksele_wyjsciowe = (int***) malloc(sizeof(int**) * 4);
- // allokuj wiersze
- for(int i = 0; i < 4 ; i++)
- {
- piksele_wyjsciowe[i] = (int**) malloc(sizeof(int*) * obraz->wysokosc);
- }
- // allokuj kolumny
- for(int i = 0; i < obraz->wysokosc; i++)
- {
- piksele_wyjsciowe[0][i] = (int*)malloc(sizeof(int) * obraz->szerokosc);
- piksele_wyjsciowe[1][i] = (int*)malloc(sizeof(int) * obraz->szerokosc);
- piksele_wyjsciowe[2][i] = (int*)malloc(sizeof(int) * obraz->szerokosc);
- piksele_wyjsciowe[3][i] = (int*)malloc(sizeof(int) * obraz->szerokosc);
- }
- // wybor operacji
- char wybrana_operacja[2] = " ";
- printf("Prosze wybrac operacje, ktora chcialbys wykonac.\n");
- printf("1. Negatyw\n");
- printf("2. Progowanie\n");
- printf("3. Polprogowanie czerni\n");
- printf("4. Polprogowanie bieli\n");
- printf("5. Korekcja gamma\n");
- printf("6. Zmiana poziomow\n");
- printf("7. Rozciagniecie histogramu\n");
- printf("Twoj wybor to:");
- scanf("%1s", wybrana_operacja);
- printf("|------------------------------------------------------|\n");
- // negatyw
- if(wybrana_operacja[0] == '1')
- {
- if(obraz->typ == 1 || obraz->typ == 2)
- {
- piksele_wyjsciowe[3] = negatyw(obraz->piksele_wejsciowe[3],obraz->skala, obraz->wysokosc, obraz->szerokosc);
- }
- else if(obraz->typ == 3)
- {
- piksele_wyjsciowe[0] = negatyw(obraz->piksele_wejsciowe[0],obraz->skala, obraz->wysokosc, obraz->szerokosc);
- piksele_wyjsciowe[1] = negatyw(obraz->piksele_wejsciowe[1],obraz->skala, obraz->wysokosc, obraz->szerokosc);
- piksele_wyjsciowe[2] = negatyw(obraz->piksele_wejsciowe[2],obraz->skala, obraz->wysokosc, obraz->szerokosc);
- }
- }
- // progowanie
- else if(wybrana_operacja[0] == '2')
- {
- if(obraz->typ == 1 || obraz->typ == 2)
- {
- piksele_wyjsciowe[3] = progowanie(obraz->piksele_wejsciowe[3],obraz->skala, obraz->wysokosc, obraz->szerokosc);
- }
- else if(obraz->typ == 3)
- {
- piksele_wyjsciowe[0] = progowanie(obraz->piksele_wejsciowe[0],obraz->skala, obraz->wysokosc, obraz->szerokosc);
- piksele_wyjsciowe[1] = progowanie(obraz->piksele_wejsciowe[1],obraz->skala, obraz->wysokosc, obraz->szerokosc);
- piksele_wyjsciowe[2] = progowanie(obraz->piksele_wejsciowe[2],obraz->skala, obraz->wysokosc, obraz->szerokosc);
- }
- }
- // polprogowanie czerni
- else if(wybrana_operacja[0] == '3')
- {
- if(obraz->typ == 1 || obraz->typ == 2)
- {
- piksele_wyjsciowe[3] = polprogowanie_czerni(obraz->piksele_wejsciowe[3],obraz->skala, obraz->wysokosc, obraz->szerokosc);
- }
- else if(obraz->typ == 3)
- {
- piksele_wyjsciowe[0] = progowanie(obraz->piksele_wejsciowe[0], obraz->skala, obraz->wysokosc, obraz->szerokosc);
- piksele_wyjsciowe[1] = progowanie(obraz->piksele_wejsciowe[1], obraz->skala, obraz->wysokosc, obraz->szerokosc);
- piksele_wyjsciowe[2] = progowanie(obraz->piksele_wejsciowe[2], obraz->skala, obraz->wysokosc, obraz->szerokosc);
- }
- }
- // polprogowanie bieli
- else if(wybrana_operacja[0] == '4')
- {
- if(obraz->typ == 1 || obraz->typ == 2)
- {
- piksele_wyjsciowe[3] = polprogowanie_bieli(obraz->piksele_wejsciowe[3],obraz->skala, obraz->wysokosc, obraz->szerokosc);
- }
- else if(obraz->typ == 3)
- {
- piksele_wyjsciowe[0] = polprogowanie_bieli(obraz->piksele_wejsciowe[0],obraz->skala, obraz->wysokosc, obraz->szerokosc);
- piksele_wyjsciowe[1] = polprogowanie_bieli(obraz->piksele_wejsciowe[1],obraz->skala, obraz->wysokosc, obraz->szerokosc);
- piksele_wyjsciowe[2] = polprogowanie_bieli(obraz->piksele_wejsciowe[2],obraz->skala, obraz->wysokosc, obraz->szerokosc);
- }
- }
- // korekcja gamma
- else if(wybrana_operacja[0] == '5')
- {
- if(obraz->typ == 1 || obraz->typ == 2)
- {
- piksele_wyjsciowe[3] = korekcja_gamma(obraz->piksele_wejsciowe[3],obraz->skala, obraz->wysokosc, obraz->szerokosc);
- }
- else if(obraz->typ == 3)
- {
- piksele_wyjsciowe[0] = korekcja_gamma(obraz->piksele_wejsciowe[0],obraz->skala, obraz->wysokosc, obraz->szerokosc);
- piksele_wyjsciowe[1] = korekcja_gamma(obraz->piksele_wejsciowe[1],obraz->skala, obraz->wysokosc, obraz->szerokosc);
- piksele_wyjsciowe[2] = korekcja_gamma(obraz->piksele_wejsciowe[2],obraz->skala, obraz->wysokosc, obraz->szerokosc);
- }
- }
- else if(wybrana_operacja[0] == '6')
- {
- if(obraz->typ == 1 || obraz->typ == 2)
- {
- piksele_wyjsciowe[3] = zmiana_poziomow(obraz->piksele_wejsciowe[3],obraz->skala, obraz->wysokosc, obraz->szerokosc);
- }
- else if(obraz->typ == 3)
- {
- piksele_wyjsciowe[0] = zmiana_poziomow(obraz->piksele_wejsciowe[0],obraz->skala, obraz->wysokosc, obraz->szerokosc);
- piksele_wyjsciowe[1] = zmiana_poziomow(obraz->piksele_wejsciowe[1],obraz->skala, obraz->wysokosc, obraz->szerokosc);
- piksele_wyjsciowe[2] = zmiana_poziomow(obraz->piksele_wejsciowe[2],obraz->skala, obraz->wysokosc, obraz->szerokosc);
- }
- }
- else if(wybrana_operacja[0] == '7')
- {
- if(obraz->typ == 1 || obraz->typ == 2)
- {
- piksele_wyjsciowe[3] = rozciagniecie_histogramu(obraz->piksele_wejsciowe[3],obraz->skala, obraz->wysokosc, obraz->szerokosc);
- }
- else if(obraz->typ == 3)
- {
- piksele_wyjsciowe[0] = rozciagniecie_histogramu(obraz->piksele_wejsciowe[0],obraz->skala, obraz->wysokosc, obraz->szerokosc);
- piksele_wyjsciowe[1] = rozciagniecie_histogramu(obraz->piksele_wejsciowe[1],obraz->skala, obraz->wysokosc, obraz->szerokosc);
- piksele_wyjsciowe[2] = rozciagniecie_histogramu(obraz->piksele_wejsciowe[2],obraz->skala, obraz->wysokosc, obraz->szerokosc);
- }
- }
- // normalizuj
- else if(obraz->typ == 3)
- {
- piksele_wyjsciowe[0] = normalizuj(piksele_wyjsciowe[0], obraz->skala, obraz->wysokosc, obraz->szerokosc);
- piksele_wyjsciowe[1] = normalizuj(piksele_wyjsciowe[1], obraz->skala, obraz->wysokosc, obraz->szerokosc);
- piksele_wyjsciowe[2] = normalizuj(piksele_wyjsciowe[2], obraz->skala, obraz->wysokosc, obraz->szerokosc);
- }
- if(obraz->typ == 1 || obraz->typ == 2)
- {
- piksele_wyjsciowe[3] = normalizuj(piksele_wyjsciowe[3], obraz->skala, obraz->wysokosc, obraz->szerokosc);
- }
- return piksele_wyjsciowe;
- }
- int pobierz_zdjecie(zdjecie * obraz)
- {
- // Wybor zdjecie przez uzytkownika
- obraz->nazwa = (char*)malloc(sizeof(char) * 10);
- printf("Prosze podac nazwe zdjecie, ktore ma byc wczytane(maks 100 znakow):");
- scanf("%s", obraz->nazwa);
- printf("|------------------------------------------------------|\n");
- obraz->piksele_tymczasowe = NULL;
- // WSTEPNA KONTROLA POPRAWNOSCI
- //--------------------------------------------------------------------------------------------------------------------------------
- /* Otworz plik i sprawdz jego poprawnosc tj.
- 1. Czy istnieje? (Czy da sie go otworzyc?)
- 2. Czy jest niepusty? (Czy 1 znak to EOF?)
- 3. Czy ma podany typ? (czy 2 znak pliku to 1,2,3,4,5,6
- 4. Czy ma podane OBA wymiary? (Czy sa one minimalnie 3x3? i Czy oba istnieja?)
- 5. Czy ma podana skale szarosc/ilosc odcieni? (Czy skala istnieje? i Czy jest wieksza niz 0?)
- Jesli nie to wypisuje co sie nie zgadza i wraca do menu glownego
- Jesli tak to kontynuuje
- */
- obraz->plik = fopen(obraz->nazwa, "r");
- int poprawnosc = sprawdz_poprawnosc_metadanych_pliku(obraz->plik);
- if( poprawnosc != 0) // w jakis sposob niepoprawny
- {
- // gdy nie istnieje to funkcja zwroci -100
- // warunek istnienia jest o tyle wazniejszy od innych,
- // ze zamkniecie pliku wtedy powoduje blad
- if(poprawnosc != -100) fclose(obraz->plik);
- printf("Obraz nie przeszedl pomyslnie kontroli poprawnosci \nWychodze do menu glownego\n");
- printf("|------------------------------------------------------|\n");
- return -1;
- }
- // pobierz typ zdjecia (na pewno jest wsrod 123456 gdyz w kontroli poprawnosci o to zadbalismy)
- pobierz_typ(obraz->plik, &obraz->typ);
- // nie czytaj binarnych
- switch(obraz->typ)
- {
- // obslugiwane formaty P123 nie rob nic
- case 1:
- break;
- case 2:
- break;
- case 3:
- break;
- // nieobslugiwane formaty
- case 4:
- printf("Program nie obsluguje formatu P%d \nWychodze do menu glownego\n", obraz->typ);
- printf("|------------------------------------------------------|\n");
- free(obraz->nazwa);
- fclose(obraz->plik);
- return -1;
- break;
- case 5:
- printf("Program nie obsluguje formatu P%d \nWychodze do menu glownego\n", obraz->typ);
- printf("|------------------------------------------------------|\n");
- free(obraz->nazwa);
- fclose(obraz->plik);
- return -1;
- break;
- case 6:
- printf("Program nie obsluguje formatu P%d \nWychodze do menu glownego\n", obraz->typ);
- printf("|------------------------------------------------------|\n");
- free(obraz->nazwa);
- fclose(obraz->plik);
- return -1;
- break;
- }
- // pobierz komentarze i zapisz ich ilosc
- // jesli brak to zwroc null i ustal ich ilosc na 0
- obraz->komentarze = pobierz_komentarze(obraz->plik, &obraz->ilosc_komentarzy);
- // pobierz wymiary. Wiemy, ze na pewno istnieja, sa dodatnie i wieksze nic 3x3
- pobierz_wymiary(obraz->plik, &obraz->wysokosc, &obraz->szerokosc);
- // Pobierz skale szarosci badz odcieni o ile ma to sens P23
- if(obraz->typ == 2 || obraz->typ == 3)
- {
- pobierz_skale(obraz->plik, &obraz->skala);
- }
- // pobierz piksele w tablicy 3d [4][wysokosc][szerokosc]
- obraz->piksele_wejsciowe = pobierz_piksele(obraz->plik, obraz->wysokosc, obraz->szerokosc, obraz->typ);
- /*
- W tym momencie wiemy, że istniejacy, niepusty plik zawiera poprawne metadane
- tj. wiemy:
- 1. Plik ma podany dobry typ (P1/P2)
- 2. Plik ma podane prawidlowe wymiary(min 3x3)
- 3. Plik ma podana dobra skale szarosci/ilosc/odcieni(min 2 {0,1} obraz czarno bialy)
- Po wczytaniu pikseli nalezy jeszcze sprawdzic:
- 1. Czy podana skala szarosci jest rowna rzeczywistej?
- 1.1 Znajduje realne minimum wartosci piksela (RMin)
- 1.2 znajduje realne maksimum wartosci piksela (Rmax)
- 1.3 Porownuje realne minimum i maksumum z zadeklarowanymi przez plik wartosciami ZMin, ZMax
- Czy ZMin <= {RMin, RMax} <= RMax
- PRZYKLAD:
- ZLE
- Zdjecie1{RMin; RMax} = {-1; 256}
- Zdjecie1{ZMin; ZMax} = { 0; 255}
- Zdjecie1 ma niepoprawne piksele
- DOBRE
- Zdjecie2{RMin; RMax} = {0; 255}
- Zdjecie2{ZMin; ZMax} = {RMin: RMin in [0;255]; RMax in [0;255]}
- Zdjecie2 ma poprawne piksele
- 2. Czy podana ilosc pikseli jest rowna rzeczywistej
- 2.1 Przy pobieraniu pikseli zapisywac ile ich wystapilo przed EOF
- 2.2 Sprawdza czy wysokosc*szerokosc == ilosc_pikseli
- Jesli nie to wypisuje co sie nie zgadza, zamyka plik i wraca do menu glownego
- Jesli tak to kontynuuje
- */
- // czy skala szarosci zgadza sie z rzeczywista
- if(obraz->typ == 2)
- {
- // sprawdz szarosci
- int czy_skala_sie_zgadza =czy_skala_jest_prawdziwa(obraz->piksele_wejsciowe[3],
- obraz->skala,
- obraz->wysokosc,
- obraz-> szerokosc);
- if(czy_skala_sie_zgadza == -1)
- {
- printf("Zadeklarowana skala ilosci odcieni szerosci w pliku "
- "nie zgadza sie z rzeczywista iloscia.\n");
- printf("Wracam do menu glownego \n\n");
- printf("|------------------------------------------------------|\n");
- return -1;
- }
- }
- else if(obraz->typ == 3)
- {
- // sprawdz czerwony
- int red = czy_skala_jest_prawdziwa(obraz->piksele_wejsciowe[0],
- obraz->skala,
- obraz->wysokosc,
- obraz->szerokosc);
- // sprawdz szarosci
- int green = czy_skala_jest_prawdziwa(obraz->piksele_wejsciowe[1],
- obraz->skala,
- obraz->wysokosc,
- obraz->szerokosc);
- // sprawdz szarosci
- int blue = czy_skala_jest_prawdziwa(obraz->piksele_wejsciowe[2],
- obraz->skala,
- obraz->wysokosc,
- obraz->szerokosc);
- if(red + green + blue < 0)
- {
- printf("Zadeklarowana skala ilosci odcieni w pliku "
- "nie zgadza sie z rzeczywista iloscia.\n");
- printf("Wracam do menu glownego \n\n");
- printf("|------------------------------------------------------|\n");
- return -1;
- }
- }
- }
- void zwolnij_pamiec(zdjecie * obraz)
- {
- // zwolnij nazwe
- free(obraz->nazwa);
- // zwolnij komentarze
- if(obraz->ilosc_komentarzy != 0)
- {
- zwolnij_tablice_znakow(obraz->komentarze, obraz->ilosc_komentarzy);
- }
- // zwolnij piksele wejsciowe jesli istnieja
- if (obraz->piksele_wejsciowe != NULL)
- {
- if(obraz->typ == 3)
- {
- zwolnij_tablice_liczb(obraz->piksele_wejsciowe[0], obraz->wysokosc);
- zwolnij_tablice_liczb(obraz->piksele_wejsciowe[1], obraz->wysokosc);
- zwolnij_tablice_liczb(obraz->piksele_wejsciowe[2], obraz->wysokosc);
- }
- else if(obraz->typ == 1 || obraz->typ == 2)
- {
- zwolnij_tablice_liczb(obraz->piksele_wejsciowe[3], obraz->wysokosc);
- }
- free(obraz->piksele_wejsciowe);
- }
- // zwolni piksele wyjsciowe
- if(obraz->piksele_wyjsciowe != NULL)
- {
- if(obraz->typ == 3)
- {
- zwolnij_tablice_liczb(obraz->piksele_wyjsciowe[0], obraz->wysokosc);
- zwolnij_tablice_liczb(obraz->piksele_wyjsciowe[1], obraz->wysokosc);
- zwolnij_tablice_liczb(obraz->piksele_wyjsciowe[2], obraz->wysokosc);
- }
- else if(obraz->typ == 1 || obraz->typ == 2)
- {
- zwolnij_tablice_liczb(obraz->piksele_wyjsciowe[3], obraz->wysokosc);
- }
- free(obraz->piksele_wyjsciowe);
- }
- // zwolnij piksele tymczasowe
- if(obraz->piksele_tymczasowe != NULL)
- {
- if(obraz->typ == 3)
- {
- zwolnij_tablice_liczb(obraz->piksele_tymczasowe[0], obraz->wysokosc);
- zwolnij_tablice_liczb(obraz->piksele_tymczasowe[1], obraz->wysokosc);
- zwolnij_tablice_liczb(obraz->piksele_tymczasowe[2], obraz->wysokosc);
- }
- else if (obraz->typ == 1 || obraz->typ == 2)
- {
- zwolnij_tablice_liczb(obraz->piksele_tymczasowe[3], obraz->wysokosc);
- }
- free(obraz->piksele_tymczasowe);
- }
- // zamknij uchwyt pliku
- fclose(obraz->plik);
- }
- int czy_plik_istnieje( FILE * plik)
- {
- /*
- Argumenty: uchwyt do pliku
- Zwraca: 0 plik istnieje
- -1 plik nie istnieje
- */
- // czy plik NIE istnieje?
- if(plik == NULL) return -1;
- else return 0;
- }
- int czy_plik_jest_niepusty(FILE * plik)
- {
- /*
- Argumenty: uchwyt do pliku
- Zwraca: 0 plik nie jest pusty
- -1 plik jest pusty
- */
- // przewin na poczatek na wszelki wypadek
- rewind(plik);
- // pobierz 1 znak i sprawdz czy nie jest znakiem konca pliku
- char pierwszy_znak = fgetc(plik);
- if(pierwszy_znak == EOF) return -1;
- else return 0;
- }
- int czy_sa_wymiary(FILE * plik)
- {
- /*
- Argumenty: wskaznik na plik
- Zwraca: 0 sa podane odpowiednie wymiary
- -1 nie ma podanych odpowiednich wymiarow
- Dzialanie:
- 1. Pomija typ pliku
- 2. Pomija komentarze
- 3. Sprawdza czy istnieja dodatnie wymiary
- Funkcja ta opiera sie na formacie plikow.
- PIERWSZA LINIA w ktorej PIERWSZY ZNAK jest CYFRA to linia z wymiarami tj.
- PRZYKLAD:
- Px
- # jakies kometarze
- 100 100 <- pierwsza linia z cyfra jako 1 znak to wymiary
- Gdy dojdziemy do tej linii przerywamy przewijanie pliku
- oraz wczytujemy dane z bufora i sprawdzany nastepujace warunki:
- 1. Czy wymiar oznaczajacy szerokosc istnieje? (czy fscanf zwroci 2)
- 2. Czy wymiar oznaczajacy wysokosc istnieje? (czy fscanf zwroci 2)
- 3. Czy OBA wymiary sa wieksze od 3x3?
- Warunek 3 jest niekonieczny, gdyz niektore operacje mozna wykonac na pojedynczych
- pikselach np. negatyw.
- Jednakże obsluga takiego typu plikow znaczaco zwieksza ilosc wymaganej kontroli bledow
- oraz ma znikomy sens i dlatego nie nie sa one obslugiwane.
- */
- rewind(plik); // na wszelki wypadek przewin na poczatek
- char bufor[DL_LINII]; // bufor pomocniczy
- char * czy_koniec; // zmienna pomocnicza
- // pobierz 1 linie
- czy_koniec = fgets(bufor, DL_LINII, plik);
- do
- {
- // Pomin typ pliku
- if(bufor[0] == 'P')
- {
- // pobierz nastepna linie
- czy_koniec = fgets(bufor, DL_LINII, plik);
- continue;
- }
- // pomin komentarze
- else if(bufor[0] == '#')
- {
- // pobierz nastepna linie
- czy_koniec = fgets(bufor, DL_LINII, plik);
- continue;
- }
- // pomin linie zaczynajace sie od pustych znakow
- else if(isspace(bufor[0]))
- {
- // pobierz nastepna linie
- czy_koniec = fgets(bufor, DL_LINII, plik);
- continue;
- }
- /*
- Gdy przy czytaniu pliku po raz pierwszy pojawi sie linie, ktora nie zaczyna sie od
- P, #, \n
- To jest to linia z wymiarami. Nastapi to przy 1 wywolaniu else
- */
- else
- {
- // wypelnij wymiaru ujemnymi liczbami
- int wymx = -1, wymy = -1;
- // wczytaj wymiary z bufora
- int ilosc_wymiarow = sscanf(bufor, "%d %d", &wymx, &wymy);
- // Jesli wymiary istnieja i sa wieksze/rowne niz 3x3
- // jesli nie udalo sie wczytac chociaz jednej piksele to 2 warunki beda bledne
- // gdyz wartosc pewnego wymiaru pozostanie rowna -1 i zmienna pomocnicza nie bedzie rowna 2
- if( wymx >= 3 && wymy >= 3 && ilosc_wymiarow == 2)
- {
- return 0;
- }
- else
- {
- return -1;
- }
- }
- }
- while(czy_koniec != NULL);
- return -1;
- }
- int czy_jest_podana_skala(FILE * plik)
- {
- /*
- Argumenty: wskaznik na plik
- Zwraca: 0 Jest podana poprawna skala
- -1 nie ma podanej skali
- -2 skala jest niepoprawna np -10
- Dzialanie:
- 1. Pomija typ pliku
- 2. Pomija komentarze
- 3. Pomija wymiary
- 4. Sprawdza czy jest podana dodatnie(minimum 1) skala szarosci
- */
- // zapobiegawczo przewin na poczatek
- rewind(plik);
- char bufor[DL_LINII];
- char * czy_koniec; // zmienna pomocnicza
- // pobierz 1 linie
- czy_koniec = fgets(bufor, DL_LINII, plik);
- do
- {
- // Pomin typ pliku
- if(bufor[0] == 'P')
- {
- // pobierz nastepna linie
- czy_koniec = fgets(bufor, DL_LINII, plik);
- continue;
- }
- // pomin komentarze
- else if(bufor[0] == '#')
- {
- // pobierz nastepna linie
- czy_koniec = fgets(bufor, DL_LINII, plik);
- continue;
- }
- // pomin puste linie
- else if(isspace(bufor[0]))
- {
- // pobierz nastepna linie
- czy_koniec = fgets(bufor, DL_LINII, plik);
- continue;
- }
- else
- {
- // Pierwsza linia po komentarzach to wymiary -> Pomijamy;
- // pobierz nastepna linie -> Teoretycznie tam powinny byc odcienie
- if(fgets(bufor, DL_LINII, plik) != NULL)
- {
- // Czy ilosc odcieni istnieje i jest wieksza od 1
- int skala;
- sscanf(bufor, "%d", &skala);
- if(skala > 1)
- {
- return 0;
- }
- // jesli jest mniejsza/rowna 1 oznacza to, ze wartosc jest niepoprawna
- else
- {
- return -1;
- }
- }
- // jesli nie ma w ogole ilosci odcieni
- else
- {
- return -2;
- }
- }
- }
- while(czy_koniec != NULL);
- return -1;
- }
- int czy_jest_typ(FILE * plik)
- {
- /*
- Sprawdza czy plik ma poprawny typ
- Zwracana wartosc mozna porownac z zerem przy sprawdzaniu poprawnosci
- Zwraca :
- [1;6] jesli typ jest poprawny(typ obrazu)
- -1 jesli typ jest nie poprawny
- */
- // pojdz na poczatek
- rewind(plik);
- // pobierz 2 pierwsze znaki
- char typ[DL_LINII];
- char * czy_koniec = fgets(typ, DL_LINII, plik);
- // Zwroc typ obrazu
- if(typ[0] == 'P' && czy_koniec != NULL)
- {
- // zaleznie od typu zwroc jego wartosc
- switch(typ[1])
- {
- case '1':
- return 1;
- break;
- case '2':
- return 2;
- break;
- case '3':
- return 3;
- break;
- case '4':
- return 4;
- break;
- case '5':
- return 5;
- break;
- case '6':
- return 6;
- break;
- // gdyby byla inna cyfra np P9 to uznaj to za niepoprawny typ
- default:
- return -1;
- break;
- }
- }
- else if (typ[0] != 'P' || czy_koniec == NULL)
- {
- return -1;
- }
- return -1;
- }
- int sprawdz_poprawnosc_metadanych_pliku(FILE * plik)
- {
- /*
- Opis:
- Wczesniejsze kontrola metadanych pliku ma na celu(w takiej kolejnosci) sprawdzic:
- 1. Czy plik istnieje?
- TAK -> poinformuj i kontynuuj
- NIE -> poinformuj i zwroc -2 i wyjdz z funkcji
- 2. Czy plik jest NIEpusty?
- TAK -> poinformuj i kontynuuj
- NIE -> poinformuj i zwroc -1 i wyjdz z funkcji
- 3. Czy plik ma podany poprawny typ?
- TAK -> poinformuj, odnotuj i kontynuuj
- NIE -> poinformuj, odnotuj i kontynuuj
- 4. Czy plik ma podane wymiary?
- TAK -> poinformuj, odnotuj i kontynuuj
- NIE -> poinformuj, odnotuj i kontynuuj
- 5. Jesli plik jest typu P2 lub P3 to:
- 5.1 Czy ma podana POPRAWNA skale2?
- TAK -> poinformuj, odnotuj i kontynuuj
- NIE MA SKALI -> poinformuj, odnotuj i kontynuuj
- MA NIEPOPRAWNA -> poinformuj, odnotuj i kontynuuj
- Wykonujac te operacje jeszcze przed zabraniem sie za prace z danymi pliku,
- sprawdzic czy metadane pliku sa poprawne co wyeliminuje koniecznosc kontroli
- w trakcie dzialania programu czy np wymiary sa dodatnie albo skala jest poprawna.
- Dzialanie:
- 1. Jesli plik nie istnieje (zwroc -2) lub jest pusty(zwroc -1) nie ma sensu sprawdzac
- dalszych warunkow (2.). Poinformuj uzytkowanika co jest nie tak
- 2. Jesli plik ma niepoprawne lub nie ma: typu(P123), wymiarow(P123), skali(P23),
- poinformuj uzytkownika o tym fakcie.
- Kazda mozliwa(prawie, ale reszty sie nie da tutaj sprawdzic w prosty sposob) niepoprawnosc
- zostanie odnotowana tj.
- Jesli, ktoras wymagana wartosc nie jest prawidlowa badz nie istnieje to zmienna
- przechowujaca wartosc logiczna przyjmie -1
- Jesli, ktoras wymagana wartosc jest prawidowa to zmienna przechowujaca wartosc logiczna
- przyjmie 0
- Nastepnie sumujemy wszystkie te zmienne logiczne(oprocz czy istnieje i czy jest niepusty),
- w zmiennej, ktorej wartosc na poczatku ustawiona na 0.
- Jesli po zsumowaniu suma nadal jest rowna 0 to oznacza to, ze zadna nieprawidlowosc wystapila.
- Jesli po zsumowaniu suma jest mniejsza od 0 to funkcja zwraca -1 co oznacza, ze plik nie powinien
- zostac wczytany.
- Zwraca:
- 0 plik jest poprawny i mozna go wczytac
- -1 plik nie jest poprawny i odradza sie jego wczytywanie
- */
- // 1. Czy w ogole istnieje taki plik?
- printf("Sprawdzam poprawnosc pliku: \n");
- int czy_istnieje = czy_plik_istnieje(plik);
- if(czy_istnieje == -1)
- {
- printf("Plik o podanej nazwie nie istnieje\n");
- return -100;
- }
- else
- {
- printf("Plik o podanej nazwie istnieje\t\t 1 z 5\n");
- }
- // 2. Czy niepusty? Czy ma chociaz jeden znak?
- int czy_niepusty = czy_plik_jest_niepusty(plik);
- if(czy_niepusty == -1)
- {
- printf("Plik o podanej nazwie jest pusty\n");
- return -1;
- }
- else
- {
- printf("Plik o podanej nazwie nie jest pusty\t 2 z 5 \n");
- }
- // 3. Czy jest podany typ?
- int jaki_jest_typ = czy_jest_typ(plik); // zwraca typ lub -1
- if(jaki_jest_typ == 1 || jaki_jest_typ == 2 || jaki_jest_typ == 3)
- {
- printf("Plik ma poprawnie podany typ P%d\t \t 3 z 5 \n", jaki_jest_typ);
- }
- else if(jaki_jest_typ == -1)
- {
- printf("Plik nie ma poprawnie podanego typu badz typ nie istnieje");
- }
- // 4. czy istnieja DWA wymiary WIEKSZE od 3x3?
- int czy_podano_wymiary = czy_sa_wymiary(plik);
- if(czy_podano_wymiary == 0)
- {
- printf("Plik ma poprawne wymiary(min 3x3) \t 4 z 5\n");
- }
- else if(czy_podano_wymiary == -1)
- {
- printf("Plik nie ma poprawnych wymiarow badz nie sa one podane\n");
- }
- // czy jest podana skala(gdy typ to P2 lub P3)
- // korzystamy ze zmiennej z wczesniejszego podpunktu.
- // Gdyby sie okazalo, ze
- int czy_jest_skala;
- if(jaki_jest_typ == 2 || jaki_jest_typ == 3)
- {
- czy_jest_skala = czy_jest_podana_skala(plik);
- // gdy jest poprawna
- if(czy_jest_skala == 0)
- {
- printf("Plik na poprawna skale\t\t\t 5 z 5 \n");
- }
- // gdy jest niepoprawna tj mniejsza od 2
- else if(czy_jest_skala == -1)
- {
- printf("Plik ma niepoprawna skale\n");
- }
- // jesli nie istnieje
- else if(czy_jest_skala == -2)
- {
- printf("Plik nie ma podanej skali\n");
- }
- }
- // bledy sumarycznie
- int suma_bledow = czy_podano_wymiary + czy_jest_skala;
- if(jaki_jest_typ == -1) suma_bledow += jaki_jest_typ; // gdy nie bylo typu
- else suma_bledow += 0; // gdy byl poprawny typ
- // gdy byl przynajmniej 1 blad
- if(suma_bledow != 0)
- {
- return -1;
- }
- // gdy wszystko jest w porzadku
- else
- {
- return 0;
- }
- }
- /*****************************************************************************************************************/
- /* FUNKCJE POMOCNICZE */
- /*****************************************************************************************************************/
- int czy_jest_cyfra(char znak)
- {
- /*
- Dzialanie:
- Sprawdza czy znak z argumentu jest jest cyfra
- Zwraca:
- 1 jest
- 0 nie jest
- */
- char cyfry[10] = {'0','1','2','3','4','5','6','7','8','9'};
- for (int i = 0; i < 10; i++)
- {
- // gdy zero
- if(znak == cyfry[i] && i == 0)
- {
- return 0;
- }
- // gdy inna cyfra
- else if(znak == cyfry[i] && i != 0)
- {
- return 1;
- }
- }
- return 0;
- }
- void pobierz_typ(FILE * plik, int * typ)
- {
- /*
- Dzialanie:
- Pobiera 2 znak z 1 linii.
- W tym miejscu jest podany tym obrazu.
- Przypisuje go do zmiennej przekazanej przez argument.
- */
- char bufor[DL_LINII];
- rewind(plik);
- fgets(bufor, DL_LINII, plik);
- // typ to 2 znak z 1 linii
- *typ = atoi(bufor+1);
- }
- char** pobierz_komentarze(FILE * plik, int * ilosc_komentarzy)
- {
- /*
- Dzialanie:
- Przeszukuje plik w poszukiwaniu linii ze znakiem '#' na poczatku
- Gdy taka linie znajdzie realokuje tablice z komentarzami i zapisuje
- znaleziona linie.
- Jednoczenie przypisuje wartosc zmiennej ilosc komentarzy
- Zwraca:
- tablice 2d komentarzy
- NULL jesli nie ma komentarzy
- UWAGA: UWOLNIC POTEM PAMIEC
- */
- char bufor[DL_LINII];
- char ** komentarze = NULL;
- *ilosc_komentarzy = 0;
- while(1)
- {
- char * czy_koniec = fgets(bufor, DL_LINII, plik);
- if(czy_koniec == NULL)
- {
- break;
- }
- // Gdy jest to 1 komentarz to alokuj tablice i wiersz oraz zapisz komentarz z buforu
- if(bufor[0] == '#' && (*ilosc_komentarzy) == 0)
- {
- // Zwieksz ilosc komentarzy
- (*ilosc_komentarzy)++;
- // alokuj 1 wiersz
- komentarze = (char**) malloc(sizeof(char*));
- // alokuj 1 linie
- *komentarze = (char*) malloc(sizeof(char) * DL_LINII);
- // przekopiuj komentarz z bufora
- strcpy(*komentarze, bufor);
- }
- // Gdy jest to kolejny komentarz odpowiednio reallokuj tablice, powieksz ja i go zapisz z buforu
- else if(bufor[0] == '#' && (*ilosc_komentarzy) !=0)
- {
- // zwieksz ilosc
- (*ilosc_komentarzy)++;
- // realokuj na 1 wieksza
- komentarze = realloc(komentarze, sizeof(char**) * (*ilosc_komentarzy));
- // alokuj nowa linie
- *(komentarze + (*ilosc_komentarzy) - 1) = (char*) malloc(sizeof(char) * DL_LINII);
- // przekopiuj do nowej linii komentarz z bufora
- strcpy(*(komentarze + (*ilosc_komentarzy) -1), bufor);
- }
- }
- return komentarze;
- }
- void pobierz_wymiary(FILE * plik, int * wysokosc, int * szerokosc)
- {
- /*
- Dzialanie:
- Funkcja ta opiera sie na formacie plikow.
- PIERWSZA LINIA w ktorej PIERWSZY ZNAK jest CYFRA to linia z wymiarami tj.
- PRZYKLAD:
- Px
- # jakies kometarze
- 100 100 <- pierwsza linia z cyfra jako 1 znak to wymiary
- Gdy dojdziemy do tej linii ekstrahujemy z niej wymiary i przypisujemy do zmiennych z argumentow
- */
- char bufor[DL_LINII];
- rewind(plik); // na wszelki wypadek przewin
- int ktora_z_kolei = 0; // okresla, z ktora linia, w ktorej pierwszym znakiem jest cyfra, mamy do czynienia
- while(1)
- {
- char * czy_koniec = fgets(bufor, DL_LINII, plik);
- // gdy 1 znak jest cyfra to funkcja zwraca 1(dla 1-9) lub 0(dla zera), gdy nie -1
- if(czy_jest_cyfra(bufor[0]) == 1)
- {
- ktora_z_kolei++;
- }
- if(czy_koniec == NULL)
- {
- break;
- }
- if(ktora_z_kolei == 1)
- {
- // gdy znaleziono 1 linie z cyframi to
- sscanf(bufor, "%d %d", szerokosc, wysokosc);
- break;
- }
- }
- }
- void pobierz_skale(FILE * plik, int * skala)
- {
- /*
- Dzialanie:
- Funkcja ta opiera sie na formacie plikow typu P2 i P3.
- DRUGA LINIA w ktorej PIERWSZY ZNAK jest CYFRA to linia z odcieniami szarosci tj.
- PRZYKLAD:
- Px
- # jakies kometarze
- 100 100 <- pierwsza linia z cyfra jako 1 znak to wymiary
- 1234 <- druga -||- to skala
- Gdy dojdziemy do tej linii ekstrahujemy z niej skale i przypisujemy do zmiennej z argumentu
- */
- char bufor[DL_LINII];
- int ktora_z_kolei = 0;
- rewind(plik); // na wszelki wypadek przewin
- while(1)
- {
- char * czy_koniec = fgets(bufor, DL_LINII, plik);
- // gdy 1 znak jest cyfra to funkcja zwraca 1(dla 1-9) lub 0(dla zera), gdy nie -1
- if(czy_jest_cyfra(bufor[0]) == 1)
- {
- ktora_z_kolei++;
- }
- if(czy_koniec == NULL)
- {
- break;
- }
- if(ktora_z_kolei == 2)
- {
- sscanf(bufor, "%d", skala);
- break;
- }
- }
- }
- int *** pobierz_piksele(FILE * plik, int wysokosc, int szerokosc, int typ)
- {
- /*
- Dzialanie:
- Zaleznie od typu pobiera z danego pliku piksele
- Kazdy zestaw pikseli sklada sie z 4 dwuwymiarowych tablic intigerow, w ktorych
- 1 tablica to piksele czerwone R
- 2 tablica to piksele zielone G
- 3 tablica to piksele niebieskie B
- 4 tablica to piksele bialo czarne badz w odcieniach szarosci
- Tablice 1-3 sa wypelniane gdy natrafimy na plik typu P3.
- Tablica 4 pozostaje wtedy niewypelniana
- Tablica 4 jest wypelniana gdy natrafimy na typ P1 lub P2.
- Tablice 1-3 pozostaja wtedy niewypelniane
- UWAGA: NALEZY NA KONIEC PRACY ZE ZDJECIEM ZWOLNIC WSZYSTKIE 4 TABLICE
- TYP P1 Przyklad:
- P1
- # ewentualne komentarze
- 100 100 <- Pierwsza linia, w ktorej na poczatku jest cyfra [1-9] to na pewno wymiary
- 1 0... <- Druga linia, w ktorej na poczatku jest cyfra [0-1] to na pewno piksele
- Gdy wykryje 1 linie z cyfra przestaje skanowac dalej plik a zaczyna pobieranie wartosci
- danych pikseli i zapisywac je w piksele[4][x][y]
- TYP P2 Przyklad:
- P2
- # ewentualne komentarze
- 100 100 <- Pierwsza linia, w ktorej na poczatku jest cyfra [1-9] to na pewno wymiary
- 1024 <- Druga linia, w ktorej na poczatku jest cyfra [1-9] to na pewno skala szarosci
- 1 0... <- Trzecia linia, w ktorej na poczatku jest cyfra [0-1] to na pewno piksele
- Gdy wykryje 1 linie z cyfra przestaje skanowac dalej plik a zaczyna pobieranie wartosci
- danych pikseli i zapisywac je w piksele[4][x][y]
- TYP P3 Przyklad:
- P3
- # ewentualne komentarze
- 100 100 <- Pierwsza linia, w ktorej na poczatku jest cyfra [1-9] to na pewno wymiary
- 1024 <- Druga linia, w ktorej na poczatku jest cyfra [1-9] to na pewno skladowe kolorow
- 1 0... <- Trzecia linia, w ktorej na poczatku jest cyfra [0-1] to na pewno piksele
- Gdy wykryje 1 linie z cyfra przestaje skanowac dalej plik a zaczyna pobieranie wartosci
- danych pikseli.
- Nastepnie przypisuje dane piksele trojkami do odpowiednich tablic tj
- fscanf("%d %d %d", RED, GREEN, BLUE)
- fscanf("%d %d %d", piksele[1][x][y], piksele[1][x][y], piksele[1][x][y])
- Kontrola bledow:
- W chwili pobierania pikseli monitorujemy jaka ich ilosc udalo sie pobrac.
- W przypadku obrazow typu P1 i P2 ilosc pikseli, ktore udalo sie pobrac powinna
- byc rowna wysokosci * szerokosc.
- Jesli tak nie jest funkcja zwroci NULL
- W przypadku obrazow typu P3 dzialamy analogicznie jednakze, przy kazdej pobranej
- trojce pikseli zwiekszamy ilosc pobranych o 3, a na koncu przyrownujemy do
- 3 * wysokosc * szerokosc.
- Zwraca:
- Jesli sukces int ***
- Jesli nie udalo sie wczytac NULL
- */
- // Bufor pomocniczy do przewijania pliku
- char bufor[DL_LINII];
- // zmienna pomocnicza do liczenia pikseli, ktore udalo sie pobrac
- int ktora_z_kolei = 0;
- rewind(plik); // na wszelki wypadek przewin
- /* trojwymiarowa tablica pikseli alokacja ---------------------------------------------------------*/
- int *** piksele = (int***) malloc(sizeof(int**) * 4); // zaalokuj 3 tablice dla RGB i jedna dla odcieni szarosci
- // zaalokuj odpowiednia wierszy w kazdej tablicy
- for(int tab = 0; tab < 4; tab++)
- {
- for(int wiersz = 0; wiersz < wysokosc; wiersz++)
- {
- *(piksele + tab) = (int**) malloc(sizeof(int*) * wysokosc);
- }
- }
- // zaalokuj odpowiednia ilosc kolumn w kazdej tablicy
- for(int tab = 0; tab < 4; tab++)
- {
- for(int wiersz = 0; wiersz < wysokosc; wiersz++)
- {
- *(*(piksele + tab) + wiersz) = (int*) malloc(sizeof(int) * szerokosc);
- }
- }
- /* trojwymiarowa tablica pikseli alokacja koniec --------------------------------------------------*/
- /* Przewin do miejsca gdzie znajduja sie piksele*/
- while(1)
- {
- char * czy_koniec = fgets(bufor, DL_LINII, plik);
- // gdy 1 znak jest cyfra to funkcja zwraca 1(dla 1-9) lub 0(dla zera), gdy nie -1
- if(czy_jest_cyfra(bufor[0]) == 1)
- {
- ktora_z_kolei++;
- }
- if(czy_koniec == NULL)
- {
- break;
- }
- // Jesli typ to P1 to w tym momencie mozna zakonczyc przewijanie gdyz 1 linia to wymiary
- // po ktorych znajduja sie piksele
- if(ktora_z_kolei == 1 && typ == 1)
- {
- break;
- }
- // Jesli typ to P2 lub P3 to po 2 linii, w ktorej jako 1 znak wystepuje cyfra(skala)
- // wystepuje piksele
- if(ktora_z_kolei == 2 && (typ == 2 || typ == 3))
- {
- break;
- }
- }
- if (typ == 1 || typ == 2)
- {
- /*
- Jezeli typ pliku to 1 albo 2 to pobieramy POJEDYNCZE wartosci dla kazdego piksela
- i zapisujemy w tablicy numer 4
- */
- int ile_pikseli_wczytano = 0;
- for(int wys = 0; wys < wysokosc; wys++)
- {
- for(int szer = 0; szer < szerokosc; szer++)
- {
- // wczytuj i licz wczytane
- if(fscanf(plik, "%d", &piksele[3][wys][szer]) == 1)
- {
- ile_pikseli_wczytano++;
- }
- }
- }
- // gdy ilosc sie zgadza
- if(wysokosc*szerokosc == ile_pikseli_wczytano) return piksele;
- // gdy ilosc sie nie zgadza
- else return NULL;
- }
- if(typ == 3)
- {
- /*
- Jezeli typ pliku to 3 to piksele zapisujemy w tablicach 1,2,3, ktore odpowiedaja R G B;
- */
- int ile_pikseli_wczytano = 0;
- for(int wys = 0; wys < wysokosc; wys++)
- {
- for(int szer = 0; szer < szerokosc; szer++)
- {
- // wczytuj R G B i licz wczytane
- if(fscanf(plik, "%d %d %d", &piksele[0][wys][szer], &piksele[1][wys][szer], &piksele[2][wys][szer]) == 3)
- {
- ile_pikseli_wczytano += 3;
- }
- }
- }
- // gdy ilosc sie zgadza
- if(wysokosc*szerokosc*3 == ile_pikseli_wczytano) return piksele;
- // gdy ilosc sie nie zgadza
- else return NULL;
- }
- return NULL;
- }
- void zwolnij_tablice_znakow(char ** tablica, int ilosc_wierszy)
- {
- if(ilosc_wierszy != 0)
- {
- for(int i = 0; i< ilosc_wierszy; i++)
- {
- // kolumny
- free(*(tablica +i ));
- // i na koniec wiersze
- if(i + 1 == ilosc_wierszy) free(tablica);
- }
- }
- }
- void zwolnij_tablice_liczb(int ** tablica, int ilosc_wierszy)
- {
- if(ilosc_wierszy != 0)
- {
- for(int i =0; i< ilosc_wierszy; i++)
- {
- // kolumny
- free(*(tablica +i ));
- // i na koniec wiersze
- if(i + 1 == ilosc_wierszy) free(tablica);
- }
- }
- }
- int czy_skala_jest_prawdziwa(int ** piksele, int skala, int wysokosc, int szerokosc)
- {
- int minimum = znajdz_minimum (piksele, wysokosc, szerokosc);
- int maksimum = znajdz_maksimum(piksele, wysokosc, szerokosc);
- // gdy realne wartosci przekraczaja zadeklarowane granice
- if(minimum < 0 || maksimum > skala)
- {
- printf("Realne minimum = %d | Realne maksimum = %d\n", minimum, maksimum);
- printf("Deklarowane minimum = %d | Deklarowane maksimum = %d\n", 0, skala - 1);
- return -1;
- }
- else return 0;
- }
- int ** normalizuj(int ** piksele, int skala, int wysokosc, int szerokosc)
- {
- /*
- Dzialanie
- Normalizuje zadana tablice liczb(pikseli) by byly w odpowiednim przedziale szarosci
- Pozbywa sie elementow odstajacych (otlier)
- Zwraca: Znormalizowana tablice
- */
- int minimum = znajdz_minimum (piksele, wysokosc, szerokosc); // znajdz realne minimum
- int maksimum = znajdz_maksimum(piksele, wysokosc, szerokosc); // znajdz realne maksimum
- // alokuj znormalizowana tablice
- int ** znormalizowana_tablica = (int**) malloc(sizeof(int*) * wysokosc);
- for(int i =0; i< szerokosc; i++)
- {
- *(znormalizowana_tablica + i) = (int*)malloc(sizeof(int) * szerokosc);
- }
- // wykonaj operacje
- for(int wys = 0; wys < wysokosc; wys++)
- {
- for(int szer = 0; szer < szerokosc; szer++)
- {
- // rzutowania na double bo na liczbach calkowitych nie da sie poprawnie wykonac takich dzialan
- // dziele na licznik i mianownik dla przejrzystosci
- double licznik = (double)(piksele[wys][szer] - minimum) * (double) skala;
- double mianownik = (double)(maksimum - minimum);
- znormalizowana_tablica[wys][szer] = (int)(licznik / mianownik);
- }
- }
- return znormalizowana_tablica;
- }
- int znajdz_minimum(int ** piksele, int wysokosc, int szerokosc)
- {
- int minimum = piksele[0][0];
- for(int i = 0; i < wysokosc; i++)
- {
- for(int e =0; e< szerokosc; e++)
- {
- if(piksele[i][e] < minimum)
- {
- minimum = piksele[i][e];
- }
- }
- }
- return minimum;
- }
- int znajdz_maksimum(int ** piksele, int wysokosc, int szerokosc)
- {
- int maksimum = piksele[0][0];
- for(int i = 0; i < wysokosc; i++)
- {
- for(int e = 0; e< szerokosc; e++)
- {
- if(piksele[i][e] > maksimum)
- {
- maksimum = piksele[i][e];
- }
- }
- }
- return maksimum;
- }
- int ** negatyw(int ** piksele, int skala, int wysokosc, int szerokosc)
- {
- /*
- Dzialanie:
- Wykonuje operacje na tablicy liczb pobranych jako 1 argument(pikseli)
- Wynik dzialania na piksele[x][y] zapisuje w odpowiadajacym jej miejsci nowe_piksele[x][y]
- Zwraca:
- Nowa tablice 2d liczb(pikseli), ktora nalezy przypisac do pikseli wyjsciowych
- */
- int ** nowe_piksele = (int**) malloc(sizeof(int*) * wysokosc); // (n)owe (piksele) - tablica wynikowa po operacji
- for(int i =0; i < wysokosc; i++)
- {
- *(nowe_piksele + i) = (int*) malloc(sizeof(int) * szerokosc);
- }
- for(int i = 0; i < wysokosc; i++)
- {
- for(int e = 0; e < szerokosc; e++)
- {
- nowe_piksele[i][e] = skala - piksele[i][e];
- }
- }
- return nowe_piksele;
- }
- int ** progowanie(int ** piksele, int skala, int wysokosc, int szerokosc)
- {
- /*
- Dzialanie:
- Wykonuje operacje na tablicy liczb pobranych jako 1 argument(pikseli)
- Wynik dzialania na piksele[x][y] zapisuje w odpowiadajacym jej miejsci nowe_piksele[x][y]
- Zwraca:
- Nowa tablice 2d liczb(pikseli), ktora nalezy przypisac do pikseli wyjsciowych
- */
- int ** nowe_piksele = (int**) malloc(sizeof(int*) * wysokosc); // (n)owe (piksele) - tablica wynikowa po operacji
- int prog_proc; // okresla jaki procent skali ma byc progiem
- int prog_wart; // wartosc progu jako liczba calkowita
- // pobierz wartosc procentowa progu i wylicz wartosc liczbowa
- printf("Podaj wartosc progu(procentowo): ");
- scanf("%d", &prog_proc);
- prog_wart = (prog_proc * skala) / 100;
- // zaalokuj potrzebna ilosc kolumn
- for(int i =0; i < wysokosc; i++)
- {
- *(nowe_piksele + i) = (int*) malloc(sizeof(int) * szerokosc);
- }
- // oblicz nowa tablice
- for(int i = 0; i < wysokosc; i++)
- {
- for(int e = 0; e < szerokosc; e++)
- {
- // jesli powyzej progu to daj maksymalna wartosc szarosci piksela (bialy)
- if(piksele[i][e] > prog_wart)
- {
- nowe_piksele[i][e] = skala - 1; // -1 bo majac ilosc odcieni np 255 najwyzsza jest 254
- }
- // jesli poniezej progu to daj minimalna wartosc szarosci piksela(czern)
- else
- {
- nowe_piksele[i][e] = 0;
- }
- }
- }
- return nowe_piksele;
- }
- int ** polprogowanie_czerni(int ** piksele, int skala, int wysokosc, int szerokosc)
- {
- /*
- Dzialanie:
- Wykonuje operacje na tablicy liczb pobranych jako 1 argument(pikseli)
- Wynik dzialania na piksele[x][y] zapisuje w odpowiadajacym jej miejsci nowe_piksele[x][y]
- Zwraca:
- Nowa tablice 2d liczb(pikseli), ktora nalezy przypisac do pikseli wyjsciowych
- */
- int ** nowe_piksele = (int**) malloc(sizeof(int*) * wysokosc);
- int prog_proc; // wartosc procentowa dla progu
- int prog_wart; // wartosc liczbowa
- // pobierz wartosc procentowa i przelicz na liczbowa
- printf("Podaj wartosc progu(procentowo): ");
- scanf("%d", &prog_proc);
- prog_wart = (prog_proc * skala) / 100;
- // alokuj kolumny
- for(int i =0; i < wysokosc; i++)
- {
- *(nowe_piksele + i) = (int*) malloc(sizeof(int) * szerokosc);
- }
- // wykonaj operacje
- for(int i = 0; i < wysokosc; i++)
- {
- for(int e = 0; e < szerokosc; e++)
- {
- // powyzej progu zostaw wastosc
- if(piksele[i][e] > prog_wart)
- {
- nowe_piksele[i][e] = piksele[i][e];
- }
- // ponizej progu daj minimalna wartosc(czern)
- else
- {
- nowe_piksele[i][e] = 0;
- }
- }
- }
- return nowe_piksele;
- }
- int ** polprogowanie_bieli(int ** piksele, int skala, int wysokosc, int szerokosc)
- {
- /*
- Dzialanie:
- Wykonuje operacje na tablicy liczb pobranych jako 1 argument(pikseli)
- Wynik dzialania na piksele[x][y] zapisuje w odpowiadajacym jej miejsci nowe_piksele[x][y]
- Zwraca:
- Nowa tablice 2d liczb(pikseli), ktora nalezy przypisac do pikseli wyjsciowych
- */
- int ** nowe_piksele = (int**) malloc(sizeof(int*) * wysokosc);
- int prog_proc; // wartosc procentowa progu
- int prog_wart; // wartosc liczbowa progu
- // pobierz wartosc procentowa i przelicz na liczbowa
- printf("Podaj wartosc progu(procentowo): ");
- scanf("%d", &prog_proc);
- prog_wart = (prog_proc * skala) / 100;
- // alokuj kolumny
- for(int i =0; i < wysokosc; i++)
- {
- *(nowe_piksele + i) = (int*) malloc(sizeof(int) * szerokosc);
- }
- // wykonaj operacje
- for(int i = 0; i < wysokosc; i++)
- {
- for(int e = 0; e < szerokosc; e++)
- {
- // jesli ponizej progu to zostaw wartosc
- if(piksele[i][e] <= prog_wart)
- {
- nowe_piksele[i][e] = piksele[i][e];
- }
- // jesli powyzej to daj maksymalna wartosc(biel)
- else
- {
- nowe_piksele[i][e] = skala -1; // -1 bo majac np 255 odcieni szarosci maksymalna wartosc to 254
- }
- }
- }
- return nowe_piksele;
- }
- int ** korekcja_gamma(int ** piksele, int skala, int wysokosc, int szerokosc)
- {
- /*
- Dzialanie:
- Wykonuje operacje na tablicy liczb pobranych jako 1 argument(pikseli)
- Wynik dzialania na piksele[x][y] zapisuje w odpowiadajacym jej miejsci nowe_piksele[x][y]
- Zwraca:
- Nowa tablice 2d liczb(pikseli), ktora nalezy przypisac do pikseli wyjsciowych
- */
- double gamma; // wartosc parametru gamma
- int ** nowe_piksele = (int**) malloc(sizeof(int*) * wysokosc);
- // pobierz wartosc parametru gamma*10.0 i wylicz odpowiednia wartosc
- printf("Podaj wartosc parametru gamma(pomnozona przez 10 np. jesli chcesz 0.5 podaj 5):");
- scanf("%le", &gamma);
- gamma = gamma/10.0;
- // alokuj kolumny
- for(int i =0; i < wysokosc; i++)
- {
- *(nowe_piksele + i) = (int*) malloc(sizeof(int) * szerokosc);
- }
- // wykonaj operacje
- for(int i = 0; i < wysokosc; i++)
- {
- for(int e = 0; e < szerokosc; e++)
- {
- // oblicza osobno liczni i mianownik dla uproszzcenia wyrazenia i przejrzystosci
- double licznik = pow((double) piksele[i][e], 1.0/ gamma);
- double mianownik = pow((double) skala, (1.0 - gamma)/gamma);
- nowe_piksele[i][e] = (int) licznik / mianownik;
- }
- }
- return nowe_piksele;
- }
- int ** zmiana_poziomow(int ** piksele, int skala, int wysokosc, int szerokosc)
- {
- /*
- Dzialanie:
- Wykonuje operacje na tablicy liczb pobranych jako 1 argument(pikseli)
- Wynik dzialania na piksele[x][y] zapisuje w odpowiadajacym jej miejsci nowe_piksele[x][y]
- Zwraca:
- Nowa tablice 2d liczb(pikseli), ktora nalezy przypisac do pikseli wyjsciowych
- */
- // pobierz prog bieli i czerni
- int czern, biel;
- int ** nowe_piksele = (int**) malloc(sizeof(int*) * wysokosc);
- do
- {
- printf("Podaj wartosc progow czern/biel przedzielone przecinkiem \n");
- scanf("%d,%d", &czern, &biel);
- } while(!(czern > 0 && biel < skala)); // majac ilosc odcieni np 100 nie mozna dac progu bieli 101, a czerni -1,
- // Ponadto prog czerni nie ma sensu gdy jest rowny 0
- // gdyz wtedy ta operacja jest progowaniem czerni, ktore jest juz
- // zaimplementowane w innej funkcji
- // alokuj kolumny
- for(int i = 0; i < wysokosc; i++)
- {
- *(nowe_piksele + i) = (int*) malloc(sizeof(int) * szerokosc);
- }
- // wykonaj operacje
- for(int i = 0; i < wysokosc; i++)
- {
- for(int e = 0; e < szerokosc; e++)
- {
- // ponizej progu czerni ustaw na czern
- if(piksele[i][e] < czern)
- {
- nowe_piksele[i][e] = 0;
- }
- // pomiedzy progiem czerni a bieli zostaw jak jest
- else if(piksele[i][e] > czern && piksele[i][e] < biel)
- {
- nowe_piksele[i][e] = piksele[i][e];
- }
- // powyzej progu bieli ustaw na biel
- else if(piksele[i][e] > biel)
- {
- nowe_piksele[i][e] = skala - 1; // -1 bo najwyzsza wartosc jest o 1 mniejsza niz ilosc odcieni szarosci
- }
- }
- }
- return nowe_piksele;
- }
- int ** konturowanie(int ** piksele, int wysokosc, int szerokosc)
- {
- /*
- Dzialanie:
- Wykonuje operacje na tablicy liczb pobranych jako 1 argument(pikseli)
- Wynik dzialania na piksele[x][y] zapisuje w odpowiadajacym jej miejsci nowe_piksele[x][y]
- Zwraca:
- Nowa tablice 2d liczb(pikseli), ktora nalezy przypisac do pikseli wyjsciowych
- */
- int ** nowe_piksele = (int**) malloc(sizeof(int*) * wysokosc);
- // zaalokuj kolumny
- for(int i =0; i < wysokosc; i++)
- {
- *(nowe_piksele + i) = (int*) malloc(sizeof(int) * szerokosc);
- }
- // wykonaj operacje
- for(int i = 1; i < wysokosc - 1; i++)
- {
- for(int e = 1; e < szerokosc - 1; e++)
- {
- nowe_piksele[i][e] = abs(piksele[i+1][e] - piksele[i][e]) + abs(piksele[i][e+1] - piksele[i][e]);
- }
- }
- return nowe_piksele;
- }
- int ** rozmycie_poziome(int ** piksele, int wysokosc, int szerokosc)
- {
- /*
- Dzialanie:
- Wykonuje operacje na tablicy liczb pobranych jako 1 argument(pikseli)
- Wynik dzialania na piksele[x][y] zapisuje w odpowiadajacym jej miejsci nowe_piksele[x][y]
- Zwraca:
- Nowa tablice 2d liczb(pikseli), ktora nalezy przypisac do pikseli wyjsciowych
- */
- int ** nowe_piksele = (int**) malloc(sizeof(int*) * wysokosc);
- // zaalokuj kolumny
- for(int i =0; i < wysokosc; i++)
- {
- *(nowe_piksele + i) = (int*) malloc(sizeof(int) * szerokosc);
- }
- // wykonaj operacje TODO dowolny promien v2
- for(int i = 1; i < wysokosc - 1; i++)
- {
- for(int e = 1; e < szerokosc - 1; e++)
- {
- nowe_piksele[i][e] = (piksele[i][e+1] + piksele[i][e] + piksele[i][e+1]) / 3;
- }
- }
- return nowe_piksele;
- }
- int ** rozmycie_pionowe(int ** piksele, int wysokosc, int szerokosc)
- {
- /*
- Dzialanie:
- Wykonuje operacje na tablicy liczb pobranych jako 1 argument(pikseli)
- Wynik dzialania na piksele[x][y] zapisuje w odpowiadajacym jej miejsci nowe_piksele[x][y]
- Zwraca:
- Nowa tablice 2d liczb(pikseli), ktora nalezy przypisac do pikseli wyjsciowych
- */
- int ** nowe_piksele = (int**) malloc(sizeof(int*) * wysokosc);
- // zaalokuj kolumny
- for(int i =0; i < wysokosc; i++)
- {
- *(nowe_piksele + i) = (int*) malloc(sizeof(int) * szerokosc);
- }
- // wykonaj operacje TODO dowolny promien v2
- for(int i = 1; i < wysokosc - 1; i++)
- {
- for(int e = 1; e < szerokosc - 1; e++)
- {
- nowe_piksele[i][e] = (piksele[i+1][e] + piksele[i][e] + piksele[i-1][e]) / 3;
- }
- }
- return nowe_piksele;
- }
- int ** rozciagniecie_histogramu(int ** piksele, int skala, int wysokosc, int szerokosc)
- {
- /*
- Dzialanie:
- Wykonuje operacje na tablicy liczb pobranych jako 1 argument(pikseli)
- Wynik dzialania na piksele[x][y] zapisuje w odpowiadajacym jej miejsci nowe_piksele[x][y]
- Zwraca:
- Nowa tablice 2d liczb(pikseli), ktora nalezy przypisac do pikseli wyjsciowych
- */
- int ** nowe_piksele = (int**) malloc(sizeof(int*) * wysokosc);
- int minimum = znajdz_minimum (piksele, wysokosc, szerokosc); // znajduje realne minimum w tablicy
- int maksimum = znajdz_maksimum(piksele, wysokosc, szerokosc); // znajduje realne maksimum w tablicy
- for(int i =0; i < wysokosc; i++)
- {
- *(nowe_piksele + i) = (int*) malloc(sizeof(int) * szerokosc);
- }
- for(int i = 1; i < wysokosc - 1; i++)
- {
- for(int e = 1; e < szerokosc - 1; e++)
- {
- nowe_piksele[i][e] = ((piksele[i][e] - minimum) * skala)/(maksimum - minimum);
- }
- }
- return nowe_piksele;
- }
- int ** operacje_z_uzyciem_masek(int ** piksele, int skala, int wysokosc, int szerokosc, int ** maska)
- {
- // alokuj nowe piksele
- int ** nowe_piksele = (int**) malloc(sizeof(int*) * wysokosc);
- for(int i =0; i < wysokosc; i++)
- {
- *(nowe_piksele + i) = (int*) malloc(sizeof(int) * szerokosc);
- }
- // osobno piksele wynik z gornego, srodkowego i dolnego rzedu, by pojedyncza linia nie byla zbyt dluga
- for(int i = 1; i < wysokosc -1; i++)
- {
- for(int e = 1; e < szerokosc - 1; e++)
- {
- int gorny_rzad = maska[0][0] * piksele[i-1][e-1] + maska[0][1] * piksele[i-1][e] + maska[0][2] * piksele[i-1][e+1];
- int srodkowy_rzad = maska[1][0] * piksele[i] [e-1] + maska[1][1] * piksele[i] [e] + maska[1][2] * piksele[i] [e+1];
- int dolny_rzad = maska[2][0] * piksele[i+1][e-1] + maska[2][1] * piksele[i+1][e] + maska[2][2] * piksele[i+1][e+1];
- int suma = gorny_rzad + srodkowy_rzad + dolny_rzad;
- nowe_piksele[i][e] = suma;
- }
- }
- // normalizuj do wymaganego przedzialu( pozbywa sie elementow odstajacych(outlier))
- nowe_piksele = normalizuj(nowe_piksele, skala, wysokosc, szerokosc);
- return nowe_piksele;
- }
- int ** zwroc_zaalokowana_maske(int maska[3][3])
- {
- // alokuj maske
- int ** maska_do_zwrocenia = (int**) malloc(sizeof(int*) * 3);
- for(int i = 0; i < 3; i++)
- {
- *(maska_do_zwrocenia + i) = (int*)malloc(sizeof(int) *3);
- }
- for(int i = 0; i < 3; i++)
- {
- for(int e = 0; e < 3; e++)
- {
- *(*(maska_do_zwrocenia + i) + e) = maska[i][e];
- }
- }
- return maska_do_zwrocenia;
- }
- int ** wybor_maski()
- {
- // identycznosc na wypadek zlego wyboru maski
- int idn [3][3] = {{0, 0, 0},
- {0, 1, 0},
- {0, 0, 0}};
- // dolnoprzepustowe - redukcja lokalnych roznic jasnosci--------------------------------------------
- int usr [3][3] = {{1, 1, 1},
- {1, 1, 1},
- {1, 1, 1}};
- int usr_wzm [3][3] = {{1, 1, 1},
- {1, 2, 1},
- {1, 1, 1}};
- // gornoprzepustowe - wyodrebnianie kontury/krawedzie-----------------------------------------------
- //krawedzie
- int roberts [3][3] = {{ 0, 0, 0},
- {-1, 0, 0},
- { 0, 1, 0}};
- //linie poziome
- int prewit_poziom [3][3] = {{-1, -1, -1},
- { 0, 0, 0},
- { 1, 1, 1}};
- //linie pionowe
- int prewit_pion [3][3] = {{ 1, 0, -1},
- { 1, 0, -1},
- { 1, 0, -1}};
- // maski sobela - wyodrebnianie linii ---------------------------------------------------------------
- // poziomych
- int sobel_poziom [3][3] = {{-1, -2, -1},
- { 0, 0, 0},
- { 1, 2, 1}};
- // pionowych
- int sobel_pion [3][3] = {{-1, 0, 1},
- {-2, 0, 2},
- {-1, 0, 1}};
- // krawedzie i kontury naraz ------------------------------------------------------------------------
- int lapsjan1 [3][3] = {{ 1, -2, 1},
- {-2, 4, -2},
- { 1, -2, 1}};
- int lapsjan2 [3][3] = {{ 0, -1, 0},
- {-1, 4, -1},
- { 0,- 1, 0}};
- int lapsjan3 [3][3] = {{-1, -1, -1},
- {-1, 8, -1},
- {-1, -1, -1}};
- int wybor_maski;
- printf("Maski do wyboru:\n");
- printf("1. Usredniajaca\n");
- printf("2. Usredniajaca ze wzmocnieniem\n");
- printf("3. Robertsa\n");
- printf("4. Pozioma Prewita\n");
- printf("5. Pionowa Prewita\n");
- printf("6. Pozioma Sobela\n");
- printf("7. Pionowa Sobela\n");
- printf("8. Slaby lapsjan\n");
- printf("9. Sredni lapsjan\n");
- printf("10. Mocny lapsjan\n");
- printf("11. Stworz wlasna maske\n");
- printf("Twoj wybor: ");
- scanf("%d", &wybor_maski);
- printf("|------------------------------------------------------|\n");
- switch(wybor_maski)
- {
- case 1:
- return zwroc_zaalokowana_maske(usr);
- break;
- case 2:
- return zwroc_zaalokowana_maske(usr_wzm);
- break;
- case 3:
- return zwroc_zaalokowana_maske(roberts);
- break;
- case 4:
- return zwroc_zaalokowana_maske(prewit_poziom);
- break;
- case 5:
- return zwroc_zaalokowana_maske(prewit_pion);
- break;
- case 6:
- return zwroc_zaalokowana_maske(sobel_poziom);
- break;
- case 7:
- return zwroc_zaalokowana_maske(sobel_pion);
- break;
- case 8:
- return zwroc_zaalokowana_maske(lapsjan1);
- break;
- case 9:
- return zwroc_zaalokowana_maske(lapsjan2);
- break;
- case 10:
- return zwroc_zaalokowana_maske(lapsjan3);
- break;
- case 11:
- // tworzenie wlasnej maski
- {
- int wlasna[3][3];
- printf("Prosze podac wartosci maski w formacie x,x,x \n");
- for(int i = 0; i < 3; i++)
- {
- printf("Rzad numer %d:", i+1);
- scanf("%d,%d,%d", &wlasna[i][0], &wlasna[i][1], &wlasna[i][2]);
- }
- return zwroc_zaalokowana_maske(wlasna);
- break;
- }
- default:
- printf("Nieprawidlowy wybor maski. Zwracam identycznosc. \n((0 0 0)\n(0 1 0)\n(0 0 0)\n");
- return zwroc_zaalokowana_maske(idn);
- break;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement