Google Cloud Vision – czyli rozpoznawanie obrazów w chmurze, część 1: OCR

Google udostępniło API pozwalające na rozpoznawanie obrazów. W liście funkcjonalności możemy znaleźć wiele ciekawych pozycji:

  • Label Detection – kategoryzowanie zawartości obrazka, możemy otrzymać informację, że na obrazku znajduje się zwierzę,
  • Explicit Content Detection – wykrywanie nieodpowiedniej zawartości – takiej jak przemoc czy treści dla dorosłych
  • Logo Detection – wykrywa logo znanych marek,
  • Landmark Detection – wykrywanie znanych budowli,
  • Optical Character Recognition (OCR) – rozpoznawanie tekstu,
  • Face Detection – wykrywanie twarzy na zdjęciu,
  • Image Attributes – podaje informacje o obrazie, np. dominujący kolor

W tym poście pokażę jak skorzystać z rozpoznawania tekstu na przykładzie zdjęcia paragonu 🙂

Jak zawsze przykładowy kod można znaleźć na moim GitHubie w postaci gotowego do uruchomienia projektu. Kod z postu znajduje się pod adresem: https://github.com/mloza/google-cloud-storage

Chciałem jeszcze wcześniej wspomnieć o bardzo ważnej rzeczy, a mianowicie Vison API nie rozpoznaje polskich znaków, wspiera tylko alfabet łaciński. Jednak w zamian oferuje pierwsze 1,000 requestów do API za darmo.

Punktem wyjścia będzie projekt z poprzedniego postu o Google Cloud Storage, tam pokazywałem jak się uwierzytelnić i jak wysłać coś do chmury. Tym razem też musimy przesłać obrazek do Cloud Storage przed jego przetworzeniem. Jak już wspomniałem wcześniej naszą ofiarą będzie zdjęcie paragonu:
2016-05-29 15.15.57

Zdjęcie jest wyraźne, paragon lekko pomięty ale wciąż bardzo czytelny. Nie powinno być problemu z rozpoznaniem zawartości. Zatem do dzieła.

Przesłanie obrazka do bucketu.

Autoryzacja i tworzenie obiektów API opisywałem w poprzednim poście. Kod znajduje się również w GitHubie. Dla przypomnienia kod, który tworzy klienta Google Cloud Storage wygląda następująco:

HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
JsonFactory jsonFactory = new JacksonFactory();
Credential credential = GoogleCredential
    .fromStream(
        Main.class.getClassLoader()
            .getResourceAsStream("client-secrets.json")) 
    .createScoped(Collections.singleton(StorageScopes.CLOUD_PLATFORM));

Storage storage = new Storage.Builder(httpTransport, jsonFactory, credential)
    .setApplicationName("Test project")
    .build();

Pierwszym krokiem jest przesłanie zdjęcia do chmury, gdzie usługa Vision będzie mogła się do niego dostać. Odpowiada za to następujący kod:

InputStreamContent mediaContent = new InputStreamContent("image/jpeg", 
                getClass().getClassLoader().getResourceAsStream(PICTURE_NAME));
        
StorageObject object = storage
        .objects()
        .insert(BUCKET, null, mediaContent)
        .setName(PICTURE_NAME)
        .execute();

System.out.println("Adres przesłanego obrazu: "+object.getSelfLink());

Mamy już obrazek w buckecie, Yay!

Rozpoznawanie tekstu

Potrzebujemy nowej zależności w pom.xml do biblioteki vision:

 <dependency>
    <groupId>com.google.apis</groupId>
    <artifactId>google-api-services-vision</artifactId>
    <version>v1-rev15-1.22.0</version>
</dependency>

Podobnie jak do Storage tworzymy sobie klienta Vision, który pozwoli nam na wywoływanie metod z API:

 Vision visionClient = new Vision.Builder(httpTransport, jsonFactory, credential)
       .setApplicationName(APPLICATION_NAME)
       .build();

Mając klienta możemy przejść do wywołania żądania przetworzenia obrazu. Jest ono dość duże w porównaniu z poprzednimi przykładami kodu:

Image image = new Image().setSource(new ImageSource() //1
        .setGcsImageUri("gs://" + BUCKET + "/" + PICTURE_NAME));

Feature annotateFeature = new Feature() //2
        .setType("TEXT_DETECTION");

AnnotateImageRequest annotateImage = new AnnotateImageRequest()  // 3
        .setFeatures(Collections.singletonList(annotateFeature))
        .setImage(image);

BatchAnnotateImagesResponse text_detection = visionClient // 4
        .images()
        .annotate(
                new BatchAnnotateImagesRequest()
                        .setRequests(Collections.singletonList(annotateImage)))
        .execute();

System.out.println(text_detection.getResponses().get(0).getTextAnnotations()); //5

Najpierw tworzymy obiekt reprezentujący nasz obrazek, podając url w postaci gs://nazwa-bucketu/nazwa-obrazka.jpg [1]. Następnie tworzymy obiekt, który będzie reprezentował, co chcemy otrzymać z obrazka, w naszym przypadku będzie to rozpoznawanie tekstu [2]. Kolejnym krokiem jest stworzenie obiektu zapytania, przekazując mu wcześniej stworzony obrazek oraz wymagany tryb przetwarzania [3]. Ostatnim krokiem jest wysłanie zapytania z użyciem wcześniej stworzonego klienta [4]. W jednym zapytaniu możemy przekazać większą ilość obrazków do przetworzenia, jeśli zajdzie taka potrzeba.

W odpowiedzi dostaniemy JSON, który zawiera pełny tekst z obrazka oraz poszczególne słowa/fragmenty wraz z koordynatami, w którym miejscu został rozpoznany. Odpowiedź z serwisu dotycząca naszego testowego zdjęcia paragonu wygląda następująco (uwaga, 1429 linii po sformatowaniu!):

[
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 337,
                    "y": 801
                },
                {
                    "x": 2242,
                    "y": 801
                },
                {
                    "x": 2242,
                    "y": 2787
                },
                {
                    "x": 337,
                    "y": 2787
                }
            ]
        },
        "description": "SKLEP \"ZABKA'' Z3816\nul. Mogilska 59, 31-545 Krakow\nPHU \"DANA\"\nNIP 678-185-16-34\n2016-05-29\nnr Wydr 808669\nPARAGON FISKALNY\nMLEKO KONECKIE D\n2,50 zh. 2,50 D\nMLEKO KONECKIE D 1 2,50 zt, 2,50 D\nSprzed. opod. PTU D\n5,00\nKwota D 05,00%\n0,24\nPodatek PTU\n0,24\nSUMA PLN\n5,00\n0003241 5 MACIEK\n08:43\n1EIOS-NLNTD-0GXTD-ON09 G-XYUSE\nBAE 13112254\nPtatno\na kred\n5,00\n501782\n",
        "locale": "pl"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 876,
                    "y": 801
                },
                {
                    "x": 1089,
                    "y": 801
                },
                {
                    "x": 1089,
                    "y": 898
                },
                {
                    "x": 876,
                    "y": 898
                }
            ]
        },
        "description": "SKLEP"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1133,
                    "y": 801
                },
                {
                    "x": 1432,
                    "y": 801
                },
                {
                    "x": 1432,
                    "y": 898
                },
                {
                    "x": 1133,
                    "y": 898
                }
            ]
        },
        "description": "\"ZABKA''"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1475,
                    "y": 801
                },
                {
                    "x": 1693,
                    "y": 801
                },
                {
                    "x": 1693,
                    "y": 898
                },
                {
                    "x": 1475,
                    "y": 898
                }
            ]
        },
        "description": "Z3816"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 662,
                    "y": 898
                },
                {
                    "x": 778,
                    "y": 898
                },
                {
                    "x": 778,
                    "y": 1009
                },
                {
                    "x": 662,
                    "y": 1009
                }
            ]
        },
        "description": "ul."
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 825,
                    "y": 898
                },
                {
                    "x": 1167,
                    "y": 898
                },
                {
                    "x": 1167,
                    "y": 1009
                },
                {
                    "x": 825,
                    "y": 1009
                }
            ]
        },
        "description": "Mogilska"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1212,
                    "y": 898
                },
                {
                    "x": 1337,
                    "y": 898
                },
                {
                    "x": 1337,
                    "y": 1009
                },
                {
                    "x": 1212,
                    "y": 1009
                }
            ]
        },
        "description": "59,"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1386,
                    "y": 898
                },
                {
                    "x": 1648,
                    "y": 898
                },
                {
                    "x": 1648,
                    "y": 1009
                },
                {
                    "x": 1386,
                    "y": 1009
                }
            ]
        },
        "description": "31-545"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1692,
                    "y": 898
                },
                {
                    "x": 1959,
                    "y": 898
                },
                {
                    "x": 1959,
                    "y": 1009
                },
                {
                    "x": 1692,
                    "y": 1009
                }
            ]
        },
        "description": "Krakow"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1086,
                    "y": 1010
                },
                {
                    "x": 1214,
                    "y": 1013
                },
                {
                    "x": 1211,
                    "y": 1107
                },
                {
                    "x": 1083,
                    "y": 1104
                }
            ]
        },
        "description": "PHU"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1259,
                    "y": 1013
                },
                {
                    "x": 1512,
                    "y": 1020
                },
                {
                    "x": 1509,
                    "y": 1114
                },
                {
                    "x": 1256,
                    "y": 1107
                }
            ]
        },
        "description": "\"DANA\""
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 914,
                    "y": 1101
                },
                {
                    "x": 1037,
                    "y": 1106
                },
                {
                    "x": 1033,
                    "y": 1206
                },
                {
                    "x": 910,
                    "y": 1201
                }
            ]
        },
        "description": "NIP"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1082,
                    "y": 1107
                },
                {
                    "x": 1644,
                    "y": 1132
                },
                {
                    "x": 1640,
                    "y": 1231
                },
                {
                    "x": 1078,
                    "y": 1207
                }
            ]
        },
        "description": "678-185-16-34"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 390,
                    "y": 1208
                },
                {
                    "x": 824,
                    "y": 1227
                },
                {
                    "x": 820,
                    "y": 1313
                },
                {
                    "x": 386,
                    "y": 1294
                }
            ]
        },
        "description": "2016-05-29"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1592,
                    "y": 1236
                },
                {
                    "x": 1680,
                    "y": 1232
                },
                {
                    "x": 1684,
                    "y": 1332
                },
                {
                    "x": 1596,
                    "y": 1336
                }
            ]
        },
        "description": "nr"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1722,
                    "y": 1231
                },
                {
                    "x": 1907,
                    "y": 1223
                },
                {
                    "x": 1911,
                    "y": 1323
                },
                {
                    "x": 1726,
                    "y": 1331
                }
            ]
        },
        "description": "Wydr"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1949,
                    "y": 1220
                },
                {
                    "x": 2236,
                    "y": 1207
                },
                {
                    "x": 2240,
                    "y": 1307
                },
                {
                    "x": 1953,
                    "y": 1320
                }
            ]
        },
        "description": "808669"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 935,
                    "y": 1321
                },
                {
                    "x": 1254,
                    "y": 1328
                },
                {
                    "x": 1252,
                    "y": 1433
                },
                {
                    "x": 933,
                    "y": 1426
                }
            ]
        },
        "description": "PARAGON"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1294,
                    "y": 1329
                },
                {
                    "x": 1638,
                    "y": 1336
                },
                {
                    "x": 1636,
                    "y": 1441
                },
                {
                    "x": 1292,
                    "y": 1434
                }
            ]
        },
        "description": "FISKALNY"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 379,
                    "y": 1421
                },
                {
                    "x": 602,
                    "y": 1421
                },
                {
                    "x": 602,
                    "y": 1515
                },
                {
                    "x": 379,
                    "y": 1515
                }
            ]
        },
        "description": "MLEKO"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 642,
                    "y": 1413
                },
                {
                    "x": 983,
                    "y": 1417
                },
                {
                    "x": 981,
                    "y": 1541
                },
                {
                    "x": 640,
                    "y": 1537
                }
            ]
        },
        "description": "KONECKIE"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1029,
                    "y": 1421
                },
                {
                    "x": 1072,
                    "y": 1421
                },
                {
                    "x": 1072,
                    "y": 1515
                },
                {
                    "x": 1029,
                    "y": 1515
                }
            ]
        },
        "description": "D"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1547,
                    "y": 1443
                },
                {
                    "x": 1720,
                    "y": 1443
                },
                {
                    "x": 1720,
                    "y": 1525
                },
                {
                    "x": 1547,
                    "y": 1525
                }
            ]
        },
        "description": "2,50"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1765,
                    "y": 1427
                },
                {
                    "x": 1899,
                    "y": 1429
                },
                {
                    "x": 1897,
                    "y": 1553
                },
                {
                    "x": 1763,
                    "y": 1551
                }
            ]
        },
        "description": "zh."
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1944,
                    "y": 1443
                },
                {
                    "x": 2140,
                    "y": 1443
                },
                {
                    "x": 2140,
                    "y": 1525
                },
                {
                    "x": 1944,
                    "y": 1525
                }
            ]
        },
        "description": "2,50"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 2186,
                    "y": 1443
                },
                {
                    "x": 2233,
                    "y": 1443
                },
                {
                    "x": 2233,
                    "y": 1525
                },
                {
                    "x": 2186,
                    "y": 1525
                }
            ]
        },
        "description": "D"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 377,
                    "y": 1533
                },
                {
                    "x": 588,
                    "y": 1533
                },
                {
                    "x": 588,
                    "y": 1622
                },
                {
                    "x": 377,
                    "y": 1622
                }
            ]
        },
        "description": "MLEKO"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 640,
                    "y": 1523
                },
                {
                    "x": 981,
                    "y": 1527
                },
                {
                    "x": 980,
                    "y": 1643
                },
                {
                    "x": 639,
                    "y": 1639
                }
            ]
        },
        "description": "KONECKIE"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1024,
                    "y": 1526
                },
                {
                    "x": 1101,
                    "y": 1527
                },
                {
                    "x": 1100,
                    "y": 1643
                },
                {
                    "x": 1023,
                    "y": 1642
                }
            ]
        },
        "description": "D"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1255,
                    "y": 1529
                },
                {
                    "x": 1332,
                    "y": 1530
                },
                {
                    "x": 1331,
                    "y": 1646
                },
                {
                    "x": 1254,
                    "y": 1645
                }
            ]
        },
        "description": "1"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1547,
                    "y": 1553
                },
                {
                    "x": 1719,
                    "y": 1553
                },
                {
                    "x": 1719,
                    "y": 1639
                },
                {
                    "x": 1547,
                    "y": 1639
                }
            ]
        },
        "description": "2,50"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1762,
                    "y": 1553
                },
                {
                    "x": 1894,
                    "y": 1553
                },
                {
                    "x": 1894,
                    "y": 1639
                },
                {
                    "x": 1762,
                    "y": 1639
                }
            ]
        },
        "description": "zt,"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1944,
                    "y": 1553
                },
                {
                    "x": 2141,
                    "y": 1553
                },
                {
                    "x": 2141,
                    "y": 1639
                },
                {
                    "x": 1944,
                    "y": 1639
                }
            ]
        },
        "description": "2,50"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 2186,
                    "y": 1553
                },
                {
                    "x": 2232,
                    "y": 1553
                },
                {
                    "x": 2232,
                    "y": 1639
                },
                {
                    "x": 2186,
                    "y": 1639
                }
            ]
        },
        "description": "D"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 371,
                    "y": 1743
                },
                {
                    "x": 675,
                    "y": 1743
                },
                {
                    "x": 675,
                    "y": 1841
                },
                {
                    "x": 371,
                    "y": 1841
                }
            ]
        },
        "description": "Sprzed."
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 718,
                    "y": 1743
                },
                {
                    "x": 926,
                    "y": 1743
                },
                {
                    "x": 926,
                    "y": 1841
                },
                {
                    "x": 718,
                    "y": 1841
                }
            ]
        },
        "description": "opod."
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 973,
                    "y": 1743
                },
                {
                    "x": 1110,
                    "y": 1743
                },
                {
                    "x": 1110,
                    "y": 1841
                },
                {
                    "x": 973,
                    "y": 1841
                }
            ]
        },
        "description": "PTU"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1152,
                    "y": 1743
                },
                {
                    "x": 1196,
                    "y": 1743
                },
                {
                    "x": 1196,
                    "y": 1841
                },
                {
                    "x": 1152,
                    "y": 1841
                }
            ]
        },
        "description": "D"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1931,
                    "y": 1778
                },
                {
                    "x": 2129,
                    "y": 1761
                },
                {
                    "x": 2138,
                    "y": 1862
                },
                {
                    "x": 1940,
                    "y": 1880
                }
            ]
        },
        "description": "5,00"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 363,
                    "y": 1850
                },
                {
                    "x": 581,
                    "y": 1850
                },
                {
                    "x": 581,
                    "y": 1950
                },
                {
                    "x": 363,
                    "y": 1950
                }
            ]
        },
        "description": "Kwota"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 623,
                    "y": 1850
                },
                {
                    "x": 670,
                    "y": 1850
                },
                {
                    "x": 670,
                    "y": 1950
                },
                {
                    "x": 623,
                    "y": 1950
                }
            ]
        },
        "description": "D"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 715,
                    "y": 1850
                },
                {
                    "x": 979,
                    "y": 1850
                },
                {
                    "x": 979,
                    "y": 1950
                },
                {
                    "x": 715,
                    "y": 1950
                }
            ]
        },
        "description": "05,00%"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1941,
                    "y": 1888
                },
                {
                    "x": 2125,
                    "y": 1872
                },
                {
                    "x": 2134,
                    "y": 1975
                },
                {
                    "x": 1950,
                    "y": 1992
                }
            ]
        },
        "description": "0,24"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 356,
                    "y": 1958
                },
                {
                    "x": 663,
                    "y": 1958
                },
                {
                    "x": 663,
                    "y": 2048
                },
                {
                    "x": 356,
                    "y": 2048
                }
            ]
        },
        "description": "Podatek"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 712,
                    "y": 1958
                },
                {
                    "x": 845,
                    "y": 1958
                },
                {
                    "x": 845,
                    "y": 2048
                },
                {
                    "x": 712,
                    "y": 2048
                }
            ]
        },
        "description": "PTU"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1941,
                    "y": 2000
                },
                {
                    "x": 2120,
                    "y": 1992
                },
                {
                    "x": 2124,
                    "y": 2089
                },
                {
                    "x": 1945,
                    "y": 2097
                }
            ]
        },
        "description": "0,24"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 352,
                    "y": 2070
                },
                {
                    "x": 704,
                    "y": 2070
                },
                {
                    "x": 704,
                    "y": 2240
                },
                {
                    "x": 352,
                    "y": 2240
                }
            ]
        },
        "description": "SUMA"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 790,
                    "y": 2070
                },
                {
                    "x": 1049,
                    "y": 2070
                },
                {
                    "x": 1049,
                    "y": 2240
                },
                {
                    "x": 790,
                    "y": 2240
                }
            ]
        },
        "description": "PLN"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1837,
                    "y": 2113
                },
                {
                    "x": 2196,
                    "y": 2082
                },
                {
                    "x": 2212,
                    "y": 2268
                },
                {
                    "x": 1853,
                    "y": 2299
                }
            ]
        },
        "description": "5,00"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 349,
                    "y": 2243
                },
                {
                    "x": 656,
                    "y": 2243
                },
                {
                    "x": 656,
                    "y": 2341
                },
                {
                    "x": 349,
                    "y": 2341
                }
            ]
        },
        "description": "0003241"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 725,
                    "y": 2243
                },
                {
                    "x": 795,
                    "y": 2243
                },
                {
                    "x": 795,
                    "y": 2341
                },
                {
                    "x": 725,
                    "y": 2341
                }
            ]
        },
        "description": "5"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 838,
                    "y": 2243
                },
                {
                    "x": 1099,
                    "y": 2243
                },
                {
                    "x": 1099,
                    "y": 2341
                },
                {
                    "x": 838,
                    "y": 2341
                }
            ]
        },
        "description": "MACIEK"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1984,
                    "y": 2282
                },
                {
                    "x": 2200,
                    "y": 2282
                },
                {
                    "x": 2200,
                    "y": 2361
                },
                {
                    "x": 1984,
                    "y": 2361
                }
            ]
        },
        "description": "08:43"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 616,
                    "y": 2342
                },
                {
                    "x": 1576,
                    "y": 2362
                },
                {
                    "x": 1574,
                    "y": 2467
                },
                {
                    "x": 614,
                    "y": 2447
                }
            ]
        },
        "description": "1EIOS-NLNTD-0GXTD-ON09"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1598,
                    "y": 2363
                },
                {
                    "x": 1887,
                    "y": 2369
                },
                {
                    "x": 1885,
                    "y": 2474
                },
                {
                    "x": 1596,
                    "y": 2468
                }
            ]
        },
        "description": "G-XYUSE"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1109,
                    "y": 2471
                },
                {
                    "x": 1242,
                    "y": 2471
                },
                {
                    "x": 1242,
                    "y": 2572
                },
                {
                    "x": 1109,
                    "y": 2572
                }
            ]
        },
        "description": "BAE"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1290,
                    "y": 2463
                },
                {
                    "x": 1642,
                    "y": 2478
                },
                {
                    "x": 1637,
                    "y": 2582
                },
                {
                    "x": 1285,
                    "y": 2567
                }
            ]
        },
        "description": "13112254"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 337,
                    "y": 2580
                },
                {
                    "x": 603,
                    "y": 2568
                },
                {
                    "x": 606,
                    "y": 2653
                },
                {
                    "x": 341,
                    "y": 2665
                }
            ]
        },
        "description": "Ptatno"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1310,
                    "y": 2578
                },
                {
                    "x": 1353,
                    "y": 2580
                },
                {
                    "x": 1348,
                    "y": 2673
                },
                {
                    "x": 1305,
                    "y": 2671
                }
            ]
        },
        "description": "a"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1402,
                    "y": 2586
                },
                {
                    "x": 1578,
                    "y": 2586
                },
                {
                    "x": 1578,
                    "y": 2680
                },
                {
                    "x": 1402,
                    "y": 2680
                }
            ]
        },
        "description": "kred"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 2011,
                    "y": 2593
                },
                {
                    "x": 2188,
                    "y": 2587
                },
                {
                    "x": 2191,
                    "y": 2680
                },
                {
                    "x": 2014,
                    "y": 2686
                }
            ]
        },
        "description": "5,00"
    },
    {
        "boundingPoly": {
            "vertices": [
                {
                    "x": 1923,
                    "y": 2696
                },
                {
                    "x": 2184,
                    "y": 2693
                },
                {
                    "x": 2185,
                    "y": 2782
                },
                {
                    "x": 1924,
                    "y": 2785
                }
            ]
        },
        "description": "501782"
    }
]

 

Cały rozpoznany tekst w porównaniu z obrazkiem:

SKLEP "ZABKA'' Z3816
ul. Mogilska 59, 31-545 Krakow
PHU "DANA"
NIP 678-185-16-34
2016-05-29
nr Wydr 808669
PARAGON FISKALNY
MLEKO KONECKIE D
2,50 zh. 2,50 D
MLEKO KONECKIE D 1 2,50 zt, 2,50 D
Sprzed. opod. PTU D
5,00
Kwota D 05,00%
0,24
Podatek PTU
0,24
SUMA PLN
5,00
0003241 5 MACIEK
08:43
1EIOS-NLNTD-0GXTD-ON09 G-XYUSE
BAE 13112254
Ptatno
a kred
5,00
501782
2016-05-29 15.15.57

Jak widać, program poradził sobie całkiem dobrze z tym zadaniem, trochę trudności mu sprawiły polskie litery. Sprawdzałem jego działanie również z większym paragonem, gdzie literki już nie były tak wyraźne i wyniki były równie zadowalające, nie było już tak poprawnie jak w przykładzie, jednak wciąż większość była rozpoznana poprawnie. Przy cenach proponowanych przez Google wygląda to bardzo dobrze. Zastanawiam się tylko czy z powodu opublikowania API zmienili mechanizm reCaptchy z przepisywania słów na klikanie w obrazki :]

1 myśl na “Google Cloud Vision – czyli rozpoznawanie obrazów w chmurze, część 1: OCR”

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *