'How to obtain path from ZipFile objects that could be passed into OpenCV?
I would like to pass the image file into OpenCV to create a NumPy array without unzipping it.
My code looks like this:
zip_file = r'D:\Folder\small_img.zip'
with zipfile.ZipFile(zip_file) as zip:
for info in zip.infolist():
path_to_image = os.path.abspath(info.filename)
zip_img = zip.open(info.filename)
pil_img = Image.open(zip_img).convert('RGB')
# cv_img = cv.imread(*)
The place where I put a *
is what I'm not sure what to pass in. I have created a few variables of class Pillow Image
(pil_img
), and ZipFileExt
(zip_img
). I understand that cv2.imread
only accepts a path. So, I have tried to pass in a path name, however I have not de-zipped the zip file, hence I also tried to create a absolute path (path_to_image
) that looks like ('D:\Folder\File1.jpg'
), and a file name (info.filename
) that looks like (File1.jpg
).
However, most of them render an error message:
TypeError: Can't convert object of type 'Image' to 'str' for 'filename'
or
TypeError: Can't convert object of type 'ZipExtFile' to 'str' for 'filename'
Or, in the case where I pass in path_to_image
or info.filename
, it returns None
.
Anyone knows what I could pass into cv2.imread
to get the NumPy array?
Solution 1:[1]
There's cv2.imdecode
for that purpose:
import cv2
import numpy as np
import zipfile
with zipfile.ZipFile('images.zip') as zf:
for info in zf.infolist():
zip_img = zf.open(info.filename)
cv_img = cv2.imdecode(np.frombuffer(zip_img.read(), dtype=np.uint8),
cv2.IMREAD_UNCHANGED)
On the ZipExtFile
object obtained from zipfile.ZipFile.open
, you can call read
to get the raw bytes. You then need np.frombuffer
to get a proper input for cv2.imdecode
.
If you (also) need the Pillow Image
object, you could also simply cast that one to some NumPy array, but have to keep in mind to correct the ordering from RGB (Pillow) to BGR (OpenCV):
import cv2
import numpy as np
from PIL import Image
import zipfile
with zipfile.ZipFile('images.zip') as zf:
for info in zf.infolist():
zip_img = zf.open(info.filename)
pil_img = Image.open(zip_img)
cv_img = cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGB2BGR)
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.19041-SP0
Python: 3.9.1
PyCharm: 2021.1.1
NumPy: 1.20.2
OpenCV: 4.5.1
Pillow: 8.2.0
----------------------------------------
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | HansHirse |