I am trying to calculate the pixel area of images uploaded to a bucket in S3. So far, I have managed to put a trigger on my Lambda function in response to an image upload in S3, I have also managed to add all the necessary libraries.
To read the image loaded into the bucket I used the key
inside cv2.imread()
, but in doing so I got a path integrity warning.
warning
[ WARN:[email protected]] global /io/opencv/modules/imgcodecs/src/loadsave.cpp
(239) findDecoder imread_('public/IMG-10.jpg'):
can't open/read file: check file path/integrity
lambda_function.py
import boto3
import base64
import numpy as np
import cv2
s3_client = boto3.client('s3')
def lambda_handler(event, context):
print(event)
# getting bucket and object key from event object
source_bucket = event['Records'][0]['s3']['bucket']['name']
key = event['Records'][0]['s3']['object']['key']
# taking image from bucket to calculate pixel area
image = cv2.imread(key)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray,0,255,cv2.THRESH_OTSU cv2.THRESH_BINARY)[1]
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
total = 0
for c in cnts:
x,y,w,h = cv2.boundingRect(c)
mask = np.zeros(image.shape, dtype=np.uint8)
cv2.fillPoly(mask, [c], [255,255,255])
mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
pixels = cv2.countNonZero(mask)
total = pixels
cv2.putText(image, '{}'.format(pixels), (x,y - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255,255,255), 2)
print(total)
My problem is how to correctly access the image path to be read via opencv.
CodePudding user response:
It's need to first establish a connection to S3, then download the image data, and finally decode the data with OpenCV.
Full sample code:
from io import BytesIO
import boto3
import base64
import numpy as np
import cv2
s3_client = boto3.client('s3')
def lambda_handler(event, context):
print(event)
# getting bucket and object key from event object
source_bucket = event['Records'][0]['s3']['bucket']['name']
key = event['Records'][0]['s3']['object']['key']
img_file = BytesIO()
s3_client.download_fileobj(source_bucket, key, img_file)
np_1d_array = np.frombuffer(img_file.getbuffer(), dtype="uint8")
image = cv2.imdecode(np_1d_array, cv2.IMREAD_COLOR)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray,0,255,cv2.THRESH_OTSU cv2.THRESH_BINARY)[1]
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
total = 0
for c in cnts:
x,y,w,h = cv2.boundingRect(c)
mask = np.zeros(image.shape, dtype=np.uint8)
cv2.fillPoly(mask, [c], [255,255,255])
mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
pixels = cv2.countNonZero(mask)
total = pixels
cv2.putText(image, '{}'.format(pixels), (x,y - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255,255,255), 2)
print("ÁREA EM PIXEL:", total)