# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: conda_python3
#     language: python
#     name: conda_python3
# ---

# # Text detection using Amazon Rekognition

# ***
# This notebook provides a walkthrough of the [text detection API](https://docs.aws.amazon.com/rekognition/latest/dg/text-detection.html) in Amazon Rekognition. You can quickly identify text in your video and image libraries to catalog footage and photos for marketing, advertising, and media industry use cases.
# ***

# # Initialize stuff

# Update boto3 to current version
# !conda upgrade -y boto3

# +
#Check to ensure that current version of boto3 is installed
import boto3
print(boto3.__version__)

import botocore
print(botocore.__version__)
# -

# Initialise Notebook
import boto3
from IPython.display import HTML, display, Image as IImage
from PIL import Image, ImageDraw, ImageFont
import time
import os

# +
# Curent AWS Region. Use this to choose corresponding S3 bucket with sample content

mySession = boto3.session.Session()
awsRegion = mySession.region_name
# -

# Init clients
rekognition = boto3.client('rekognition')
s3 = boto3.client('s3')

# +
# S3 bucket that contains sample images and videos

# We are providing sample images and videos in this bucket so
# you do not have to manually download/upload test images and videos.
bucketName = "aws-workshops-" + awsRegion

# +
# Create temporary directory
# This directory is not needed to call Rekognition APIs.
# We will only use this directory to download images from S3 bucket and draw bounding boxes

# !mkdir m1tmp
tempFolder = 'm1tmp/'
# -

# # Detect text in image
# ***

imageName = "content-moderation/media/coffee.jpg"

display(IImage(url=s3.generate_presigned_url('get_object', Params={'Bucket': bucketName, 'Key': imageName})))

# #### Call Rekognition to detect text in the image

# +
# Call Amazon Rekognition to detect text in the image
# https://docs.aws.amazon.com/rekognition/latest/dg/API_DetectText.html

detectTextResponse = rekognition.detect_text(
    Image={
        'S3Object': {
            'Bucket': bucketName,
            'Name': imageName,
        }
      },
      Filters={
        'WordFilter': {
            'MinConfidence': 90
        }
      }
)
# -

# #### Review the raw JSON reponse from Rekognition

# +
# Show JSON response returned by Rekognition Text API (Text Detection)
# In the JSON response below, you will see detected text, confidence score, and additional information.

display(detectTextResponse)
# -

# #### Display list of detected unsafe text

import string
unsafeWords = ["crap", "darn", "damm"]
for textDetection in detectTextResponse["TextDetections"]:
    # strip punctuation before checking match
    text = textDetection["DetectedText"].translate(str.maketrans('', '', string.punctuation))
    if(textDetection["Type"] == "WORD" and text in unsafeWords):
        print("Detected unsafe word: {}".format(textDetection["DetectedText"]))


# #### Show image with bounding boxes around detected objects

# +
# Define a function that will display image with bounded boxes around recognized text
# We will call this function in next step
  
def drawBoundingBoxes (sourceImage, boxes):
    # blue, green, red, grey
    colors = ((255,255,255),(255,255,255),(76,182,252),(52,194,123))
    
    # Download image locally
    imageLocation = tempFolder+os.path.basename(sourceImage)
    s3.download_file(bucketName, sourceImage, imageLocation)

    # Draws BB on Image
    bbImage = Image.open(imageLocation)
    draw = ImageDraw.Draw(bbImage)
    width, height = bbImage.size
    col = 0
    maxcol = len(colors)
    line= 3
    for box in boxes:
        x1 = int(box[1]['Left'] * width)
        y1 = int(box[1]['Top'] * height)
        x2 = int(box[1]['Left'] * width + box[1]['Width'] * width)
        y2 = int(box[1]['Top'] * height + box[1]['Height']  * height)
        
        draw.text((x1,y1),box[0],colors[col])
        for l in range(line):
            draw.rectangle((x1-l,y1-l,x2+l,y2+l),outline=colors[col])
        col = (col+1)%maxcol
    
    imageFormat = "PNG"
    ext = sourceImage.lower()
    if(ext.endswith('jpg') or ext.endswith('jpeg')):
        imageFormat = 'JPEG'

    bbImage.save(imageLocation,format=imageFormat)

    display(bbImage)


# +
# Extract bounding box information from JSON response above and display image with bounding boxes around text.

boxes = []
textDetections = detectTextResponse['TextDetections']
for textDetection in textDetections:
        boxes.append ((textDetection['Type'], textDetection["Geometry"]['BoundingBox']))
    
drawBoundingBoxes(imageName, boxes)
# -



# # Detect text in image using Filters and Regions of Interest
# ***

imageName = "content-moderation/media/coffee.jpg"

display(IImage(url=s3.generate_presigned_url('get_object', Params={'Bucket': bucketName, 'Key': imageName})))

# +
# Call Amazon Rekognition to detect text in the image
# https://docs.aws.amazon.com/rekognition/latest/dg/API_DetectText.html

detectTextResponse = rekognition.detect_text(
    Image={
        'S3Object': {
            'Bucket': bucketName,
            'Name': imageName,
        }
    },
    Filters={
        'WordFilter': {
            'MinConfidence': 90,
            'MinBoundingBoxHeight': 0.05,
            'MinBoundingBoxWidth': 0.02
        },
        'RegionsOfInterest': [
            {
                'BoundingBox': {
                    'Width': 0.1,
                    'Height': 0.05,
                    'Left': 0.01,
                    'Top': 0.01
                }
            },
        ]
    }
)

# +
# Show JSON response returned by Rekognition Text API (Text Detection)
# In the JSON response below, you will see detected text, confidence score, and additional information.

display(detectTextResponse)
# -

for textDetection in detectTextResponse["TextDetections"]:
    text = textDetection["DetectedText"]
    if(textDetection["Type"] == "WORD"):
        print("Word: {}".format(textDetection["DetectedText"]))



# # Detect text in video
#  Text detection in video is an async operation. 
# https://docs.aws.amazon.com/rekognition/latest/dg/text-detecting-video-procedure.html.
#
# - First we start a text detection job which returns a Job Id.
# - We can then call `get_text_detection` to get the job status and after job is complete, we can get object metadata.
# - In production use cases, you would usually use StepFunction or SNS topic to get notified when job is complete.
# ***

videoName = "content-moderation/media/serverless-bytes.mov"

# #### Call Rekognition to start a job for text detection

# +
# Start video text job
startTextDetection = rekognition.start_text_detection(
    Video={
        'S3Object': {
            'Bucket': bucketName,
            'Name': videoName,
        }
    },
)

textJobId = startTextDetection['JobId']
display("Job Id: {0}".format(textJobId))
# -

# #### Wait for text detection job to complete

# +
# Wait for text detection job to complete
# In production use cases, you would usually use StepFunction or SNS topic to get notified when job is complete.
getTextDetection = rekognition.get_text_detection(
    JobId=textJobId
)

while(getTextDetection['JobStatus'] == 'IN_PROGRESS'):
    time.sleep(5)
    print('.', end='')
 
    getTextDetection = rekognition.get_text_detection(
    JobId=textJobId
    )
    
display(getTextDetection['JobStatus'])
# -

# #### Review raw JSON reponse from Rekognition

# +
# Show JSON response returned by Rekognition Text Detection API
# In the JSON response below, you will see list of detected text.
# For each detected object, you will see information like Timestamp

display(getTextDetection)
# -

# #### Display recognized text in the video

# +
flaggedTextInVideo = ["AWS", "Twitter"]

theLines = {}

# Display timestamps and objects detected at that time
strDetail = "Text detected in video<br>=======================================<br>"
strOverall = "Text in the overall video:<br>=======================================<br>"

# Objects detected in each frame
for obj in getTextDetection['TextDetections']:
    if(obj['TextDetection']['Type'] == 'WORD'):
        ts = obj ["Timestamp"]
        cconfidence = obj['TextDetection']["Confidence"]
        oname = obj['TextDetection']["DetectedText"]

        if(oname in flaggedTextInVideo):
            print("Found flagged text at {} ms: {} (Confidence: {})".format(ts, oname, round(cconfidence,2)))

        strDetail = strDetail + "At {} ms: {} (Confidence: {})<br>".format(ts, oname, round(cconfidence,2))
        if oname in theLines:
            cojb = theLines[oname]
            theLines[oname] = {"Text" : oname, "Count": 1+cojb["Count"]}
        else:
            theLines[oname] = {"Text" : oname, "Count": 1}

# Unique objects detected in video
for theLine in theLines:
    strOverall = strOverall + "Name: {}, Count: {}<br>".format(theLine, theLines[theLine]["Count"])

# Display results
display(HTML(strOverall))
# -

# #### Show video in the player

# +
# Show video in a player

s3VideoUrl = s3.generate_presigned_url('get_object', Params={'Bucket': bucketName, 'Key': videoName})

videoTag = "<video controls='controls' autoplay width='640' height='360' name='Video' src='{0}'></video>".format(s3VideoUrl)

videoui = "<table><tr><td style='vertical-align: top'>{}</td></tr></table>".format(videoTag)

display(HTML(videoui))
# -

listui = "<table><tr><td style='vertical-align: top'>{}</td></tr></table>".format(strDetail)
display(HTML(listui))

# ***
# ### References
# - https://docs.aws.amazon.com/rekognition/latest/dg/API_DetectText.html
# - https://docs.aws.amazon.com/rekognition/latest/dg/API_StartTextDetection.html
# - https://docs.aws.amazon.com/rekognition/latest/dg/API_GetTextDetection.html
#
# ***

# You have successfully used Amazon Rekognition to identify text in images an videos.

StarcoderdataJupyterScriptsDedupFiltered