Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EasyOCR example added for text detection in images #43

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions samples/PT37_opengpu_easyocr/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Run EasyOCR library on AWS Panorama

## Brief
In this guide, we show how to use easyocr library on the Panorama device.

## Setup the application

The dependencies folder included with this application has

* The Dockerfile
* TensorRT 7.1
* Cuda Enabled PyTorch for Jetson Xavier

## Steps for setting this up

* Step 1: Navigate to ./dependencies
* Step 2 : ``` sudo docker build -t pt:37 . ```
* Step 3 : Open pytorch_example.ipynb and make sure you configure the following
* The Device ID
* The Camera node information
* Step 4 : Follow the steps outlined in the notebook

## Special flags in package.json

* Step 1 : Before you deploy the application, open PT37_opengpu_easyocr/easyocr_37_app/packages/(account-id)-easyocr_37_app-1.0/package.json
* Step 2 : Add the following flags to the package.json

```
"requirements":
[{
"type" : "hardware_access",
"inferenceAccelerators": [
{
"deviceType": "nvhost_gpu",
"sharedResourcePolicy": {
"policy" : "allow_all"
}
}
]
}]
```

The assets should look something like this

```
"assets": [
{
"name": "easyocr_37_2_app",
"implementations": [
{
"type": "container",
"assetUri": "9a49a98784f4571adacc417f00942dac7ef2e34686eef21dca9fcb7f4b7ffd70.tar.gz",
"descriptorUri": "4bab130ec48eea84e072d9fe813b947e9d9610b2924099036b0165026a91d306.json",
"requirements":
[{
"type" : "hardware_access",
"inferenceAccelerators": [
{
"deviceType": "nvhost_gpu",
"sharedResourcePolicy": {
"policy" : "allow_all"
}
}
]
}]
}
]
}
],
```

# Debugging

If you encounter issues with deploying from this, once the application is uploaded to the cloud, you can use the graph.json and deploy using the Panorama console as well
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"nodeGraphOverrides": {"envelopeVersion": "2021-01-01", "packages": [{"name": "028663699634::test_rtsp_camera_lab3", "version": "2.0"}], "nodes": [{"name": "test_rtsp_camera_lab3", "interface": "028663699634::test_rtsp_camera_lab3.test_rtsp_camera_lab3", "overridable": true, "overrideMandatory": false, "launch": "onAppStart"}], "nodeOverrides": [{"replace": "front_door_camera", "with": [{"name": "test_rtsp_camera_lab3"}]}]}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"nodeGraph": {
"envelopeVersion": "2021-01-01",
"packages": [
{
"name": "028663699634::easyocr_37_2_app",
"version": "1.0"
},
{
"name": "panorama::hdmi_data_sink",
"version": "1.0"
},
{
"name": "panorama::abstract_rtsp_media_source",
"version": "1.0"
}
],
"nodes": [
{
"name": "front_door_camera",
"interface": "panorama::abstract_rtsp_media_source.rtsp_v1_interface",
"overridable": true,
"launch": "onAppStart",
"decorator": {
"title": "Camera front_door_camera",
"description": "Default description for camera front_door_camera"
}
},
{
"name": "easyocr_37_2_app_node",
"interface": "028663699634::easyocr_37_2_app.easyocr_37_2_app_interface",
"overridable": false,
"launch": "onAppStart"
},
{
"name": "output_node",
"interface": "panorama::hdmi_data_sink.hdmi0",
"overridable": true,
"launch": "onAppStart"
}
],
"edges": [
{
"producer": "front_door_camera.video_out",
"consumer": "easyocr_37_2_app_node.video_in"
},
{
"producer": "easyocr_37_2_app_node.video_out",
"consumer": "output_node.video_in"
}
]
}
}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Use the pre-built docker image attached in this example by doing ```docker load --input panoramasdk_gpu_access_base_image.tar.gz``` or build the base image yourself using the dockerfile provided under /docker/Dockerfile
FROM pt:37
RUN apt-get update && apt-get install -y libglib2.0-0
RUN python3.7 -m pip install boto3
COPY src /panorama
# COPY saved_model_trt_fp16 /panorama/saved_model_trt_fp16

# For easyOCR
RUN pip install opencv-python-headless==4.5.4.60
RUN pip install easyocr
RUN pip install -U scikit-image==0.17.2
RUN python3 -c 'import easyocr; easyocr.Reader(["en"], gpu=False);'
RUN chmod -R 777 /root/
RUN ls /root/.EasyOCR/model/ -lrt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"runtimeDescriptor":
{
"envelopeVersion": "2021-01-01",
"entry":
{
"path": "python3.7",
"name": "/panorama/src/app.py"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"nodePackage": {
"envelopeVersion": "2021-01-01",
"name": "easyocr_37_2_app",
"version": "1.0",
"description": "Default description for package easyocr_37_app",
"assets": [

],
"interfaces": [
{
"name": "easyocr_37_2_app_interface",
"category": "business_logic",
"asset": "easyocr_37_2_app",
"inputs": [
{
"name": "video_in",
"type": "media"
}
],
"outputs": [
{
"name": "video_out",
"type": "media"
}
]
}
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import logging
from logging.handlers import RotatingFileHandler

import easyocr
import numpy as np
import panoramasdk


class Application(panoramasdk.node):
def __init__(self):
"""Initializes the application's attributes with parameters from the interface, and default values."""
self.ocr_detector = easyocr.Reader(["en"], gpu=True)

logger.info('Initialiation complete.')


def process_streams(self):
"""Processes one frame of video from one or more video streams."""
self.frame_num += 1
logger.debug(self.frame_num)

# Loop through attached video streams
streams = self.inputs.video_in.get()
for stream in streams:
self.process_media(stream)

self.outputs.video_out.put(streams)

def process_media(self, stream):
"""Runs inference on a frame of video."""
image_data = stream.image
logger.debug(image_data.shape)

# Cropping image to focus on region to read OCR (top left region with 100*100 pixels)
cropped_image = image_data[:100, :100, :]

# Process results (object deteciton)
self.process_results(cropped_image, stream)

def process_results(self, cropped_image, stream):
"""Processes output tensors from a computer vision model and annotates a video frame."""
if any(dim_size==0 for dim_size in cropped_image.shape):
logger.warning("Image size too small")
return

list_of_words_detected = self.ocr_detector.readtext(cropped_image, detail=0)

drift = 0.05

# Logging and printing first 5 words
for idx, word in enumerate(list_of_words_detected[:5]):
logger.info('word #{} = {}'.format(str(idx), word))
stream.add_label('word #{} = {}'.format(str(idx), word), 0.1, 0.1*(drift*idx))

def get_logger(name=__name__,level=logging.INFO):
logger = logging.getLogger(name)
logger.setLevel(level)
handler = RotatingFileHandler("/opt/aws/panorama/logs/app.log", maxBytes=100000000, backupCount=2)
formatter = logging.Formatter(fmt='%(asctime)s %(levelname)-8s %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger

def main():
try:
logger.info("INITIALIZING APPLICATION")
app = Application()
logger.info("PROCESSING STREAMS")
while True:
app.process_streams()
except:
logger.exception('Exception during processing loop.')

logger = get_logger(level=logging.INFO)
main()
Loading