· 7 years ago · Dec 26, 2018, 04:32 PM
1#define _CRT_SECURE_NO_WARNINGS
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5#include <math.h>
6
7struct pixel {
8 unsigned char R, G, B;
9};
10
11struct detectie {
12 unsigned int x, y, latime, inaltime, sablon;
13 float corr;
14};
15
16unsigned int grayscaleImage(char* nume_fisier_sursa, char* nume_fisier_destinatie, int okType)
17{
18 FILE *fin, *fout;
19 unsigned int dim_img, latime_img, inaltime_img;
20 unsigned char aux, *pRGB = (unsigned char*)malloc(3);
21 int i, j;
22
23 fin = fopen(nume_fisier_sursa, "rb");
24 if (fin == NULL)
25 {
26 printf("Nu am gasit imaginea sursa din care citesc.\n");
27 return 0;
28 }
29 fout = fopen(nume_fisier_destinatie, "wb+");
30
31 fseek(fin, 2, SEEK_SET);
32 fread(&dim_img, sizeof(unsigned int), 1, fin);
33
34 fseek(fin, 18, SEEK_SET);
35 fread(&latime_img, sizeof(unsigned int), 1, fin);
36 fread(&inaltime_img, sizeof(unsigned int), 1, fin);
37
38 if(okType) printf("\nTransformare grayscale..");
39 fseek(fin, 0, SEEK_SET);
40 unsigned char c; // copiem headerul
41 for (i = 0; i < 54; i++)
42 {
43 fread(&c, 1, 1, fin);
44 fwrite(&c, 1, 1, fout);
45 fflush(fout);
46 }
47
48 int padding;
49 if (latime_img % 4 != 0)
50 padding = 4 - (3 * latime_img) % 4;
51 else
52 padding = 0;
53
54 if (okType) printf(".");
55 for (i = 0; i < inaltime_img; i++)
56 {
57 for (j = 0; j < latime_img; j++)
58 {
59 fread(pRGB, 1, 3, fin);
60 aux = 0.299*pRGB[2] + 0.587*pRGB[1] + 0.114*pRGB[0];
61 pRGB[0] = pRGB[1] = pRGB[2] = aux;
62 fwrite(pRGB, 1, 3, fout);
63 fflush(fout);
64 }
65 if (padding)
66 {
67 fread(pRGB, 1, padding, fin);
68 fwrite(pRGB, 1, padding, fout);
69 }
70 if (okType) if (i % 128 == 0) //vizualizare progres
71 printf(".");
72 }
73 if (okType) printf("\n");
74 fclose(fin);
75 fclose(fout);
76 return dim_img;
77}
78
79void xorshift32_C1(unsigned int **R, unsigned int n, unsigned int seed)
80{
81 unsigned int r = seed;
82
83 (*R) = (unsigned int*)malloc(n * sizeof(unsigned int));
84
85 (*R)[0] = r;
86 int k;
87 for (k = 1; k < n; k++)
88 {
89 r = r ^ r << 13;
90 r = r ^ r >> 17;
91 r = r ^ r << 5;
92 (*R)[k] = r;
93 }
94}
95
96void pDurstenfeld(unsigned int **P, unsigned int n, unsigned int *R)
97{
98 unsigned int r, k, rk, aux;
99
100 (*P) = (unsigned int*)malloc(n * sizeof(unsigned int));
101
102 for (k = 0; k < n; k++)
103 (*P)[k] = k;
104
105 rk = 1;
106 for (k = n - 1; k > 0; k--)
107 {
108 r = R[rk] % (k + 1);
109 aux = (*P)[r];
110 (*P)[r] = (*P)[k];
111 (*P)[k] = aux;
112 rk++;
113 }
114}
115
116void inversaPerm(unsigned int **P, unsigned int n)
117{
118 unsigned int *invP = (unsigned int*)malloc(n * sizeof(unsigned int));
119 int i;
120 for (i = 0; i < n; i++)
121 invP[(*P)[i]] = i;
122
123 for (i = 0; i < n; i++)
124 (*P)[i] = invP[i];
125 free(invP);
126}
127
128int getSecretKeys(char *nume_fisier_secret_key, unsigned int *R0, unsigned int *SV)
129{
130 FILE *s;
131 s = fopen(nume_fisier_secret_key, "r");
132 if (s == NULL)
133 {
134 printf("Nu am gasit fisierul ce contine cheile secrete.\n");
135 return 0;
136 }
137 fscanf(s, "%u", &(*R0));
138 fscanf(s, "%u", &(*SV));
139 fclose(s);
140 return 1;
141}
142
143unsigned int loadImageLin_C2(char *nume_fisier_sursa, unsigned char **header, struct pixel **L, unsigned int *latime_img, unsigned int *inaltime_img, unsigned int *padding, int okType)
144{
145 unsigned int dim_img;
146 unsigned char *tmp = (unsigned char*)malloc(3);
147 int i, j;
148
149 if (okType)
150 printf("\nNume_fisier_sursa = %s \n", nume_fisier_sursa);
151
152 //Deschidere fisier imagine
153 FILE *fin;
154 fin = fopen(nume_fisier_sursa, "rb");
155 if (fin == NULL)
156 {
157 printf("Nu am gasit imaginea sursa din care citesc.\n");
158 return 0;
159 }
160
161 //Dimensiune imagine
162 fseek(fin, 2, SEEK_SET);
163 fread(&dim_img, sizeof(unsigned int), 1, fin);
164 if (okType)
165 printf("Dimensiunea imaginii in octeti: %u\n", dim_img);
166
167 //Latime si inaltime imagine
168 fseek(fin, 18, SEEK_SET);
169 fread(latime_img, sizeof(unsigned int), 1, fin);
170 fread(inaltime_img, sizeof(unsigned int), 1, fin);
171 if (okType)
172 printf("Dimensiunea imaginii in pixeli (latime x inaltime): %u x %u\n", *latime_img, *inaltime_img);
173
174 //Calculare padding
175 if ((*latime_img) % 4 != 0)
176 *padding = 4 - (3 * (*latime_img)) % 4;
177 else
178 *padding = 0;
179 if (okType)
180 printf("padding = %d \n", *padding);
181
182 //Copierea header-ului
183 *header = (unsigned char*)malloc(54);
184 fseek(fin, 0, SEEK_SET);
185 for (i = 0; i < 54; i++)
186 fread(&(*header)[i], 1, 1, fin);
187
188 //Alocare spatiu pt imaginea liniarizata
189 *L = (struct pixel *) malloc((*latime_img) * (*inaltime_img) * sizeof(struct pixel));
190
191 //Citirea imaginii in forma liniarizata
192 if (okType)
193 printf("\nCitire...");
194 for (i = 0; i < (*inaltime_img); i++)
195 {
196 for (j = 0; j < (*latime_img); j++)
197 {
198 fread(&(*L)[((*inaltime_img) - 1 - i)*(*latime_img) + j].B, 1, 1, fin);
199 fread(&(*L)[((*inaltime_img) - 1 - i)*(*latime_img) + j].G, 1, 1, fin);
200 fread(&(*L)[((*inaltime_img) - 1 - i)*(*latime_img) + j].R, 1, 1, fin);
201 }
202 if (*padding)
203 fread(&tmp, 1, (*padding), fin);
204 if (i % 128 == 0 && okType) //vizualizare progres
205 printf(".");
206 }
207 printf("\n");
208 fclose(fin);
209 return dim_img;
210}
211
212void saveImageLin_C3(char *nume_fisier_destinatie, unsigned char *header, struct pixel *L, unsigned int latime_img, unsigned int inaltime_img, unsigned int padding)
213{
214 FILE *fout;
215 fout = fopen(nume_fisier_destinatie, "wb");
216 int i, j;
217
218 //Salvarea header ului imaginii
219 for (i = 0; i < 54; i++)
220 fwrite(&header[i], 1, 1, fout);
221
222 //Salvarea imaginii din forma liniarizata
223 unsigned char *tmp = (unsigned char*)malloc(3); tmp[0] = 0; tmp[1] = 0; tmp[2] = 0;
224 printf("\nSalvare...");
225 for (i = 0; i < inaltime_img; i++)
226 {
227 for (j = 0; j < latime_img; j++)
228 {
229 fwrite(&L[(inaltime_img - 1 - i)*latime_img + j].B, 1, 1, fout);
230 fwrite(&L[(inaltime_img - 1 - i)*latime_img + j].G, 1, 1, fout);
231 fwrite(&L[(inaltime_img - 1 - i)*latime_img + j].R, 1, 1, fout);
232 }
233 if (padding)
234 fwrite(tmp, 1, padding, fout);
235 if (i % 128 == 0) //vizualizare progres
236 printf(".");
237 }
238 printf("\n");
239 fclose(fout);
240}
241
242void chiSquaredTest_C6(char *nume_fisier_testat)
243{
244 struct frecventa {
245 unsigned int R, G, B;
246 };
247
248 unsigned int dim_img, latime_img, inaltime_img, padding;
249 unsigned char *header;
250 struct pixel *L;
251 int i;
252
253 dim_img = loadImageLin_C2(nume_fisier_testat, &header, &L, &latime_img, &inaltime_img, &padding, 0);
254 if (!dim_img)
255 return;
256
257 FILE *fout = fopen("chi-squared-test-values.txt", "ab");
258
259 struct frecventa *frecv = (struct frecventa*)malloc(256 * sizeof(struct frecventa));
260 for (i = 0; i < 256; i++)
261 {
262 frecv[i].R = 0;
263 frecv[i].G = 0;
264 frecv[i].B = 0;
265 }
266 for (i = 0; i < latime_img * inaltime_img; i++)
267 {
268 frecv[L[i].R].R++;
269 frecv[L[i].G].G++;
270 frecv[L[i].B].B++;
271 }
272
273 float chiR = 0, chiG = 0, chiB = 0, frecvEstT;
274 frecvEstT = (latime_img * inaltime_img) / 256.0;
275
276 for (i = 0; i < 256; i++)
277 {
278 chiR = chiR + ((frecv[i].R - frecvEstT) * (frecv[i].R - frecvEstT)) / frecvEstT;
279 chiG = chiG + ((frecv[i].G - frecvEstT) * (frecv[i].G - frecvEstT)) / frecvEstT;
280 chiB = chiB + ((frecv[i].B - frecvEstT) * (frecv[i].B - frecvEstT)) / frecvEstT;
281 }
282 printf("Chi-squared test on RGB channels for %s:\nR: %.2f\nG: %.2f\nB: %.2f\n", nume_fisier_testat, chiR, chiG, chiB);
283 fprintf(fout, "Chi-squared test on RGB channels for %s:\r\nR: %.2f\r\nG: %.2f\r\nB: %.2f\r\n\r\n", nume_fisier_testat, chiR, chiG, chiB);
284 fclose(fout);
285 free(frecv);
286}
287
288void encryptImage_C4(char *nume_fisier_sursa, char *nume_fisier_destinatie, char *secret_key)
289{
290 unsigned int dim_img, latime_img, inaltime_img, padding, *R, *Perm, R0, SV;
291 unsigned char *header;
292 struct pixel *L, *LP, *C;
293 int i, k;
294
295 //Citire chei secrete
296 if (!getSecretKeys(secret_key, &R0, &SV))
297 return;
298
299 //Citire imagine initiala
300 dim_img = loadImageLin_C2(nume_fisier_sursa, &header, &L, &latime_img, &inaltime_img, &padding, 1);
301 if (!dim_img)
302 return;
303
304 //Generare secventa de nr aleatoare
305 xorshift32_C1(&R, 2 * latime_img * inaltime_img, R0);
306
307 //Generare permutare aleatorie
308 pDurstenfeld(&Perm, latime_img*inaltime_img, R);
309
310 //Permutarea pixelilor imaginii
311 LP = (struct pixel*) malloc(latime_img * inaltime_img * sizeof(struct pixel));
312 for (i = 0; i < latime_img * inaltime_img; i++)
313 LP[Perm[i]] = L[i];
314
315 //Schimbarea valorilor pixelilor
316 printf("\nCriptare...");
317 C = (struct pixel*) malloc(latime_img * inaltime_img * sizeof(struct pixel));
318 C[0].R = SV ^ (LP[0].R) ^ R[latime_img * inaltime_img];
319 C[0].G = SV ^ (LP[0].G) ^ R[latime_img * inaltime_img];
320 C[0].B = SV ^ (LP[0].B) ^ R[latime_img * inaltime_img];
321 for (k = 1; k < latime_img * inaltime_img; k++)
322 {
323 C[k].R = (C[k - 1].R) ^ (LP[k].R) ^ R[latime_img * inaltime_img + k];
324 C[k].G = (C[k - 1].G) ^ (LP[k].G) ^ R[latime_img * inaltime_img + k];
325 C[k].B = (C[k - 1].B) ^ (LP[k].B) ^ R[latime_img * inaltime_img + k];
326 if (k % (128 * latime_img) == 0) //vizualizare progres
327 printf(".");
328 }
329 printf("\n");
330
331 //Salvare imagine criptata
332 saveImageLin_C3(nume_fisier_destinatie, header, C, latime_img, inaltime_img, padding);
333
334 free(L);
335 free(LP);
336 free(C);
337 free(R);
338 free(Perm);
339 free(header);
340 printf("\nImaginea a fost criptata.\n");
341 chiSquaredTest_C6(nume_fisier_sursa);
342 chiSquaredTest_C6(nume_fisier_destinatie);
343}
344
345void decryptImage_C5(char *nume_fisier_decriptat, char *nume_fisier_criptat, char *secret_key)
346{
347 unsigned int dim_img, latime_img, inaltime_img, padding, *R, *Perm, R0, SV;
348 unsigned char *header;
349 struct pixel *C, *CP, *L;
350 int i;
351
352 //Citire chei secrete
353 if (!getSecretKeys(secret_key, &R0, &SV))
354 return;
355
356 //Citire imagine initiala
357 dim_img = loadImageLin_C2(nume_fisier_criptat, &header, &C, &latime_img, &inaltime_img, &padding, 1);
358 if (!dim_img)
359 return;
360
361 //Generare secventa de nr aleatoare
362 xorshift32_C1(&R, 2 * latime_img * inaltime_img, R0);
363
364 //Generare permutare aleatorie
365 pDurstenfeld(&Perm, latime_img * inaltime_img, R);
366
367 //Calculare inversa permutarii
368 inversaPerm(&Perm, latime_img * inaltime_img);
369
370 //Restaurarea valorilor pixelilor
371 printf("\nDecriptare...");
372 CP = (struct pixel*) malloc(latime_img * inaltime_img * sizeof(struct pixel));
373 CP[0].R = SV ^ (C[0].R) ^ R[latime_img * inaltime_img];
374 CP[0].G = SV ^ (C[0].G) ^ R[latime_img * inaltime_img];
375 CP[0].B = SV ^ (C[0].B) ^ R[latime_img * inaltime_img];
376 for (int k = 1; k < latime_img * inaltime_img; k++)
377 {
378 CP[k].R = (C[k - 1].R) ^ (C[k].R) ^ R[latime_img * inaltime_img + k];
379 CP[k].G = (C[k - 1].G) ^ (C[k].G) ^ R[latime_img * inaltime_img + k];
380 CP[k].B = (C[k - 1].B) ^ (C[k].B) ^ R[latime_img * inaltime_img + k];
381 if (k % (128 * latime_img) == 0) //vizualizare progres
382 printf(".");
383 }
384 printf("\n");
385
386 //Permutarea pixelilor imaginii
387 L = (struct pixel*) malloc(latime_img * inaltime_img * sizeof(struct pixel));
388 for (i = 0; i < latime_img * inaltime_img; i++)
389 L[Perm[i]] = CP[i];
390
391 //Salvare imagine decriptata
392 saveImageLin_C3(nume_fisier_decriptat, header, L, latime_img, inaltime_img, padding);
393
394 free(L);
395 free(CP);
396 free(C);
397 free(R);
398 free(Perm);
399 free(header);
400 printf("\nImaginea a fost decriptata.\n");
401}
402
403void setColors(struct pixel **C)
404{
405 (*C) = (struct pixel*) malloc(10 * sizeof(struct pixel));
406 (*C)[0].R = 255; (*C)[0].G = 0; (*C)[0].B = 0;
407 (*C)[1].R = 255; (*C)[1].G = 255; (*C)[1].B = 0;
408 (*C)[2].R = 0; (*C)[2].G = 255; (*C)[2].B = 0;
409 (*C)[3].R = 0; (*C)[3].G = 255; (*C)[3].B = 255;
410 (*C)[4].R = 255; (*C)[4].G = 0; (*C)[4].B = 255;
411 (*C)[5].R = 0; (*C)[5].G = 0; (*C)[5].B = 255;
412 (*C)[6].R = 192; (*C)[6].G = 192; (*C)[6].B = 192;
413 (*C)[7].R = 255; (*C)[7].G = 140; (*C)[7].B = 0;
414 (*C)[8].R = 128; (*C)[8].G = 0; (*C)[8].B = 128;
415 (*C)[9].R = 128; (*C)[9].G = 0; (*C)[9].B = 0;
416}
417
418struct pixel **loadMatI(char *nume_fisier_sursa, unsigned char **header)
419{
420 unsigned int latime_img, inaltime_img, padding;
421 struct pixel **MatI;
422 int i, j;
423
424 //Deschidere fisier imagine originala
425 FILE *f = fopen(nume_fisier_sursa, "rb"); //nu poate fi NULL
426
427 //Latime si inaltime imagine
428 fseek(f, 18, SEEK_SET);
429 fread(&latime_img, sizeof(unsigned int), 1, f);
430 fread(&inaltime_img, sizeof(unsigned int), 1, f);
431
432 //Calculare padding
433 if (latime_img % 4 != 0)
434 padding = 4 - (3 * latime_img) % 4;
435 else
436 padding = 0;
437
438 //Copierea header-ului
439 *header = (unsigned char*)malloc(54);
440 fseek(f, 0, SEEK_SET);
441 for (i = 0; i < 54; i++)
442 fread(&(*header)[i], 1, 1, f);
443
444 //Citire imagine
445 unsigned char *tmp = (unsigned char*)malloc(3);
446 printf("\nIncarcare..");
447 MatI = (struct pixel **) malloc(inaltime_img * sizeof(struct pixel*));
448 for (i = 0; i < inaltime_img; i++)
449 {
450 MatI[i] = (struct pixel *) malloc(latime_img * sizeof(struct pixel));
451 for (j = 0; j < latime_img; j++)
452 {
453 fread(&MatI[i][j].B, 1, 1, f);
454 fread(&MatI[i][j].G, 1, 1, f);
455 fread(&MatI[i][j].R, 1, 1, f);
456 }
457 if (padding)
458 fread(tmp, 1, padding, f);
459 if (i % 256 == 0) //vizualizare progres
460 printf(".");
461 }
462 printf(" si ");
463 fclose(f);
464 return MatI;
465}
466
467void saveMatI(char *nume_fisier_dest, struct pixel **MatI, unsigned char *header)
468{
469 unsigned int latime_img, inaltime_img, padding;
470 int i, j;
471
472 FILE *fout = fopen(nume_fisier_dest, "wb");
473
474 //Latime si inaltime imagine
475 latime_img = *(unsigned int*)&header[18];
476 inaltime_img = *(unsigned int*)&header[22];
477
478 //Calculare padding
479 if (latime_img % 4 != 0)
480 padding = 4 - (3 * latime_img) % 4;
481 else
482 padding = 0;
483
484 //Salvare imagine cu pattern uri recunoscute
485 fwrite(header, 1, 54, fout);
486 unsigned char *tmp = (unsigned char*)malloc(3); tmp[0] = 0; tmp[1] = 0; tmp[2] = 0;
487 printf("salvare..");
488 for (i = 0; i < inaltime_img; i++)
489 {
490 for (j = 0; j < latime_img; j++)
491 {
492 fwrite(&MatI[i][j].B, 1, 1, fout);
493 fwrite(&MatI[i][j].G, 1, 1, fout);
494 fwrite(&MatI[i][j].R, 1, 1, fout);
495 }
496 if (padding)
497 fwrite(tmp, 1, padding, fout);
498 if (i % 256 == 0) //vizualizare progres
499 printf(".");
500 }
501 printf("\n");
502 fclose(fout);
503}
504
505struct detectie windowMatch(struct pixel **MatI, struct pixel **S, int x, int y, unsigned int inaltime, unsigned int latime, int nrSab)
506{
507 struct detectie det;
508 int i, j;
509 float n, medS, dS, medF, dF;
510
511 //det.corr = ?
512 det.sablon = nrSab;
513 det.inaltime = inaltime;
514 det.latime = latime;
515 det.x = x;
516 det.y = y;
517
518 n = latime * inaltime;
519 //Calculare media pixelilor in sablon (medS)
520 medS = 0;
521 for (i = 0; i < inaltime; i++)
522 for (j = 0; j < latime; j++)
523 medS += S[i][j].R;
524 medS = medS / n;
525
526 //Calculare media pixelilor in fereastra imaginii (medF)
527 medF = 0;
528 for (i = x; i < x + inaltime; i++)
529 for (j = y; j < y + latime; j++)
530 medF += MatI[i][j].R;
531 medF = medF / n;
532
533 //Calculare deviatie standard in sablon (dS)
534 dS = 0;
535 for (i = 0; i < inaltime; i++)
536 for (j = 0; j < latime; j++)
537 dS += (S[i][j].R - medS) * (S[i][j].R - medS);
538 dS = sqrt((1 / (n - 1)) * dS);
539
540 //Calculare deviatie standard in fereastra imaginii (dF)
541 dF = 0;
542 for (i = x; i < x + inaltime; i++)
543 for (j = y; j < y + latime; j++)
544 dF += (MatI[i][j].R - medF) * (MatI[i][j].R - medF);
545 dF = sqrt((1 / (n - 1)) * dF);
546
547 //Calculare corelatie (det.corr)
548 det.corr = 0;
549 for (i = 0; i < inaltime; i++)
550 for (j = 0; j < latime; j++)
551 det.corr += (1 / (dF * dS)) * (MatI[i + x][j + y].R - medF) * (S[i][j].R - medS);
552 det.corr = (1 / n) * det.corr;
553
554 return det;
555}
556
557struct detectie *templateMatching_C7(char *nume_fisier_sursa, char *nume_sablon, float prag, unsigned int *cnt, int nrSab)
558{
559 unsigned int latime_img, inaltime_img, padding, latime_sab, inaltime_sab, padding_sab;
560 char *nume_sablon_grayscale;
561 struct detectie *arrDet;
562 struct pixel **MatI, **S;
563 int i, j;
564 FILE *f, *fS;
565
566 //Deschidere fisier imagine
567 f = fopen(nume_fisier_sursa, "rb");
568 if (f == NULL)
569 {
570 printf("Nu am gasit imaginea sursa din care citesc.\n");
571 return NULL;
572 }
573
574 //Latime si inaltime imagine
575 fseek(f, 18, SEEK_SET);
576 fread(&latime_img, sizeof(unsigned int), 1, f);
577 fread(&inaltime_img, sizeof(unsigned int), 1, f);
578
579 //Calculare padding
580 if (latime_img % 4 != 0)
581 padding = 4 - (3 * latime_img) % 4;
582 else
583 padding = 0;
584
585 //Citire imagine
586 fseek(f, 54, SEEK_SET);
587 unsigned char *tmp = (unsigned char*)malloc(3);
588 MatI = (struct pixel **) malloc(inaltime_img * sizeof(struct pixel*));
589 for (i = 0; i < inaltime_img; i++)
590 {
591 MatI[i] = (struct pixel *) malloc(latime_img * sizeof(struct pixel));
592 for (j = 0; j < latime_img; j++)
593 {
594 fread(&MatI[i][j].B, 1, 1, f);
595 fread(&MatI[i][j].G, 1, 1, f);
596 fread(&MatI[i][j].R, 1, 1, f);
597 }
598 if (padding)
599 fread(tmp, 1, padding, f);
600 }
601 fclose(f);
602
603 //Transformare grayscale a sablonului
604 nume_sablon_grayscale = (char*)malloc(60);
605 strcpy(nume_sablon_grayscale, "grayscale_");
606 strcat(nume_sablon_grayscale, nume_sablon);
607 grayscaleImage(nume_sablon, nume_sablon_grayscale, 0);
608
609 //Deschidere fisier sablon
610 fS = fopen(nume_sablon_grayscale, "rb");
611 if (fS == NULL)
612 {
613 printf("Nu am gasit imaginea sablonului din care citesc.\n");
614 return NULL;
615 }
616
617 //Latime si inaltime sablon
618 fseek(fS, 18, SEEK_SET);
619 fread(&latime_sab, sizeof(unsigned int), 1, fS);
620 fread(&inaltime_sab, sizeof(unsigned int), 1, fS);
621
622 //Calculare padding
623 if (latime_sab % 4 != 0)
624 padding_sab = 4 - (3 * latime_sab) % 4;
625 else
626 padding_sab = 0;
627
628 //Citire sablon grayscale
629 fseek(fS, 54, SEEK_SET);
630 S = (struct pixel **) malloc(inaltime_sab * sizeof(struct pixel*));
631 for (i = 0; i < inaltime_sab; i++)
632 {
633 S[i] = (struct pixel *) malloc(latime_sab * sizeof(struct pixel));
634 for (j = 0; j < latime_sab; j++)
635 {
636 fread(&S[i][j].B, 1, 1, fS);
637 fread(&S[i][j].G, 1, 1, fS);
638 fread(&S[i][j].R, 1, 1, fS);
639 }
640 if (padding_sab)
641 fread(tmp, 1, padding_sab, fS);
642 }
643 fclose(fS);
644
645 //Glisarea sablonului si retinerea corelatiile peste pragul indicat (0.5)
646 arrDet = (struct detectie*) malloc(inaltime_img * latime_img * sizeof(struct detectie));
647 *cnt = 0;
648 for (i = 0; i <= inaltime_img - inaltime_sab; i++)
649 {
650 for (j = 0; j <= latime_img - latime_sab; j++)
651 {
652 arrDet[*cnt] = windowMatch(MatI, S, i, j, inaltime_sab, latime_sab, nrSab);
653 if (arrDet[*cnt].corr >= prag)
654 (*cnt)++;
655 }
656 }
657
658 //eliberare memorie
659 for (i = 0; i < inaltime_img; i++)
660 free(MatI[i]);
661 free(MatI);
662 for (i = 0; i < inaltime_sab; i++)
663 free(S[i]);
664 free(S);
665 free(nume_sablon_grayscale);
666
667 return arrDet;
668}
669
670void drawBorder_C8(struct pixel **MatI, struct detectie fI, struct pixel C)
671{
672 int i;
673 for (i = fI.x; i < fI.x + fI.inaltime; i++) //stanga si dreapta
674 {
675 MatI[i][fI.y].B = C.B;
676 MatI[i][fI.y].G = C.G;
677 MatI[i][fI.y].R = C.R;
678 MatI[i][fI.y + fI.latime - 1].B = C.B;
679 MatI[i][fI.y + fI.latime - 1].G = C.G;
680 MatI[i][fI.y + fI.latime - 1].R = C.R;
681 }
682 for(i = fI.y; i < fI.y + fI.latime; i++) //sus si jos
683 {
684 MatI[fI.x][i].B = C.B;
685 MatI[fI.x][i].G = C.G;
686 MatI[fI.x][i].R = C.R;
687 MatI[fI.x + fI.inaltime - 1][i].B = C.B;
688 MatI[fI.x + fI.inaltime - 1][i].G = C.G;
689 MatI[fI.x + fI.inaltime - 1][i].R = C.R;
690 }
691}
692
693int cmp_C9(const void *a, const void *b)
694{
695 if ((*(struct detectie*)b).corr - (*(struct detectie*)a).corr > 0.00)
696 return 1;
697 else
698 return -1;
699}
700
701void sortDetect_C9(struct detectie *arr, unsigned int n)
702{
703 qsort(arr, n, sizeof(struct detectie), cmp_C9);
704}
705
706float overlap(struct detectie a, struct detectie b)
707{
708 float Aa, Ab, Aanb, Aaub;
709 if (a.x + a.inaltime <= b.x || a.y + a.latime <= b.y)
710 return 0;
711 if (b.x + b.inaltime <= a.x || b.y + b.latime <= a.y)
712 return 0;
713 Aa = a.inaltime * a.latime;
714 Ab = b.inaltime * b.latime;
715 Aanb = (min(a.inaltime, b.inaltime) - (a.x - b.x)) * (min(a.latime, b.latime) - abs(a.y - b.y));
716 Aaub = Aa + Ab - Aanb;
717 return Aanb / Aaub;
718}
719
720void delete_non_max_C10(struct detectie *arr, unsigned int *n)
721{
722 int i, j, nAux = 0;
723 struct detectie *arrAux = (struct detectie*)malloc((*n) * sizeof(struct detectie));
724 for (i = 0; i < (*n); i++)
725 {
726 if (arr[i].corr == 0)
727 continue;
728 arrAux[nAux] = arr[i];
729 nAux++;
730 for (j = i + 1; j < (*n); j++)
731 if (overlap(arr[i], arr[j]) > 0.2)
732 arr[j].corr = 0;
733 }
734 for (i = 0; i < nAux; i++)
735 arr[i] = arrAux[i];
736 (*n) = nAux;
737 free(arrAux);
738}
739
740void patternMatching(char *nume_fisier_sursa)
741{
742 char *nume_fisier_grayscale, *nume_fisier_sabloane, *nume_fisier_rec, **sabloane;
743 unsigned int dimImg, cntDetFi, cntDet;
744 unsigned char *header;
745 struct detectie *arrFiSab, *arrDetected;
746 struct pixel **MatI, *culoare;
747 float ps = 0.5; //prag
748 int i, j;
749
750 nume_fisier_sabloane = (char*)malloc(50);
751 printf("Nume fisier sabloane: ");
752 scanf("%s", nume_fisier_sabloane);
753
754 FILE *fSab = fopen(nume_fisier_sabloane, "rb");
755 if (fSab == NULL)
756 {
757 printf("Fisierul pt sabloane nu a fost gasit.\n");
758 return;
759 }
760 sabloane = (char**)malloc(10 * sizeof(char*));
761 for (i = 0; i < 10; i++)
762 {
763 sabloane[i] = (char*)malloc(65);
764 fscanf(fSab, "%s", sabloane[i]);
765 }
766 fclose(fSab);
767 free(nume_fisier_sabloane);
768
769 nume_fisier_grayscale = (char*)malloc(100);
770 nume_fisier_rec = (char*)malloc(100);
771 strcpy(nume_fisier_grayscale, nume_fisier_sursa);
772 strcpy(nume_fisier_rec, nume_fisier_sursa);
773 strcat(nume_fisier_grayscale, "_grayscale.bmp");
774 strcat(nume_fisier_rec, "_rec.bmp");
775 strcat(nume_fisier_sursa, ".bmp");
776
777 dimImg = grayscaleImage(nume_fisier_sursa, nume_fisier_grayscale, 1);
778 if (!dimImg)
779 {
780 free(nume_fisier_grayscale);
781 return;
782 }
783
784 //Gasire detectii pt fiecare sablon
785 arrDetected = (struct detectie*)malloc(dimImg * 10 * sizeof(struct detectie));
786 arrFiSab = (struct detectie*)malloc(dimImg * sizeof(struct detectie));
787 cntDet = 0;
788 printf("\nCautare detectii...");
789 for (i = 0; i < 10; i++)
790 {
791 //cntDetFi = 0;
792 arrFiSab = templateMatching_C7(nume_fisier_grayscale, sabloane[i], ps, &cntDetFi, i);
793 for (j = 0; j < cntDetFi; j++)
794 {
795 arrDetected[cntDet] = arrFiSab[j];
796 cntDet++;
797 }
798 //if (i % 2)
799 printf(".");
800 }
801 printf("\n");
802 for (i = 0; i < 10; i++)
803 free(sabloane[i]);
804 free(sabloane);
805 free(arrFiSab);
806 free(nume_fisier_grayscale);
807
808 //Sortare descrescatoare a detectiilor
809 sortDetect_C9(arrDetected, cntDet);
810
811 //Eliminarea non-maximelor
812 delete_non_max_C10(arrDetected, &cntDet);
813
814 //Citire imagine originala in matrice
815 MatI = loadMatI(nume_fisier_sursa, &header);
816
817 //Setare culori pt desenare contur
818 setColors(&culoare);
819
820 //Desenare bordura pt fiecare cifra recunoscuta
821 for (i = 0; i < cntDet; i++)
822 drawBorder_C8(MatI, arrDetected[i], culoare[arrDetected[i].sablon]);
823
824 //Salvare imagine cu recunoasterea finalizara
825 saveMatI(nume_fisier_rec, MatI, header);
826
827 printf("\nRecunoasterea de pattern-uri a fost efectuata.\n");
828 free(nume_fisier_rec);
829 free(arrDetected);
830}
831
832void menu_C11()
833{
834 int t;
835 char *nume_img_sursa = (char*)malloc(90);
836 printf("*** Numele imaginii sursa se va scrie fara extensie (.bmp)! ***\n\n");
837 while (1)
838 {
839 printf("1. Criptare imagine\n");
840 printf("2. Decriptare imagine\n");
841 printf("3. Recunoastere pattern-uri\n");
842 printf("0. Exit\n");
843 scanf("%d", &t);
844 if (!t)
845 return;
846 printf("Nume fisier imagine: ");
847 scanf("%s", nume_img_sursa);
848 switch (t)
849 {
850 case 1:
851 {
852 char *nume_img_encrypted = (char*)malloc(100);
853 strcpy(nume_img_encrypted, nume_img_sursa);
854 strcat(nume_img_sursa, ".bmp");
855 strcat(nume_img_encrypted, "_encrypted.bmp");
856 printf("Nume fisier cheie secreta: ");
857 char *nume_cheie_secreta = (char*)malloc(50);
858 scanf("%s", nume_cheie_secreta);
859 encryptImage_C4(nume_img_sursa, nume_img_encrypted, nume_cheie_secreta);
860 free(nume_img_encrypted);
861 free(nume_cheie_secreta);
862 }
863 break;
864 case 2:
865 {
866 char *nume_img_decrypted = (char*)malloc(100);
867 strcpy(nume_img_decrypted, nume_img_sursa);
868 strcat(nume_img_sursa, ".bmp");
869 strcat(nume_img_decrypted, "_decrypted.bmp");
870 printf("Nume fisier cheie secreta: ");
871 char *nume_cheie_secreta = (char*)malloc(50);
872 scanf("%s", nume_cheie_secreta);
873 decryptImage_C5(nume_img_decrypted, nume_img_sursa, nume_cheie_secreta);
874 free(nume_img_decrypted);
875 free(nume_cheie_secreta);
876 }
877 break;
878 case 3:
879 {
880 patternMatching(nume_img_sursa);
881 }
882 break;
883 case 0:
884 break;
885 default: printf("Optiune invalida.\n");
886 break;
887 }
888 printf("\n");
889 }
890 free(nume_img_sursa);
891}
892
893int main()
894{
895 menu_C11();
896 return 0;
897}