dragos98gl
Posts: 1
Joined: Sun Jun 09, 2019 10:11 am

picamera & ILI9341 - change picamera encoder

Sun Jun 09, 2019 11:56 am

Hello!
I'm working to a project for college which involves real-time image processing on a Raspberry Pi Zero W.
My main problem is the processing speed.
I continously take frames from camera stream and display on a ILI9341 display using the Adafruit_ILI9341 library.

The problem is that the display request RGB565 and the CPU spend too much time on conversion

From Adafruit_ILI9341(https://github.com/adafruit/Adafruit_Py ... ILI9341.py):

Code: Select all

def image_to_data(image):
    """Generator function to convert a PIL image to 16-bit 565 RGB bytes."""
    #NumPy is much faster at doing this. NumPy code provided by:
    #Keith (https://www.blogger.com/profile/02555547344016007163)
    pb = np.array(image.convert('RGB')).astype('uint16')
    color = ((pb[:,:,0] & 0xF8) << 8) | ((pb[:,:,1] & 0xFC) << 3) | (pb[:,:,2] >> 3)
    return np.dstack(((color >> 8) & 0xFF, color & 0xFF)).flatten().tolist()
My code:

Code: Select all

def outputs():
    stream = io.BytesIO()
    while True:
        yield stream

        stream.seek(0)
		
	#thresh = 130
	#fn = lambda x : 255 if x > thresh else 0
	#img = Image.open(stream).convert('L').point(fn, mode='1')
		
	img = Image.open(stream)
	disp.display(img)
        
        stream.seek(0)
        stream.truncate()


with picamera.PiCamera() as camera:
    camera.resolution = (240, 320)
    camera.rotation=180
    #c = picamera.Color.rgb_565
    #camera.framerate = 60
    time.sleep(2)
    start = time.time()
    camera.capture_sequence(outputs(), 'jpeg', use_video_port=True)
    finish = time.time()
And my idea was to change the encoding type of camera directly to RGB565 but I don't know exactly how.
I read the encoding documentation but still don't know how to implement.

https://picamera.readthedocs.io/en/rele ... m-encoders
https://picamera.readthedocs.io/en/rele ... #piencoder

If someone already done that and want to help me I will so glad.

ghp
Posts: 1351
Joined: Wed Jun 12, 2013 12:41 pm
Location: Stuttgart Germany
Contact: Website

Re: picamera & ILI9341 - change picamera encoder

Sun Jun 09, 2019 5:34 pm

Possibly multithreading could help.
build 3 processes, acquire, convert and display.
Connect them with multiprocessing queues and send data acquire --> convert --> display.
Helps to use three cores instead only one core in a standard python process.

pootle
Posts: 320
Joined: Wed Sep 04, 2013 10:20 am
Location: Staffordshire
Contact: Website

Re: picamera & ILI9341 - change picamera encoder

Mon Jun 10, 2019 7:55 am

There is only 1 core in a pi zero, so additional processes will probably slow things down, rather than speed them up.

I assume the conversion cannot keep up with frames from the camera? How far away you are from what you want. Is the process 10% too slow, or 100% too slow or worse?

The solution depends on the scale of the problem, and on what might be OK to change. Here are a few options:

Is it practical to slow down the camera frame rate?

Choosing a display which requires bit twiddled data conversion was an unfortunate choice. Can you use a differernt display? - the pi's own display would make all your problems vanish.

Loading the data into a PIL image and than twiddling it is very inefficient. Get the data straight into a numpy array see here.

Adafruit libraries are sometimes rather basic in their implementation - there may be optimisations you can do in the library.

While numpy is vastly faster than python code, but for this sort of thing dedicated C code will significantly improve performance. Ultimately GPU code would be the fastest answer.

Return to “Python”