Xilinx / PYNQ

Python Productivity for ZYNQ
http://www.pynq.io/
BSD 3-Clause "New" or "Revised" License
1.98k stars 816 forks source link

PYNQ-Z1 output JPEG by HDMI #663

Closed ghost closed 6 years ago

ghost commented 6 years ago

I want to output a JPEG by HDMI, but I get a 'JPEG' object has no attribute 'flush' error,

img_folder = './yoloimages/'
img_file = os.path.join(img_folder, random.choice(os.listdir(img_folder)))
im = Image.open(img_file)
hdmi_out.writeframe(im)

How to transform a JPEG to a HDMI frame?

aniqurrehman commented 6 years ago

make na new output frame and then assign jpeg image to that frame . and pass that output frame to hdmi_out.writeframe().

ghost commented 6 years ago

Thank you. @aniqurrehman Now I can output my own JPEG by convert it to np.array. But I can directly assign outframe = np.array

import cv2
import numpy as np
from PIL import Image

img = Image.open("/home/xilinx/jupyter_notebooks/base/video/data/opencv_filters.jpg")
inframe = np.array(img)

grayscale = np.ndarray(shape=(hdmi_in.mode.height, 
                              hdmi_in.mode.width), dtype=np.uint8)
result = np.ndarray(shape=(hdmi_in.mode.height, 
                           hdmi_in.mode.width), dtype=np.uint8)
cv2.cvtColor(inframe,cv2.COLOR_RGB2GRAY,dst=grayscale)
cv2.Laplacian(grayscale, cv2.CV_8U, dst=result)
outframe = hdmi_out.newframe()
cv2.cvtColor(result, cv2.COLOR_GRAY2RGB,dst=outframe)
hdmi_out.writeframe(outframe)

I get the error by directly assign outframe = np.array

outframe = hdmi_out.newframe()
outframe = inframe
hdmi_out.writeframe(outframe)
AttributeError                            Traceback (most recent call last)
<ipython-input-87-536a109be150> in <module>()
      1 outframe = hdmi_out.newframe()
      2 outframe = inframe
----> 3 hdmi_out.writeframe(outframe)

/opt/python3.6/lib/python3.6/site-packages/pynq/lib/video.py in writeframe(self, frame)
   1290 
   1291         """
-> 1292         self._vdma.writechannel.writeframe(frame)
   1293 
   1294     async def writeframe_async(self, frame):

/opt/python3.6/lib/python3.6/site-packages/pynq/lib/video.py in writeframe(self, frame)
    632                     asyncio.ensure_future(self._interrupt.wait()))
    633             self._mmio.write(0x04, 0x1000)
--> 634             self._writeframe_internal(frame)
    635 
    636         async def writeframe_async(self, frame):

/opt/python3.6/lib/python3.6/site-packages/pynq/lib/video.py in _writeframe_internal(self, frame)
    614                 self.sourcechannel.tie(None)
    615 
--> 616             frame.flush()
    617             next_frame = (self.desiredframe + 1) % len(self._frames)
    618             self._frames[next_frame] = frame

AttributeError: 'numpy.ndarray' object has no attribute 'flush'
PeterOgden commented 6 years ago

You need to use the outframe[:] = inframe syntax. This will copy the data into the outframe array which is known to the video subsystem. By using outframe = inframe you are only setting the outframe reference to be the same as inframe. As inframe isn't know to the video subsystem you get the error.

ghost commented 6 years ago

Thank you so much, I will close this issues. @PeterOgden @aniqurrehman