# PBinfo #1478 – EasyOCR – Rezolvare C++

Sursa: Codul lui Andrei
Limbaj: C++
Autor rezolvare: andrei

## Enunț

Prin OCR (Optical Character Recognition) se înţelege tehnologia prin care un program de calculator identifică textul dintr-un fișier în care acesta nu e stocat ca şiruri de caractere, ci ca ansamblu de pixeli (imagine).

Să presupunem că am scanat o imagine alb negru care conţine doar cifre. Cifrele sunt formate din puncte (pixeli) negre iar fundalul din puncte albe. Imaginea va fi reprezentată ca un tablou dreptunghiular de cifre 0 şi 1, cifrele 1 formează obiectele din imagine iar cifrele 0 fundalul.

Cerinţă
Scrieţi un program care să determine:

a) câte cifre sunt în imagine;
b) numărul de apariţii ale fiecărei cifre. 

Spre exemplu, dacă imaginea scanată arată ca în figura următoare:



atunci rezultatul va fi: 

8
0 2 1 1 3 2 5 1 7 1 8 1.
Explicaţie: în total sunt 8 cifre, cifra 0 apare de 2 ori, 1 apare o dată, 3 de două ori, 5 o dată, 7 o dată şi cifra 8 are o singură apariţie.

Date de intrare
Pe prima linie a fișierului de intrare easyocr.in se găsesc două numere separate printr-un spațiu. Primul număr, notat cu n, reprezintă numărul de linii al matricei prin care se reprezintă zona dreptunghiulară, iar al doilea, notat cu m, reprezintă numărul de coloane. Pe următoarele n linii se află matricea cu cifrele care codifică imaginea, pe fiecare linie găsindu-se m cifre de 0 și/sau 1 scrise fără spații între ele (0 reprezintă o zonă albă, care nu face parte dintr-o cifră, iar 1 reprezintă o zonă dintr-o cifră).

Cifrele sunt dispuse vertical, paralel cu marginile zonei dreptunghiulare, dar pot fi situate pe nivele diferite. Dimensiunile cifrelor nu se modifică. De asemenea, cifrele nu se suprapun și nici nu se ating în zonele cu valori 1, dar pot fi una în spaţiul alteia. Cifrele arată ca în figura de mai jos:



Date de ieșire
Pe prima linie din fişierul de ieşire easyocr.out se va scrie numărul de cifre descoperite în imagine, iar pe a doua linie se vor scrie, separate prin câte un spaţiu, cifrele în ordine crescătoare, fiecare cifră fiind urmată de numărul său de apariţii. Dacă o cifră are numărul de apariții 0 (zero), atunci ea nu va fi afişată.

Restricții și precizări

0 ≤ n, m ≤ 1000
0 ≤ nr ≤ 2000, unde nr reprezintă numărul de cifre aflate în matrice.
O parte din conturul unei cifre poate coincide cu conturul matricei (zonei dreptunghiulare).

Exemplu:
easyocr.in

17 15
000000000000000
011111000000000
010000000000000
010000000000000
011111000000001
000001000000011
000001011111001
011111000001001
000000000001001
011111000010001
000001000100101
000001000101100
011111000100100
000001000000100
000001000000100
011111000000100
000000000000100
easyocr.out

5
1 2 3 1 5 1 7 1
Explicație


În imagine se află 5 cifre unde:


cifra 1 apare de 2 ori;
cifra 3 apare o singură dată;
cifra 5 apare o singură dată;
cifra 7 apare tot o singură dată.

## Cod sursă C++

```cpp
//prof. Liliana Schiopu, CNFB-Craiova
#include<stdio.h>
using namespace std;
FILE *f=fopen("easyocr.in","r");
FILE *g=fopen("easyocr.out","w");
int n,m,i,j,aparitii[10],nrcif=0,nr,x,y,ok;
char a[1000][1000],c2,c5,c6;
struct el
{
    int x,y;
};
int coada(int x,int y,char a1,char b)
{ register el coada1[30];
  register int ic=0,sf=0,i,x1[9]={-1,-1,0,1,1,1,0,-1},y1[9]={0,1,1,1,0,-1,-1,-1};
  nr++;
  ic=1;
  sf=1;
  coada1[sf].x=x;
  coada1[sf].y=y;
  a[x][y]=b;
  while(ic<=sf)
  {
      for(i=0;i<8;i++)
      if(a[coada1[ic].x+x1[i]][coada1[ic].y+y1[i]]==a1)
      {
          nr++;
          sf++;
          coada1[sf].x=coada1[ic].x+x1[i];
          coada1[sf].y=coada1[ic].y+y1[i];
          a[coada1[ic].x+x1[i]][coada1[ic].y+y1[i]]=b;
      }
      ic++;
  }
  return nr;
}
int main()
{ fscanf(f,"%d%d\n",&n,&m);
  for(i=1;i<=n;i++)
  {
     for(j=1;j<=m;j++)
      a[i][j]=fgetc(f);
     fgetc(f);
  }
    fclose(f);
   do{
    ok=0;
    for(i=1;i<=n && ok==0;i++)
        for(j=1;j<=m && ok==0;j++)
            if(a[i][j]=='1')
            {ok=1;
             x=i;y=j;
            }
    c5=a[x+1][y];
    c2=a[x+4][y];
    c6=a[x+4][y];
    nr=0;
    coada(x,y,'1','0');
    switch(nr){
      case 20: aparitii[0]++;nrcif++;break;
      case 8: aparitii[1]++;nrcif++;break;
      case 14: aparitii[4]++;nrcif++;break;
      case 11: aparitii[7]++;nrcif++;break;
      case 23: aparitii[8]++;nrcif++;break;
      case 19: if(c5=='1'){aparitii[5]++;nrcif++;}
               else if(c2=='1'){aparitii[2]++;nrcif++;}
                  else {aparitii[3]++;nrcif++;}
               break;
      case 21: if(c6=='1'){aparitii[6]++;nrcif++;}
                  else {aparitii[9]++;nrcif++;}
              break;
    }
   }while(ok==1);
   fprintf(g,"%d\n",nrcif);
   for(i=0;i<=9;i++)
      if(aparitii[i]!=0) fprintf(g,"%d %d ",i,aparitii[i]);
    fclose(g);
   return 0;
}
```

## Resurse

- [Pagina originală](https://codulluiandrei.ro/rezolvari/pbinfo/1478)
- [Sursa C++](https://codulluiandrei.ro/rezolvari/pbinfo/1478/cod.cpp)
- [Sursa pe GitHub](https://raw.githubusercontent.com/codulluiandrei/pbinfo/main/pbinfo-1478/main.cpp)
- [Cursuri de informatică pentru BAC](https://codulluiandrei.ro/academia/info-curs/pachet-cpp/)
