Rezolvare completă PbInfo #1478 EasyOCR

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ă.

Cum e corect?

cout < "As la info"; cout << "As la info"; cout >> "As la info";

Felicitări! Poți mai mult?

Avem sute de probleme pentru tine, fiecare cu explicații ușor de înțeles.

Greșit, dar nu-i bai!

Antrenează-te cu sutele de probleme pe care ți le-am pregătit. Îți explicăm fiecare problemă în parte.

Rezolvare

Iată rezolvarea de 100 de puncte pentru problema EasyOCR:

//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;
}

Atenție

Enunțurile afișate pe această pagină aparțin exclusiv site-ului PbInfo. Astfel, pentru ștergerea conținutului, puteți să ne contactați la adresa Adresa de email.

Rezolvarea problemei #1478 EasyOCR

Pe această pagină găsești rezolvarea de 100 de puncte pentru problema #1478 EasyOCR de pe PbInfo.ro. Atenție: nu încurajăm copiatul codului! Totuși, credem cu tărie că analizarea unei soluții corecte este o metodă foarte ușoară de a învăța informatică, astfel că oferim sursele pentru peste 1500 de probleme de pe platforma PbInfo.ro.

Pentru rezolvări PbInfo de la peste 1500 de probleme, vă invităm să intrați pe site-ul nostru!