Python 3.x 如何使用Python 3从S3获得的OpenCV读取图像?
我的S3 bucket文件夹中有一堆图像 我有一个S3的按键列表(Python 3.x 如何使用Python 3从S3获得的OpenCV读取图像?,python-3.x,amazon-web-services,opencv,amazon-s3,boto3,Python 3.x,Amazon Web Services,Opencv,Amazon S3,Boto3,我的S3 bucket文件夹中有一堆图像 我有一个S3的按键列表(img_list),我可以读取和显示图像: key = img_list[0] bucket = s3_resource.Bucket(bucket_name) img = bucket.Object(key).get().get('Body').read() 我有一个功能: def image_from_s3(bucket, key): bucket = s3_resource.Bucket(bucket)
img_list
),我可以读取和显示图像:
key = img_list[0]
bucket = s3_resource.Bucket(bucket_name)
img = bucket.Object(key).get().get('Body').read()
我有一个功能:
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))
现在我想使用OpenCV读取图像,但我得到一个错误:
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 error
key=img\u列表[0]
bucket=s3\u资源.bucket(bucket\u名称)
img=bucket.Object(key.get().get('Body').read()
cv2.imread(img)
系统错误回溯(最近一次调用上次)
在里面
2 bucket=s3_资源.bucket(bucket_名称)
3 img=bucket.Object(key.get().get('Body').read()
---->4 cv2.imread(img)
SystemError:返回NULL而未设置错误
请告知如何正确阅读?对不起,我在评论中弄错了。此代码在内存缓冲区中设置一个PNG文件,以模拟从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 bucket
现在,我只需要这个:
nparray = cv2.imdecode(np.asarray(bytearray(raw)), cv2.IMREAD_COLOR)
因此,您需要:
bucket = s3_resource.Bucket(bucket_name)
img = bucket.Object(key).get().get('Body').read()
nparray = cv2.imdecode(np.asarray(bytearray(img)), cv2.IMREAD_COLOR)
希望这将是上述要求的最佳解决方案,使用URL读取s3存储桶中的图像
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()
使用For循环迭代键列表中的所有键。在调用函数create\u presigned\u url之前。当您不从磁盘读取时,您需要
img=cv2.imdecode(buffer)
。@MarkSetchell在这种情况下的缓冲区将是bucket.Object(key.get().get('Body')。read()
?可能,我不知道您的bucket中有什么。。如果是JPEG,它应该以十六进制的0xff0xd8
开头。@MarkSetchell我的bucket由文件夹组成,其中一个文件夹包含所有PNG图像。我也有PDF,但这是另一个问题。我想连接到S3(我已经这样做了),拿着钥匙把它传给cv2。下面是我得到的错误:TypeError:imdecode()缺少必需的参数“flags”(位置2)。这些标志与cv2.imread()相同。
.Worked!!!如果我错了,你能纠正我吗:你正在用bytearray读取它,因为它是以字节形式给出的,然后传输到一个矩阵?imdecode()
似乎需要一个Numpy数组和一个AFAIK,np.asarray()
在不复制的情况下从bytearray
准确地创建它,所以它应该相当快。可能还有其他方法(我不是专家),所以如果有人知道,请告诉我。顺便说一句,我想你可能无法更改你得到的Numpy图像,除非你用myCopy=nparray.copy()
进行复制,或者你将原来的np.asarray(…)
更改为np.array(…)
。非常感谢!我已经给你发了一封电子邮件(在你的网站上)。我的荣幸@MarkSetchellNote:请在respVery-nice代码中将url更改为url,以便处理来自s3的图像。但是你能帮助我如何从s3到cv2读取多个图像吗?你可以在一行url=s3中完成。生成预签名的url('get_object',Params={'Bucket':s3BucketName,'Key':documentName})无需循环并列出对象