-
Notifications
You must be signed in to change notification settings - Fork 0
razvanalex/Image-Processing
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
------------------------------------------------------------------------------- Image Processing ------------------------------------------------------------------------------- AUTOR Smadu Razvan-Alexandru 315CB FISIERE INCLUSE image_processing.c bmp_header.h Makefile README README Pregatiri pentru rezolvarea task-urilor Citirea datelor se face din fisierul "input.txt". Deschiderea acestui fisier se face prin functia open_file_read(FILE*, char*, char) care poate deschide un fisier in modul text 't' sau binar 'b'. In cazul in care fisierul nu exista sau modul introdus nu este 't' sau 'b' va fi returnata eroare. Prima oara se parcurge fisierul pentru a se numara caracterele, fiind util in alocarea string-urilor cu dimensiunea minima (lungimea cuvantului + 1). Pentru aceasta este folosita functia sizeof_line(FILE*). Aceasta functie returneaza numarul de caractere de la pozitia curenta (unde este pozitionat cursorul) pana la finalul randului, inclusiv caracterul '\n'. Aceasta functie poate fi folosita si pentru a exclude o linie, sau mai multe pentru citire. Se reia citirea fisierului, acum pentru popularea variablilelor. Dupa aceasta operatie, se deschide fisierul cu numele din image_filename si se citesc header-ele, gap-ul dintre info header si pixel array, si apoi se citeste matricea de pixeli prin functia read_bit_map(FILE*, T_pixel***, int). In aceasta functie, padding-ul este ignorat prin fseek(), calcularea acestuia facandu-se in main(), prin intermediul functiei calculate_padding( T_bmp_fileheader, T_bmp_infoheader). In final se copiaza imaginea pentru rezolvarea task-ului 1. Explicarea constantelor definite MIN_PX_VAL - reprezinta valoarea minima pe care o poate avea un pixel pe un canal (0) MAX_PX_VAL - reprezinta valoarea maxima pe care o poate avea un pixel pe un canal (255) EXTENTION_LENGTH - reprezinta numarului de caractere din extensia imaginii (in acest caz "BMP") (3) FILTERS_NUM - reprezinta numarul de filtre care sunt aplicate imaginii (3) DEFAULT_TMP_MEMORY - reprezina valoare initiala a vectorului queue care retine unde pixelii north si south (mai multe detalii in sectiunea Task 3) (512) SIZEOF_CHUNK - dimensiunea unui tuplu de forma ((short)X, (short)Y, (unsigned char)R, (unsigned char)G, (unsigned char)B) (7) ERROR - reprezinta valoarea de iesire a functiilor atunci cand se returneaza o eroare de alocare, existenta fisier etc. (-1) MAX_IMG_HEIGHT - inaltimea maxima specificata in cerinta (2500) Explicare structuri T_bmp_fileheader - tipul care retine informatiile din File Header T_bmp_infoheader - tipul care retine informatiile din Info Header T_pixel - tipul care retine culoarea pixelilor T_point - tipul care retine coordonatele pixelilor Task 1 In urma citirii imaginii, se aplica efectul de alb-negru prin functia make_black_white(T_pixel**, int, int) care face media canalelor (R + G + B) / 3 si apoi o aplica fiecarui canal in parte (pe R, pe G si pe B). Dupa ce s-a prelucrat matricea de pixeli, se creaza poza generata prin intermediul functiei Create_BMP_file(T_bmp_fileheader, T_bmp_infoheader, char**, T_pixel**, FILE*) care adauga File Header-ul, Info Headerul, gap-ul, si matricea de pixeli, la finalul fiecarei linii din matrice, adaugandu-se si padding-ul. Dupa crearea BMP-ului se copiaza imaginea pentru rezolvarea task-ului urmator. Task 2 Acest task este rezolvat prin functia apply_all_filters(T_bmp_fileheader*, T_bmp_infoheader*, char**, T_pixel**, char**) care contine matricile celor 3 filtre, si prefixele. Pentru fiecare filtru in parte, se copiaza imaginea prin Copy_Image(T_pixel***, T_pixel**, int, int), se genereaza noul nume prin functia generate_new_name(char*, char*) si apoi se aplica filtrul de culoare prin apply_filter(T_pixel***, int, int, int) care functioneaza astfel: Se creaza o matrice auxiliara pe care se va crea noua imagine si apoi se calculeaza fiecare canal pentru noua imagine. In cazul in care pixelul nu are 8 vecini, se iau in considerare doar cei care exista (avand acelasi efect ca si atunci cand se aduna 0 pentru pixelii din afara). Daca valoarea obtinuta este mai mare decat MAX_PX_VAL sau mai mica decat MIN_PX_VAL atunci se va realiza corectia. In final se returneaza noua imagine prin intermediul variabilei ***image. Aceasta matrice este apoi introdusa intr-o noua imagine. La final se elibereaza memoria nenecesara. Task 3 Acest tastk este rezolvat de catre functiile compress_image(T_pixel**, int, int, int) care realizeaza compresia pixelilor si compress_BMP_file( T_bmp_fileheader, T_bmp_infoheader, char**, T_pixel**, FILE*) care creaza formatul compresat. Pentru a comprima pixelii, s-a folosit o matrice care retine daca s-a trecut printr-un pixel, o data. Pentru fiecare pixel nevizitat se aplica algoritmul de compresie, realizat de functia flood_fill(T_pixel**, int, int, int, int, int, T_pixel, int**): - Se creaza un vector coada, initial cu dimensiunea DEFAULT_TMP_MEMORY. - Se initializeaza prima valoare cu pixelul de referinta - Pentru fiecare pixel din coada: - se cauta o linie pe axa Ox, care indeplineste contitia de a apartine zonei dorite, dar care contine pixeli nevizitati (prin deplasarea spre vest si est, de la pixelul din coada) - se fac pixelii de culoarea dorita pe linia gasita - pentru fiecare pixel din aceasta linie se cauta vecini in nord si sud care satisfac contidia necesara. Acestia se adauga in vectorul queue - in cazul in care vectorul este plin, se dubleaza valoarea curenta a memoriei pentru coada (acest lucru poate evita segmentarea memoriei). - dupa ce a fost folosit, se sterge pixelul din coada (reduce memoria, dar creste timpul executiei) La urma se elibereaza memoria nenecesara. Dupa aplicarea acestui algoritm, poza e gata pentru a fi pusa in fisierul binar. In acesta se adauga header-ele, gap-ul si apoi cvintuplurile (X,Y,R,G,B). Acestea sunt create astfel: pentru fiecare pixel se verifica daca are 4 vecini de aceeasi culoare prin functia count_neighbors(T_pixel**, int, int, T_point), iar in caz afirmativ, acestia vor fi ignorati. In cazul contrar, se incrementeaza coordonatele (ele fiind retinute pornind de la (0,0)), si se introduc impreuna cu cele 3 canale ale pixelului. Task 4 Acest task este realizat prin functia decompress_BMP_file( T_bmp_fileheader*, T_bmp_infoheader*, char**, T_pixel***, FILE*). Aceasta citeste header-ele, gap-ul si se calculeaza numarul de cvintupluri (chunk-uri de date) astfel: pozitia curenta (imediat dupa gap) se scade din dimensiunea binarului si rezulta dimensiunea blocului de cvintupluri, care apoi se imparte la dimensiunea chunk-ului. Se citesc primele doua cvintupluri (daca exista), se verifica daca sunt pe aceeasi coloana si, daca au aceeasi culoare, diferenta de pixeli care lipsesc. Acestia sunt completati in matricea de pixeli. Aceasta operatie se repeta pana la finalul fisierului binar. Urmeaza apoi generarea fisierului BMP. Aceasta operatie este facuta de catre Create_BMP_file(), avand toate elementele necesare. La final se elibereaza memoria nenecesara si se inchid fisierele. Observatii si note - In majoritatea functiilor au fost implementate verificari de alocare de memorie si daca se lucreaza cu fisiere care exista. In cazul in care este aruncata o eroare, atunci se returneaza -1, se elibereaza memoria si se incheie executia, fiind afisat la stderr, ce eroare a aparut. - Functia Free_All_Memory(const char*, ...) a fost implementata pentru a reduce numarul de linii pentru eliberarea memoriei. String-ul de formatare poate contine: %c pentru un pointer la char si %b pentru o matrice de T_pixel. Pentru %b este necesara introducerea a doua argumente: adresa matricii si inaltimea acesteia (numarul ce linii). Se returneaza numarul de dezalocari efectuat cu succes. - Citirea header-elor se putea face si direct printr-o singura instructiune (datorida macro-ului pack(1)), dar am ales varianta mai lunga pentru siguranta si pentru a controla exact ceea ce se pune in fisierul binar. Teste (realizate cu Visual Studio 2013) Valorile pot sa difere de la dispozitiv la dispozitiv, avand doar caracter orientativ. Toate testele din cadrul checker-ului au fost trecute cu timpi sub 30 secunde (luat in considerare si timpul de verificare a testelor) pe checker-ul local. 1. Imagine: airplane.bmp Threshold: 100 Binar: compressed.bin (generat pe airplane.bmp cu 100) Timp executie: aprox. 10 secunde Valoarea maxima a memoriei alocate: 28.7 Mb 2. Imagine: camaro.bmp Threshold: 120 Binar: camaro.bin Timp executie: aprox. 14 secunde Valoarea maxima a memoriei alocate: 28.8 Mb 3. (cel mai nefavorabil caz) Imagine: Untitled.bmp (poza de culoare alb (255,255,255), 2500x2500) Threshold: 10 Binar: compressed.bin (generat pe Untitled.bmp cu 10) Timp executie: aprox. 1 minut si 40 secunde Valoarea maxima a memoriei alocate: 77.8 Mb
About
No description, website, or topics provided.
Resources
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published