Wednesday, May 1, 2019

A second image client

This one is quite different from the previous client. It sends the width and height of the image to the server, and reconstitutes the pickled Image object from the byte stream the server sends back. It then uses pygame to display the image in a window, and does that as fast as it can. The width and height default to 300x300, but can be altered from the command line.


A second image server

Variation on the first.  This server expects the client to send the dimensions of the image to be returned - if the aspect ratio is different to the camera's aspect ratio, the camera image is cropped (centrally) to the correct aspect ratio, resized using thumbnail(), and sent.  Also, rather than sending a byte stream of the image data, I'm using pickle.dumps() to create a byte stream from an Image object, and sending that (since I'm already creating an Image object for the cropping and resizing).


Wednesday, April 17, 2019

A terrible security camera 3 - the client software

Notes:
  • Again, I'm using argparse.  The IP address now has to be the server's address, not the client's!
  • The client receives the image data, puts it into a PIL Image object, and then crops it to a square and resizes it to the dimensions of the Unicorn Hat (16 x 16).
  • If the --debug flag was used, the original and cropped/resized image are saved to files.
  • The client keeps sending requests to the server as fast as it can (which is not very fast given the other work it's doing).
If I run the client with the command below, the current webcam image is displayed on the Unicorn Hat (updating about twice a second) until I press CTRL-C.

pi@pibow:~/Python/camclient $ ./image-client.py -i 192.168.1.106 

 

 

The code


A terrible security camera 2 - the server software

A few notes on the server software:
  • I'm using the argparse module to allow me to change key information (IP address, port, debug information) from the command line.  The default is to use port 12345 on localhost.
  • The server simply takes a photo and sends it to the client.
  • The server runs forever until the process is stopped (ideally with CTRL-C).
An example of running the server: picam's IP address is 192.168.1.106 (I have set it up to have a static address on my home wifi). To run the server:

pi@picam:~/Python/camserver $ ./image-server.py -i 192.168.1.106 --debug
Server started on 192.168.1.106:12345


Because I've used the --debug flag, the server tells me it has started and the address and port number it's using.

 

The code


A terrible security camera 1 - the hardware

Raspberry Pi 3B in a Pibow case, with a Unicorn Hat HD attached and a diffuser on top of the case (machine name "pibow"). The Unicorn Hat HD comes with a dark diffuser, I prefer the look of the lighter diffuser which covers the whole top of the case.
Raspberry Pi Zero W in the official Pi case with a camera attached (machine name "picam").  The official case comes with a cable to attach the camera to the smaller connection on the Zero.

Raspberry Pi setup

A few notes on how I set up Raspberry Pi devices.

Static IP

My home router won't allocate addresses above 100 (I have set it up not to do so), so it is safe to use static IP addresses above that.  I keep a master list of allocated static addresses in /etc/hosts on my desktop (Linux) PC to avoid conflict with other addresses (doesn't do anything to avoid conflicts apart from having a master list in one place!). For example, a new Pi Zero W which I have called "pish" (it originally had a Pimoroni LED shim attached).

192.168.1.108 pish
 
Log in to pish and edit /etc/dhcpcd.conf to add the lines below, and reboot.


interface wlan0
static ip_address=192.168.1.108/24
static routers=192.168.1.1
static domain_name_servers=192.168.1.1
 
Assuming ssh is enabled on pish, on the desktop machine to allow login without password:

ssh-copy-id pi@pish

Shell

Add this line to .bashrc
 
export PATH=~/bin:$PATH
Create a ~/bin folder, and add this script to it in a file called update - allows quick system updates just by typing update at the command prompt.
#!/usr/bin/env bash

sudo apt update
sudo apt dist-upgrade
sudo apt autoremove
Create .inputrc and add this line to it (allows tab completion of file names ignoring upper and lower case variants).
set completion-ignore-case on

Editing

gvim (my preferred editor) gives a warning unless these packages are installed:

sudo apt install libcanberra-gtk*-module