· 7 years ago · Dec 27, 2018, 12:48 AM
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 int i, j;
147
148 if (okType)
149 printf("\nNume_fisier_sursa = %s \n", nume_fisier_sursa);
150
151 //Deschidere fisier imagine
152 FILE *fin;
153 fin = fopen(nume_fisier_sursa, "rb");
154 if (fin == NULL)
155 {
156 printf("Nu am gasit imaginea sursa din care citesc.\n");
157 return 0;
158 }
159
160 //Dimensiune imagine
161 fseek(fin, 2, SEEK_SET);
162 fread(&dim_img, sizeof(unsigned int), 1, fin);
163 if (okType)
164 printf("Dimensiunea imaginii in octeti: %u\n", dim_img);
165
166 //Latime si inaltime imagine
167 fseek(fin, 18, SEEK_SET);
168 fread(latime_img, sizeof(unsigned int), 1, fin);
169 fread(inaltime_img, sizeof(unsigned int), 1, fin);
170 if (okType)
171 printf("Dimensiunea imaginii in pixeli (latime x inaltime): %u x %u\n", *latime_img, *inaltime_img);
172
173 //Calculare padding
174 if ((*latime_img) % 4 != 0)
175 *padding = 4 - (3 * (*latime_img)) % 4;
176 else
177 *padding = 0;
178 if (okType)
179 printf("padding = %d \n", *padding);
180
181 //Copierea header-ului
182 *header = (unsigned char*)malloc(54);
183 fseek(fin, 0, SEEK_SET);
184 for (i = 0; i < 54; i++)
185 fread(&(*header)[i], 1, 1, fin);
186
187 //Alocare spatiu pt imaginea liniarizata
188 *L = (struct pixel *) malloc((*latime_img) * (*inaltime_img) * sizeof(struct pixel));
189
190 //Citirea imaginii in forma liniarizata
191 if (okType)
192 printf("\nCitire...");
193 unsigned char *tmp = (unsigned char*)malloc(3);
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 free(tmp);
210 return dim_img;
211}
212
213void saveImageLin_C3(char *nume_fisier_destinatie, unsigned char *header, struct pixel *L, unsigned int latime_img, unsigned int inaltime_img, unsigned int padding)
214{
215 FILE *fout;
216 fout = fopen(nume_fisier_destinatie, "wb");
217 int i, j;
218
219 //Salvarea header ului imaginii
220 for (i = 0; i < 54; i++)
221 fwrite(&header[i], 1, 1, fout);
222
223 //Salvarea imaginii din forma liniarizata
224 unsigned char *tmp = (unsigned char*)malloc(3); tmp[0] = 0; tmp[1] = 0; tmp[2] = 0;
225 printf("\nSalvare...");
226 for (i = 0; i < inaltime_img; i++)
227 {
228 for (j = 0; j < latime_img; j++)
229 {
230 fwrite(&L[(inaltime_img - 1 - i)*latime_img + j].B, 1, 1, fout);
231 fwrite(&L[(inaltime_img - 1 - i)*latime_img + j].G, 1, 1, fout);
232 fwrite(&L[(inaltime_img - 1 - i)*latime_img + j].R, 1, 1, fout);
233 }
234 if (padding)
235 fwrite(tmp, 1, padding, fout);
236 if (i % 128 == 0) //vizualizare progres
237 printf(".");
238 }
239 printf("\n");
240 fclose(fout);
241 free(tmp);
242}
243
244void chiSquaredTest_C6(char *nume_fisier_testat)
245{
246 struct frecventa {
247 unsigned int R, G, B;
248 };
249
250 unsigned int dim_img, latime_img, inaltime_img, padding;
251 unsigned char *header;
252 float chiR = 0, chiG = 0, chiB = 0, frecvEstT;
253 struct pixel *L;
254 int i;
255
256 //Citire imagine testata
257 dim_img = loadImageLin_C2(nume_fisier_testat, &header, &L, &latime_img, &inaltime_img, &padding, 0);
258 if (!dim_img)
259 return;
260
261 FILE *fout = fopen("chi-squared-test-values.txt", "ab");
262
263 struct frecventa *frecv = (struct frecventa*)malloc(256 * sizeof(struct frecventa));
264 for (i = 0; i < 256; i++)
265 {
266 frecv[i].R = 0;
267 frecv[i].G = 0;
268 frecv[i].B = 0;
269 }
270
271 //Gasire frecventa fiecarui canal de culoare pt imaginea testata
272 for (i = 0; i < latime_img * inaltime_img; i++)
273 {
274 frecv[L[i].R].R++;
275 frecv[L[i].G].G++;
276 frecv[L[i].B].B++;
277 }
278
279 //Calculare frecventa estimata teoretic (medie)
280 frecvEstT = (latime_img * inaltime_img) / 256.0;
281
282 //Calculare valori chi squared pt fiecare canal de culoare
283 for (i = 0; i < 256; i++)
284 {
285 chiR = chiR + ((frecv[i].R - frecvEstT) * (frecv[i].R - frecvEstT)) / frecvEstT;
286 chiG = chiG + ((frecv[i].G - frecvEstT) * (frecv[i].G - frecvEstT)) / frecvEstT;
287 chiB = chiB + ((frecv[i].B - frecvEstT) * (frecv[i].B - frecvEstT)) / frecvEstT;
288 }
289
290 printf("Chi-squared test on RGB channels for %s:\nR: %.2f\nG: %.2f\nB: %.2f\n", nume_fisier_testat, chiR, chiG, chiB);
291 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);
292 fclose(fout);
293 free(header);
294 free(frecv);
295}
296
297void encryptImage_C4(char *nume_fisier_sursa, char *nume_fisier_destinatie, char *secret_key)
298{
299 unsigned int dim_img, latime_img, inaltime_img, padding, *R, *Perm, R0, SV;
300 unsigned char *header;
301 struct pixel *L, *LP, *C;
302 int i, k;
303
304 //Citire chei secrete
305 if (!getSecretKeys(secret_key, &R0, &SV))
306 return;
307
308 //Citire imagine initiala
309 dim_img = loadImageLin_C2(nume_fisier_sursa, &header, &L, &latime_img, &inaltime_img, &padding, 1);
310 if (!dim_img)
311 return;
312
313 //Generare secventa de nr aleatoare
314 xorshift32_C1(&R, 2 * latime_img * inaltime_img, R0);
315
316 //Generare permutare aleatorie
317 pDurstenfeld(&Perm, latime_img*inaltime_img, R);
318
319 //Permutarea pixelilor imaginii
320 LP = (struct pixel*) malloc(latime_img * inaltime_img * sizeof(struct pixel));
321 for (i = 0; i < latime_img * inaltime_img; i++)
322 LP[Perm[i]] = L[i];
323
324 //Schimbarea valorilor pixelilor
325 printf("\nCriptare...");
326 C = (struct pixel*) malloc(latime_img * inaltime_img * sizeof(struct pixel));
327 int sv = SV;
328
329 C[0].B = (sv & 255) ^ LP[0].B ^ (R[latime_img * inaltime_img] & 255);
330
331 sv = sv >> 8;
332 R[latime_img * inaltime_img] = R[latime_img * inaltime_img] >> 8;
333
334 C[0].G = (sv & 255) ^ LP[0].G ^ (R[latime_img * inaltime_img] & 255);
335
336 sv = sv >> 8;
337 R[latime_img * inaltime_img] = R[latime_img * inaltime_img] >> 8;
338
339 C[0].R = (sv & 255) ^ LP[0].R ^ (R[latime_img * inaltime_img] & 255);
340
341 for (k = 1; k < latime_img * inaltime_img; k++)
342 {
343 C[k].B = (C[k - 1].B) ^ (LP[k].B) ^ (R[latime_img * inaltime_img + k] & 255);
344
345 R[latime_img * inaltime_img + k] = R[latime_img * inaltime_img + k] >> 8;
346
347 C[k].G = (C[k - 1].G) ^ (LP[k].G) ^ (R[latime_img * inaltime_img + k] & 255);
348
349 R[latime_img * inaltime_img + k] = R[latime_img * inaltime_img + k] >> 8;
350
351 C[k].R = (C[k - 1].R) ^ (LP[k].R) ^ (R[latime_img * inaltime_img + k] & 255);
352
353 if (k % (128 * latime_img) == 0) //vizualizare progres
354 printf(".");
355 }
356 printf("\n");
357
358 //Salvare imagine criptata
359 saveImageLin_C3(nume_fisier_destinatie, header, C, latime_img, inaltime_img, padding);
360
361 //Eliberare memorie
362 free(L);
363 free(LP);
364 free(C);
365 free(R);
366 free(Perm);
367 free(header);
368 printf("\nImaginea a fost criptata.\n");
369 chiSquaredTest_C6(nume_fisier_sursa);
370 chiSquaredTest_C6(nume_fisier_destinatie);
371}
372
373void decryptImage_C5(char *nume_fisier_decriptat, char *nume_fisier_criptat, char *secret_key)
374{
375 unsigned int dim_img, latime_img, inaltime_img, padding, *R, *Perm, R0, SV;
376 unsigned char *header;
377 struct pixel *C, *CP, *L;
378 int i;
379
380 //Citire chei secrete
381 if (!getSecretKeys(secret_key, &R0, &SV))
382 return;
383
384 //Citire imagine initiala
385 dim_img = loadImageLin_C2(nume_fisier_criptat, &header, &C, &latime_img, &inaltime_img, &padding, 1);
386 if (!dim_img)
387 return;
388
389 //Generare secventa de nr aleatoare
390 xorshift32_C1(&R, 2 * latime_img * inaltime_img, R0);
391
392 //Generare permutare aleatorie
393 pDurstenfeld(&Perm, latime_img * inaltime_img, R);
394
395 //Calculare inversa permutarii
396 inversaPerm(&Perm, latime_img * inaltime_img);
397
398 //Restaurarea valorilor pixelilor
399 printf("\nDecriptare...");
400 CP = (struct pixel*) malloc(latime_img * inaltime_img * sizeof(struct pixel));
401 int sv = SV;
402
403 CP[0].B = (sv & 255) ^ (C[0].B) ^ (R[latime_img * inaltime_img] & 255);
404
405 sv = sv >> 8;
406 R[latime_img * inaltime_img] = R[latime_img * inaltime_img] >> 8;
407
408 CP[0].G = (sv & 255) ^ (C[0].G) ^ (R[latime_img * inaltime_img] & 255);
409
410 sv = sv >> 8;
411 R[latime_img * inaltime_img] = R[latime_img * inaltime_img] >> 8;
412
413 CP[0].R = (sv & 255) ^ (C[0].R) ^ (R[latime_img * inaltime_img] & 255);
414
415 for (int k = 1; k < latime_img * inaltime_img; k++)
416 {
417 CP[k].B = (C[k - 1].B) ^ (C[k].B) ^ (R[latime_img * inaltime_img + k] & 255);
418
419 R[latime_img * inaltime_img + k] = R[latime_img * inaltime_img + k] >> 8;
420
421 CP[k].G = (C[k - 1].G) ^ (C[k].G) ^ (R[latime_img * inaltime_img + k] & 255);
422
423 R[latime_img * inaltime_img + k] = R[latime_img * inaltime_img + k] >> 8;
424
425 CP[k].R = (C[k - 1].R) ^ (C[k].R) ^ (R[latime_img * inaltime_img + k] & 255);
426
427 if (k % (128 * latime_img) == 0) //vizualizare progres
428 printf(".");
429 }
430 printf("\n");
431
432 //Permutarea pixelilor imaginii
433 L = (struct pixel*) malloc(latime_img * inaltime_img * sizeof(struct pixel));
434 for (i = 0; i < latime_img * inaltime_img; i++)
435 L[Perm[i]] = CP[i];
436
437 //Salvare imagine decriptata
438 saveImageLin_C3(nume_fisier_decriptat, header, L, latime_img, inaltime_img, padding);
439
440 //Eliberare memorie
441 free(L);
442 free(CP);
443 free(C);
444 free(R);
445 free(Perm);
446 free(header);
447 printf("\nImaginea a fost decriptata.\n");
448}
449
450void setColors(struct pixel **C)
451{
452 (*C) = (struct pixel*) malloc(10 * sizeof(struct pixel));
453 (*C)[0].R = 255; (*C)[0].G = 0; (*C)[0].B = 0;
454 (*C)[1].R = 255; (*C)[1].G = 255; (*C)[1].B = 0;
455 (*C)[2].R = 0; (*C)[2].G = 255; (*C)[2].B = 0;
456 (*C)[3].R = 0; (*C)[3].G = 255; (*C)[3].B = 255;
457 (*C)[4].R = 255; (*C)[4].G = 0; (*C)[4].B = 255;
458 (*C)[5].R = 0; (*C)[5].G = 0; (*C)[5].B = 255;
459 (*C)[6].R = 192; (*C)[6].G = 192; (*C)[6].B = 192;
460 (*C)[7].R = 255; (*C)[7].G = 140; (*C)[7].B = 0;
461 (*C)[8].R = 128; (*C)[8].G = 0; (*C)[8].B = 128;
462 (*C)[9].R = 128; (*C)[9].G = 0; (*C)[9].B = 0;
463}
464
465struct pixel **loadMatI(char *nume_fisier_sursa, unsigned char **header)
466{
467 unsigned int latime_img, inaltime_img, padding;
468 struct pixel **MatI;
469 int i, j;
470
471 //Deschidere fisier imagine originala
472 FILE *f = fopen(nume_fisier_sursa, "rb"); //nu poate fi NULL
473
474 //Latime si inaltime imagine
475 fseek(f, 18, SEEK_SET);
476 fread(&latime_img, sizeof(unsigned int), 1, f);
477 fread(&inaltime_img, sizeof(unsigned int), 1, f);
478
479 //Calculare padding
480 if (latime_img % 4 != 0)
481 padding = 4 - (3 * latime_img) % 4;
482 else
483 padding = 0;
484
485 //Copierea header-ului
486 *header = (unsigned char*)malloc(54);
487 fseek(f, 0, SEEK_SET);
488 for (i = 0; i < 54; i++)
489 fread(&(*header)[i], 1, 1, f);
490
491 //Citire imagine
492 unsigned char *tmp = (unsigned char*)malloc(3);
493 printf("\nIncarcare..");
494 MatI = (struct pixel **) malloc(inaltime_img * sizeof(struct pixel*));
495 for (i = 0; i < inaltime_img; i++)
496 {
497 MatI[i] = (struct pixel *) malloc(latime_img * sizeof(struct pixel));
498 for (j = 0; j < latime_img; j++)
499 {
500 fread(&MatI[i][j].B, 1, 1, f);
501 fread(&MatI[i][j].G, 1, 1, f);
502 fread(&MatI[i][j].R, 1, 1, f);
503 }
504 if (padding)
505 fread(tmp, 1, padding, f);
506 if (i % 256 == 0) //vizualizare progres
507 printf(".");
508 }
509 printf(" si ");
510 fclose(f);
511 free(tmp);
512 return MatI;
513}
514
515void saveMatI(char *nume_fisier_dest, struct pixel **MatI, unsigned char *header)
516{
517 unsigned int latime_img, inaltime_img, padding;
518 int i, j;
519
520 FILE *fout = fopen(nume_fisier_dest, "wb");
521
522 //Latime si inaltime imagine
523 latime_img = *(unsigned int*)&header[18];
524 inaltime_img = *(unsigned int*)&header[22];
525
526 //Calculare padding
527 if (latime_img % 4 != 0)
528 padding = 4 - (3 * latime_img) % 4;
529 else
530 padding = 0;
531
532 //Salvare imagine cu pattern uri recunoscute
533 fwrite(header, 1, 54, fout);
534 unsigned char *tmp = (unsigned char*)malloc(3); tmp[0] = 0; tmp[1] = 0; tmp[2] = 0;
535 printf("salvare..");
536 for (i = 0; i < inaltime_img; i++)
537 {
538 for (j = 0; j < latime_img; j++)
539 {
540 fwrite(&MatI[i][j].B, 1, 1, fout);
541 fwrite(&MatI[i][j].G, 1, 1, fout);
542 fwrite(&MatI[i][j].R, 1, 1, fout);
543 }
544 if (padding)
545 fwrite(tmp, 1, padding, fout);
546 if (i % 256 == 0) //vizualizare progres
547 printf(".");
548 }
549 printf("\n");
550 free(tmp);
551 fclose(fout);
552}
553
554struct detectie windowMatch(struct pixel **MatI, struct pixel **S, int x, int y, unsigned int inaltime, unsigned int latime, int nrSab)
555{
556 struct detectie det;
557 int i, j;
558 float n, medS, dS, medF, dF;
559
560 //det.corr = ?
561 det.sablon = nrSab;
562 det.inaltime = inaltime;
563 det.latime = latime;
564 det.x = x;
565 det.y = y;
566
567 n = latime * inaltime;
568 //Calculare media pixelilor in sablon (medS)
569 medS = 0;
570 for (i = 0; i < inaltime; i++)
571 for (j = 0; j < latime; j++)
572 medS += S[i][j].R;
573 medS = medS / n;
574
575 //Calculare media pixelilor in fereastra imaginii (medF)
576 medF = 0;
577 for (i = x; i < x + inaltime; i++)
578 for (j = y; j < y + latime; j++)
579 medF += MatI[i][j].R;
580 medF = medF / n;
581
582 //Calculare deviatie standard in sablon (dS)
583 dS = 0;
584 for (i = 0; i < inaltime; i++)
585 for (j = 0; j < latime; j++)
586 dS += (S[i][j].R - medS) * (S[i][j].R - medS);
587 dS = sqrt((1 / (n - 1)) * dS);
588
589 //Calculare deviatie standard in fereastra imaginii (dF)
590 dF = 0;
591 for (i = x; i < x + inaltime; i++)
592 for (j = y; j < y + latime; j++)
593 dF += (MatI[i][j].R - medF) * (MatI[i][j].R - medF);
594 dF = sqrt((1 / (n - 1)) * dF);
595
596 //Calculare corelatie (det.corr)
597 det.corr = 0;
598 for (i = 0; i < inaltime; i++)
599 for (j = 0; j < latime; j++)
600 det.corr += (1 / (dF * dS)) * (MatI[i + x][j + y].R - medF) * (S[i][j].R - medS);
601 det.corr = (1 / n) * det.corr;
602
603 return det;
604}
605
606struct detectie *templateMatching_C7(char *nume_fisier_sursa, char *nume_sablon, float prag, unsigned int *cnt, int nrSab)
607{
608 unsigned int latime_img, inaltime_img, padding, latime_sab, inaltime_sab, padding_sab;
609 char *nume_sablon_grayscale;
610 struct detectie *arrDet;
611 struct pixel **MatI, **S;
612 int i, j;
613 FILE *f, *fS;
614
615 //Deschidere fisier imagine
616 f = fopen(nume_fisier_sursa, "rb");
617 if (f == NULL)
618 {
619 printf("Nu am gasit imaginea sursa din care citesc.\n");
620 return NULL;
621 }
622
623 //Latime si inaltime imagine
624 fseek(f, 18, SEEK_SET);
625 fread(&latime_img, sizeof(unsigned int), 1, f);
626 fread(&inaltime_img, sizeof(unsigned int), 1, f);
627
628 //Calculare padding
629 if (latime_img % 4 != 0)
630 padding = 4 - (3 * latime_img) % 4;
631 else
632 padding = 0;
633
634 //Citire imagine
635 fseek(f, 54, SEEK_SET);
636 unsigned char *tmp = (unsigned char*)malloc(3);
637 MatI = (struct pixel **) malloc(inaltime_img * sizeof(struct pixel*));
638 for (i = 0; i < inaltime_img; i++)
639 {
640 MatI[i] = (struct pixel *) malloc(latime_img * sizeof(struct pixel));
641 for (j = 0; j < latime_img; j++)
642 {
643 fread(&MatI[i][j].B, 1, 1, f);
644 fread(&MatI[i][j].G, 1, 1, f);
645 fread(&MatI[i][j].R, 1, 1, f);
646 }
647 if (padding)
648 fread(tmp, 1, padding, f);
649 }
650 fclose(f);
651
652 //Transformare grayscale a sablonului
653 nume_sablon_grayscale = (char*)malloc(60);
654 strcpy(nume_sablon_grayscale, "grayscale_");
655 strcat(nume_sablon_grayscale, nume_sablon);
656 grayscaleImage(nume_sablon, nume_sablon_grayscale, 0);
657
658 //Deschidere fisier sablon
659 fS = fopen(nume_sablon_grayscale, "rb");
660 if (fS == NULL)
661 {
662 printf("Nu am gasit imaginea sablonului din care citesc.\n");
663 return NULL;
664 }
665
666 //Latime si inaltime sablon
667 fseek(fS, 18, SEEK_SET);
668 fread(&latime_sab, sizeof(unsigned int), 1, fS);
669 fread(&inaltime_sab, sizeof(unsigned int), 1, fS);
670
671 //Calculare padding
672 if (latime_sab % 4 != 0)
673 padding_sab = 4 - (3 * latime_sab) % 4;
674 else
675 padding_sab = 0;
676
677 //Citire sablon grayscale
678 fseek(fS, 54, SEEK_SET);
679 S = (struct pixel **) malloc(inaltime_sab * sizeof(struct pixel*));
680 for (i = 0; i < inaltime_sab; i++)
681 {
682 S[i] = (struct pixel *) malloc(latime_sab * sizeof(struct pixel));
683 for (j = 0; j < latime_sab; j++)
684 {
685 fread(&S[i][j].B, 1, 1, fS);
686 fread(&S[i][j].G, 1, 1, fS);
687 fread(&S[i][j].R, 1, 1, fS);
688 }
689 if (padding_sab)
690 fread(tmp, 1, padding_sab, fS);
691 }
692 fclose(fS);
693
694 //Glisarea sablonului si retinerea corelatiile peste pragul indicat (0.5)
695 arrDet = (struct detectie*) malloc(inaltime_img * latime_img * sizeof(struct detectie));
696 *cnt = 0;
697 for (i = 0; i <= inaltime_img - inaltime_sab; i++)
698 {
699 for (j = 0; j <= latime_img - latime_sab; j++)
700 {
701 arrDet[*cnt] = windowMatch(MatI, S, i, j, inaltime_sab, latime_sab, nrSab);
702 if (arrDet[*cnt].corr >= prag)
703 (*cnt)++;
704 }
705 }
706
707 //Eliberare memorie
708 for (i = 0; i < inaltime_img; i++)
709 free(MatI[i]);
710 free(MatI);
711 for (i = 0; i < inaltime_sab; i++)
712 free(S[i]);
713 free(S);
714 free(nume_sablon_grayscale);
715
716 return arrDet;
717}
718
719void drawBorder_C8(struct pixel **MatI, struct detectie fI, struct pixel C)
720{
721 int i;
722 for (i = fI.x; i < fI.x + fI.inaltime; i++) //stanga si dreapta
723 {
724 MatI[i][fI.y].B = C.B;
725 MatI[i][fI.y].G = C.G;
726 MatI[i][fI.y].R = C.R;
727 MatI[i][fI.y + fI.latime - 1].B = C.B;
728 MatI[i][fI.y + fI.latime - 1].G = C.G;
729 MatI[i][fI.y + fI.latime - 1].R = C.R;
730 }
731 for (i = fI.y; i < fI.y + fI.latime; i++) //sus si jos
732 {
733 MatI[fI.x][i].B = C.B;
734 MatI[fI.x][i].G = C.G;
735 MatI[fI.x][i].R = C.R;
736 MatI[fI.x + fI.inaltime - 1][i].B = C.B;
737 MatI[fI.x + fI.inaltime - 1][i].G = C.G;
738 MatI[fI.x + fI.inaltime - 1][i].R = C.R;
739 }
740}
741
742int cmp_C9(const void *a, const void *b)
743{
744 if ((*(struct detectie*)b).corr - (*(struct detectie*)a).corr > 0.00)
745 return 1;
746 else
747 return -1;
748}
749
750void sortDetect_C9(struct detectie *arr, unsigned int n)
751{
752 qsort(arr, n, sizeof(struct detectie), cmp_C9);
753}
754
755float overlap(struct detectie a, struct detectie b)
756{
757 float Aa, Ab, Aanb, Aaub;
758 if (a.x + a.inaltime <= b.x || a.y + a.latime <= b.y) //nu se intersecteaza
759 return 0;
760 if (b.x + b.inaltime <= a.x || b.y + b.latime <= a.y) //nu se intersecteaza
761 return 0;
762 Aa = a.inaltime * a.latime; //Arie detectie a
763 Ab = b.inaltime * b.latime; //Arie detectie b
764 Aanb = (min(a.inaltime, b.inaltime) - (a.x - b.x)) * (min(a.latime, b.latime) - abs(a.y - b.y)); //Arie intersectie a n b
765 Aaub = Aa + Ab - Aanb; //Arie reuniune a u b
766 return Aanb / Aaub; //Factor de suprapunere
767}
768
769void delete_non_max_C10(struct detectie *arr, unsigned int *n)
770{
771 int i, j, nAux = 0;
772 struct detectie *arrAux = (struct detectie*)malloc((*n) * sizeof(struct detectie));
773
774 for (i = 0; i < (*n); i++)
775 {
776 if (arr[i].corr == 0) //daca a fost sters
777 continue;
778 arrAux[nAux] = arr[i];
779 nAux++;
780 for (j = i + 1; j < (*n); j++)
781 if (overlap(arr[i], arr[j]) > 0.2) //verificare suprapunere
782 arr[j].corr = 0; //eliminare
783 }
784 for (i = 0; i < nAux; i++) //actualizare vector cu detectii
785 arr[i] = arrAux[i];
786 (*n) = nAux; //actualizare nr detectii
787 free(arrAux);
788}
789
790void patternMatching(char *nume_fisier_sursa, char *nume_fisier_rec, char *nume_fisier_sabloane, float ps)
791{
792 char *nume_fisier_grayscale, **sabloane;
793 unsigned int dimImg, cntDetFi, cntDet;
794 unsigned char *header;
795 struct detectie *arrFiSab, *arrDetected;
796 struct pixel **MatI, *culoare;
797 int i, j;
798
799 //Deschidere fisier cu adresele sabloanelor
800 FILE *fSab = fopen(nume_fisier_sabloane, "rb");
801 if (fSab == NULL)
802 {
803 printf("Fisierul pt sabloane nu a fost gasit.\n");
804 return;
805 }
806
807 //Preluarea adreselor sabloanelor
808 sabloane = (char**)malloc(10 * sizeof(char*));
809 for (i = 0; i < 10; i++)
810 {
811 sabloane[i] = (char*)malloc(65);
812 fscanf(fSab, "%s", sabloane[i]);
813 }
814 fclose(fSab);
815
816 nume_fisier_grayscale = (char*)malloc(100);
817 strcpy(nume_fisier_grayscale, "grayscale_");
818 strcat(nume_fisier_grayscale, nume_fisier_sursa);
819
820 //Transformare grayscale a imaginii sursa
821 dimImg = grayscaleImage(nume_fisier_sursa, nume_fisier_grayscale, 1);
822 if (!dimImg)
823 {
824 free(nume_fisier_grayscale);
825 return;
826 }
827
828 //Gasire detectii pt fiecare sablon
829 arrDetected = (struct detectie*)malloc(dimImg * 10 * sizeof(struct detectie));
830 arrFiSab = (struct detectie*)malloc(dimImg * sizeof(struct detectie));
831 cntDet = 0;
832 printf("\nCautare detectii...");
833 for (i = 0; i < 10; i++)
834 {
835 //cntDetFi = 0;
836 arrFiSab = templateMatching_C7(nume_fisier_grayscale, sabloane[i], ps, &cntDetFi, i);
837 //Adaugare a detectiilor gasite pt fiecare sablon in parte la un loc
838 for (j = 0; j < cntDetFi; j++)
839 {
840 arrDetected[cntDet] = arrFiSab[j];
841 cntDet++;
842 }
843 //if (i % 2)
844 printf(".");
845 }
846 printf("\n");
847 //Eliberare memorie #1
848 for (i = 0; i < 10; i++)
849 free(sabloane[i]);
850 free(sabloane);
851 free(arrFiSab);
852 free(nume_fisier_grayscale);
853
854 //Sortare descrescatoare a detectiilor
855 sortDetect_C9(arrDetected, cntDet);
856
857 //Eliminarea non-maximelor
858 delete_non_max_C10(arrDetected, &cntDet);
859
860 //Citire imagine originala in matrice
861 MatI = loadMatI(nume_fisier_sursa, &header);
862
863 //Setare culori pt desenare contur
864 setColors(&culoare);
865
866 //Desenare bordura pt fiecare cifra recunoscuta
867 for (i = 0; i < cntDet; i++)
868 drawBorder_C8(MatI, arrDetected[i], culoare[arrDetected[i].sablon]);
869
870 //Salvare imagine cu recunoasterea finalizara
871 saveMatI(nume_fisier_rec, MatI, header);
872
873 printf("\nRecunoasterea de pattern-uri a fost efectuata.\n");
874
875 //Eliberare memorie #2
876 for (i = 0; i < *(unsigned int*)&header[22]; i++)
877 free(MatI[i]);
878 free(MatI);
879 free(header);
880 free(culoare);
881 free(arrDetected);
882}
883
884void menu_C11()
885{
886 int t;
887 char *nume_img_sursa = (char*)malloc(90);
888 while (1)
889 {
890 printf("1. Criptare imagine\n");
891 printf("2. Decriptare imagine\n");
892 printf("3. Recunoastere pattern-uri\n");
893 printf("0. Exit\n");
894 scanf("%d", &t);
895 if (!t)
896 break;
897 printf("Nume fisier imagine: ");
898 scanf("%s", nume_img_sursa);
899 switch (t)
900 {
901 case 1:
902 {
903 char *nume_img_encrypted = (char*)malloc(100);
904 strcpy(nume_img_encrypted, "enc_");
905 strcat(nume_img_encrypted, nume_img_sursa);
906 printf("Nume fisier cheie secreta: ");
907 char *nume_cheie_secreta = (char*)malloc(55);
908 scanf("%s", nume_cheie_secreta);
909 encryptImage_C4(nume_img_sursa, nume_img_encrypted, nume_cheie_secreta);
910 free(nume_img_encrypted);
911 free(nume_cheie_secreta);
912 }
913 break;
914 case 2:
915 {
916 char *nume_img_decrypted = (char*)malloc(100);
917 strcpy(nume_img_decrypted, "dec_");
918 strcat(nume_img_decrypted, nume_img_sursa);
919 printf("Nume fisier cheie secreta: ");
920 char *nume_cheie_secreta = (char*)malloc(55);
921 scanf("%s", nume_cheie_secreta);
922 decryptImage_C5(nume_img_decrypted, nume_img_sursa, nume_cheie_secreta);
923 free(nume_img_decrypted);
924 free(nume_cheie_secreta);
925 }
926 break;
927 case 3:
928 {
929 float prag = 0.5;
930 char *nume_img_rec = (char*)malloc(100);
931 strcpy(nume_img_rec, "rec_");
932 strcat(nume_img_rec, nume_img_sursa);
933 printf("Nume fisier sabloane: ");
934 char *nume_fisier_sabloane = (char*)malloc(50);
935 scanf("%s", nume_fisier_sabloane);
936 //printf("Prag: ");
937 //scanf("%f", &prag);
938 patternMatching(nume_img_sursa, nume_img_rec, nume_fisier_sabloane, prag);
939 free(nume_img_rec);
940 free(nume_fisier_sabloane);
941 }
942 break;
943 case 0:
944 break;
945 default: printf("Optiune invalida.\n");
946 break;
947 }
948 printf("\n");
949 }
950 free(nume_img_sursa);
951}
952
953int main()
954{
955 menu_C11();
956 return 0;
957}