Tengo un montón de imágenes en mi carpeta de depósito S3.
Tengo una lista de claves de S3 ( img_list ) y puedo leer y mostrar las imágenes:
key = img_list[0] bucket = s3_resource.Bucket(bucket_name) img = bucket.Object(key).get().get('Body').read()Tengo una función para eso:
def image_from_s3(bucket, key): bucket = s3_resource.Bucket(bucket) image = bucket.Object(key) img_data = image.get().get('Body').read() return Image.open(io.BytesIO(img_data))Ahora lo que quiero es leer la imagen usando OpenCV pero me sale un error:
key = img_list[0] bucket = s3_resource.Bucket(bucket_name) img = bucket.Object(key).get().get('Body').read() cv2.imread(img) SystemError Traceback (most recent call last) <ipython-input-13-9561b5237a85> in <module> 2 bucket = s3_resource.Bucket(bucket_name) 3 img = bucket.Object(key).get().get('Body').read() ----> 4 cv2.imread(img) SystemError: <built-in function imread> returned NULL without setting an errorPor favor, aconseje cómo leerlo de la manera correcta.
Lo siento, me equivoqué en los comentarios. Este código configura un archivo PNG en un búfer de memoria para simular lo que obtiene de S3:
#!/usr/bin/env python3 from PIL import Image, ImageDraw import cv2 # Create new solid red image and save to disk as PNG im = Image.new('RGB', (640, 480), (255, 0, 0)) im.save('image.png') # Slurp entire contents, raw and uninterpreted, from disk to memory with open('image.png', 'rb') as f: raw = f.read() # "raw" should now be very similar to what you get from your S3 bucketAhora, todo lo que necesito es esto:
nparray = cv2.imdecode(np.asarray(bytearray(raw)), cv2.IMREAD_COLOR)Entonces, deberías necesitar:
bucket = s3_resource.Bucket(bucket_name) img = bucket.Object(key).get().get('Body').read() nparray = cv2.imdecode(np.asarray(bytearray(img)), cv2.IMREAD_COLOR)Espero que esta sea la mejor solución para el requisito mencionado, para leer las imágenes del cubo s3 usando URL..!
import os import logging import boto3 from botocore.client import Config from botocore.exceptions import ClientError import numpy as np import urllib import cv2 s3_signature ={ 'v4':'s3v4', 'v2':'s3' } def create_presigned_url(bucket_name, bucket_key, expiration=3600, signature_version=s3_signature['v4']): s3_client = boto3.client('s3', aws_access_key_id="AWS_ACCESS_KEY", aws_secret_access_key="AWS_SECRET_ACCESS_KEY", config=Config(signature_version=signature_version), region_name='ap-south-1' ) try: response = s3_client.generate_presigned_url('get_object', Params={'Bucket': bucket_name, 'Key': bucket_key}, ExpiresIn=expiration) print(s3_client.list_buckets()['Owner']) for key in s3_client.list_objects(Bucket=bucket_name,Prefix=bucket_key)['Contents']: print(key['Key']) except ClientError as e: logging.error(e) return None # The response contains the presigned URL return response def url_to_image(URL): resp = urllib.request.urlopen(url) image = np.asarray(bytearray(resp.read()), dtype="uint8") image = cv2.imdecode(image, cv2.IMREAD_COLOR) return image seven_days_as_seconds = 604800 generated_signed_url = create_presigned_url(you_bucket_name, bucket_key, seven_days_as_seconds, s3_signature['v4']) print(generated_signed_url) image_complete = url_to_image(generated_signed_url) #just debugging Purpose to show the read Image cv2.imshow('Final_Image',image_complete) cv2.waitKey(0) cv2.destroyAllWindows()Use For Loop para iterar a todas las claves en la lista de claves. Justo antes de llamar a la función create_presigned_url.