Package: rpi-camera-colony
RPi Camera Colony (RCC)Central control for video acquisition with (many) Raspberry Pi camerasRecord videos in parallel with one or more remote-controlled Raspberry Pi (RPi) cameras. :movie_camera:A single configuration file and a few lines of code allow specific and reproducible acquisition settings for groups of cameras.Example use with Python:importtimefromrpi_camera_colony.control.conductorimportConductorconductor=Conductor(settings_file="configuration_file")# Manages remote RPiconductor.start_acquisition()# Starts recording on all remotestime.sleep(20)# do nothing or something else in betweenconductor.stop_acquisition()# Stops recording on all remotesor on the commandline:rcc_conductor--config-data-fileCONFIG_DATA_FILE--acquisition-nameACQUISITION_NAMEFeaturesA centralised control objectOne central object handles all communication with the remote cameras and transmits the configuration settings to each.A single configuration file to define reproducible multi-camera acquisitionConfiguration parameters are centrally defined in an easy-to-read file format and then handed down to the cameras.Flexible entrypointsMultiple entrypoints for use in python scripts as well as in a single line on the commandline
Additionally, all levels are directly accessible: central Conductor, remote control handlers, and on the RPi the acquisition control (see below for details).NEW:Network video streamAdd an additional output via network video stream directly from the mainconfigor via commandline arguments when callingrcc_acquisition.configexample to use withrcc_conductoras usual:# ...[controllers][[camera_red_60]]description="back view"address="192.168.0.22"# Network stream setup:stream_video=Truestream_address="192.168.0.22"stream_port=8001# ...Command-line entrypoint example:Options:-s,--stream-video
-sipSTREAM_IP,--stream-ipSTREAM_IPIPaddressforvideostream.(default:192.168.100.31)-sportSTREAM_PORT,--stream-portSTREAM_PORTStreamport(default:8001)Example call:rcc_acquisition--auto-start--stream-video--stream-ip192.168.100.31--stream-port9898InstallationPython dependenciespython>= 3.6pyzmqconfigobjtqdmnumpypandasNote: Use conda to install numpy/pandas to get pre-compiled packages
(See below for instructions)On RPi only:picameraRPi.GPIOOther useful packagesFor video conversion:gpac  # contains MP4Box tool for video conversionExample hardware architecture[outside world / internet]
              |
              |
      [central machine]
              |
              |
      [network switch]
      /   |     |    \
     |    |     |     | <- network connection
[rpi #1]  |     |     |     e.g. ethernet cables
          |     |     |
     [rpi #2]   |     |
                |     |
              [...]   |
                      |
                 [rpi #n]Minimal hardware requirementsCentral machine, can be RPi itself (as it only holds the control object, but does no computation)Raspberry PiMain RPi board + fast SD card (+ card reader if not available on another machine)RPi Camera (+lens?) (depends on your specific acquisition requirements)RPi power supply (RPi4 requires USB-C connector)Display cable (RPi4 requires mico-HDMI connector)Ethernet cablesNetwork switch (if more than one RPi), e.g. any 1GB or fasterMapping between this package & hardwareOneConductor to instructallRPi cameras via network communication between the RemoteAcquisitionControl and PiAcquisitionControl.Hardware            <-->        Software


    [central machine]   <-->        Conductor
            |                           |
            |                       RemoteAcquisitionControl
            |                           |
           ...                         ...
            |                           |
       [rpi #n]         <-->        PiAcquisitionControl
                                        |
                                    CameraRaspberry Pi setupSet up RPi hardwareInstallRaspbian->NOTE: Use Raspbian Buster for now. There is no PiCamera equivalent readily available for the Raspbian Bullseye libcamera apps.Enable camera, GPIO interfaces, and ssh insudo raspi-configoptionsConnect hardware:CameraNetwork cableGPIO pin connection for TTL in/out (Seepinout.xyzforboard modepins to use)Note: adjust pin numbers used in configuration file. Default are pin #8 for frame TTL outputs and #16 for inputs. Choose any free ground pins!Install this packageSet up python, e.g. withminicondaClone this repository or usedistribute_code.shscript (Replace hostnames for your RPi)Install
a. From Pypipipinstallrpi_camera_colony[rpi]# <- Note: `[rpi]` argument adds specific requirements for acquisition on RPi, but is not required for controllerb. From Githubshell pip install https://github.com/larsrollik/rpi_camera_colony[rpi]  # <- Note: `[rpi]` argument adds specific requirements for acquisition on RPi, but is not required for controllerCentral control machine setupDHCP server on central computer. (Description only for Ubuntu)Set up static IP address on network interface that serves RPi colony via network switch, with e.g./etc/network/interfacesornetplanSet up DHCP server withisc-dhcp-serverSet up SSH keys to allow interaction with RPi without password (otherwise cannot drop remote process!)ssh-keygen  # into standard file if not exists, no passphrase
 ssh-copy-id -i ~/.ssh/id_rsa HOST  # where HOST = RPi host nameSet up python environment, e.g. withminicondaInstall this packageClone this repositoryInstall withpipinstallrpi_camera_colonyEntrypoints & levelsEasy access to central Conductorrcc_conductor--helpUse acquisition directly on RPifromrpi_camera_colony.acquisition.acquisition_controlimportPiAcquisitionControlorpythonrpi_camera_colony/acquisition--help# orpython-mrpi_camera_colony.acquisition--help# orrcc_acquisition--helpOne-to-one mapping of local control to remote acquisitionfromrpi_camera_colony.acquisition.remote_controlimportRemoteAcquisitionControlorpythonrpi_camera_colony/acquisition--help# orpython-mrpi_camera_colony.acquisition.remote_control--helpRead acquisition metadata & check for video filesfromrpi_camera_colonyimportread_session_dataSandbox Conductor object in separate process (python multiprocessing)Seerpi_camera_colony.control.process_sandboxfor example use of:fromrpi_camera_colony.control.process_sandboximportConductorAsProcessCitationRollik, Lars B. (2021). RPi Camera Colony: Central control for video acquisition with (many) Raspberry Pi cameras. doi:10.5281/zenodo.6414747.BibTeX@misc{rollik2021rpi,author={Lars B. Rollik},title={{RPi Camera Colony: Central control for video acquisition with (many) Raspberry Pi cameras}},year={2021},month=jun,publisher={Zenodo},url={https://doi.org/10.5281/zenodo.6414747},doi={10.5281/zenodo.6414747},}LicenseThis software is released under theBSD 3-Clause LicenseRelated projects with similar architecturesArne Meyer's RPiCameraPlugin for the OpenEphys GUISpecific API for one-to-one control mappings between OpenEphys GUI plugin instances and remote RPi cameras. Inspiration for use of ØMQ communication and camera TTL integration in encoder class.Deshmukh lab's PicameraPaperVideo acquisition with multiple RPi synchronised by a central TTL that is recorded with the camera timestamps.VidgearGeneral package for different types of video acquisition and streaming.Configuration file specification-> Note:additional picamera attributes can be used, but not all types implemented. Check below.-> Note:acquisition_groupis not specified by default, but ifacquisition_namecontains__double underscores, then theacquisition_groupwill get auto-populated from the first segment, when split on the__. This is to create an acquisition folder organisation like:/path_to_data/acquisition_group/acquisition_name/[files][general]acquisition_name=string(default="_test_rcc_name_config")# base name for recordingacquisition_time=string(default="dummy_time")acquisition_group=string(default="")remote_data_path=string(default="/home/pi/data/")# where to store all recordings on RPirpi_username=string(default="pi")remote_python_interpreter=string(default="/home/pi/miniconda3/envs/py36/bin/python")# path to pythonremote_python_entrypoint=string(default="rpi_camera_colony.acquisition")# path to __main__ entrypointmax_acquisition_time=integer(0,7200,default=7200)# seconds, shut down acquisition after expirationsave_data=boolean(default=True)# if False, then doesn't write files on RPigeneral_setting_has_priority=boolean(default=True)# If False, does not patch in general settingsgeneral_settings_to_patch_into_controller=string_list(default=list("save_data","acquisition_time","acquisition_group"))# Add variables here for patching into controllers[log]address=string(max=15,default="192.168.100.10")port=integer(default=55555)level=string(default="DEBUG")log_to_console=boolean(default=True)log_to_file=boolean(default=True)log_file=string(default="/tmp/rpi_camera_colony__logging")[control]address=string(default="192.168.100.10")port=integer(default=54545)[controllers][[__many__]]description=string(default="")address=string(max=15,default="")save_data=boolean(default=True)ttl_channel_external=integer(default=-1)# metadata info if recording output TTL on specific channel of other acquisition systemttl_in_pin=integer(default=16)ttl_out_pin=integer(default=8)ttl_out_duration=float(default=.001)# See for list of ALL parameters https://picamera.readthedocs.io/en/latest/api_camera.htmlframerate=integer(min=1,max=90,default=90)resolution=int_list(default=list(640,480))vflip=boolean(default=False)hflip=boolean(default=False)brightness=integer(min=0,max=100,default=50)# color_effects: (128, 128) == black and white acquisition. Default is None.color_effects=int_list(default=list(128,128))contrast=integer(min=-100,max=100,default=0)image_denoise=boolean(default=True)iso=integer(min=0,max=1600,default=0)led=boolean(default=False)preview_alpha=integer(min=0,max=255,default=255)# DEPRECATEDsaturation=integer(min=-100,max=100,default=0)sharpness=integer(min=-100,max=100,default=0)still_stats=boolean(default=False)video_denoise=boolean(default=True)video_stabilization=boolean(default=False)# zoom: (x, y, w, h)zoom=float_list(default=list(0.0,0.0,1.0,1.0))# Other picamera attributes / not implemented / not tested, but might work# awb_gains# awb_mode = option(default="auto")# drc_strength# exposure_compensation# exposure_mode# exposure_speed = 0# flash_mode = option("off", "auto", "on", "redeye", "fillin", "torch", default="off")# framerate_delta  # new in 1.11# framerate_range  # new in 1.13# image_effect = "none"# image_effect_params  # https://picamera.readthedocs.io/en/release-1.13/api_camera.html#picamera.PiCamera.image_effect_params# meter_mode = option("average", "spot", "backlit", "matrix")# rotation = option(0, 90, 180, 270)# sensor_mode = integer(default=0)# shutter_speed  # microsecondsSpecific install hintsHQ camera for RPi cannot acquire at resolutions or framerates outlined in the technical descriptionsudo rpi-updatefixes this. - Be careful, this updates the RPi firmware and might have unexpected side effects!Ip forwarding and routing on central machine# IP forwardsysctl-wnet.ipv4.ip_forward=1# check withcat/proc/sys/net/ipv4/ip_forward# Package routing# - outside interface (dhcp): enp7s0# - inside interface (static): enp8s0iptables-AFORWARD-ienp8s0-oenp7s0-jACCEPT
iptables-AFORWARD-ienp7s0-oenp8s0-mstate--stateESTABLISHED,RELATED-jACCEPT
iptables-tnat-APOSTROUTING-oenp7s0-jMASQUERADEUpdate time for ssl certificates# Check withtimedatectlstatus# force update with NTPsudoservicentpstop
sudontpd-gq
sudoservicentpstart# enable permanent updatessudosystemctlrestartsystemd-timesyncdInstall miniconda on RPi# Installing miniconda on RPiwgethttp://repo.continuum.io/miniconda/Miniconda3-latest-Linux-armv7l.sh
sudomd5sumMiniconda3-latest-Linux-armv7l.sh# (optional) check md5bashMiniconda3-latest-Linux-armv7l.sh# -> default directory should be: /home/pi/miniconda3# Add conda to pathecho'export PATH="/home/pi/miniconda3/bin:$PATH"'>>.bashrcsource.bashrc# or re-connect# Create conda environment and install basic packages (e.g. dependencies for this package)condaconfig--addchannelsrpi
condacreate-y-npy36python=3.6numpypandaspyzmqecho'source activate py36'>>.bashrcsource.bashrc# or re-connect# Re/install RCCpipuninstallrpi_camera_colony-y
pipinstall--upgraderpi_camera_colonyVersion: "0.5.0"