├── 16mpCaptureVideo.py ├── 16mpSetFrameRateAndSaveJpegPicture.py ├── 64mpGetDataSpeed.py ├── 64mpSavePng.py ├── AutofocusControl.py ├── CaptureExternalTrigger.py ├── CaptureMultiCameraAdapterModule.py ├── CaptureOpencvExample.py ├── HatSwitchCameraTakePicture.py ├── ManualfocusControl.py ├── PrintAllCameraControl.py ├── README.md ├── SetExposureTime.py ├── SetFrameRate.py ├── SetTriggerMode.py ├── ThreadRecordedVideo.py ├── imx708CaptureJpeg.py └── requirements.txt /16mpCaptureVideo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | ''' 3 | This is just a simple example. 4 | If you cannot accept that the Raspberry Pi hardware only supports 1080P, this example will give you an idea. 5 | Using opencv for software encoding will have some problems, but you can optimize it according to this idea. 6 | This example only test in Pi4, if you use other hardware, maybe have more problem. 7 | ''' 8 | 9 | import sys 10 | import signal 11 | import time 12 | import cv2 13 | from picamera2 import Picamera2 14 | 15 | def signal_handler(signal, frame): 16 | print('Program exits normally.') 17 | out.release() 18 | picam2.stop() 19 | print("Save video sucessful.") 20 | sys.exit(0) 21 | 22 | 23 | signal.signal(signal.SIGINT, signal_handler) 24 | 25 | width = 4624 26 | height = 3472 27 | 28 | picam2 = Picamera2() 29 | video_config = picam2.create_still_configuration(main={"size": (width, height), "format": "RGB888"}, buffer_count=1) 30 | picam2.configure(video_config) 31 | fourcc = cv2.VideoWriter_fourcc(*'XVID') 32 | 33 | picam2.start() 34 | 35 | print("Please use ctrl c to exit the program.") 36 | frame_count = 0 37 | times = 3 38 | start = time.time() 39 | while True: 40 | frame = picam2.capture_array(name="main") 41 | if times >= 1: 42 | frame_count += 1 43 | if time.time() - start >= 1: 44 | if sys.version[0] == '2': 45 | print("fps: {}".format(frame_count)) 46 | else: 47 | print("fps: {}".format(frame_count),end='\r') 48 | if times == 1: 49 | out = cv2.VideoWriter('output.mp4' ,fourcc, frame_count, (width, height)) 50 | frame_count = 0 51 | times -= 1 52 | start = time.time() 53 | else: 54 | if times == 0: 55 | print("Start save video.") 56 | times -= 1 57 | out.write(frame) 58 | 59 | -------------------------------------------------------------------------------- /16mpSetFrameRateAndSaveJpegPicture.py: -------------------------------------------------------------------------------- 1 | import time 2 | import cv2 3 | from picamera2 import Picamera2 4 | 5 | picam2 = Picamera2() 6 | preview_config = picam2.create_preview_configuration(main={"size": (4656, 3496)}, buffer_count=1) 7 | picam2.configure(preview_config) 8 | 9 | FRAME_RATE = 9 10 | FRAME_RATE = 1000000 // FRAME_RATE 11 | 12 | picam2.start() 13 | picam2.set_controls({"FrameDurationLimits":(FRAME_RATE,FRAME_RATE)}) 14 | 15 | save_picture_list = [] 16 | for i in range(2): 17 | save_picture_list.append(picam2.capture_array()) 18 | 19 | for i in range(len(save_picture_list)): 20 | cv2.imwrite("test_{}.jpg".format(i), save_picture_list[i]) 21 | print("Save picture {} success.".format(i)) 22 | 23 | picam2.close() 24 | -------------------------------------------------------------------------------- /64mpGetDataSpeed.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import time 4 | 5 | from picamera2 import Picamera2, Preview 6 | 7 | i = 0 8 | FrameRate = 2.7 9 | frame_time = 1000000 // FrameRate 10 | 11 | start = time.time() 12 | 13 | picam2 = Picamera2() 14 | # picam2.start_preview(Preview.QTGL) 15 | 16 | capture_config = picam2.create_still_configuration(main={"format": 'RGB888', "size": (9152, 6944)}) 17 | picam2.configure(capture_config) 18 | 19 | # picam2.set_controls({"FrameDurationLimits":(frame_time, frame_time)}) 20 | picam2.start() 21 | 22 | open_camera_time = time.time() 23 | print("open time:" + str(open_camera_time -start)) 24 | 25 | while True: 26 | last_photo_time = time.time() 27 | picam2.capture_array("main") 28 | photo_time = time.time() 29 | print("picture {} take time: {}".format(i, photo_time - last_photo_time)) 30 | 31 | i += 1 32 | -------------------------------------------------------------------------------- /64mpSavePng.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import cv2 4 | import time 5 | from picamera2 import Picamera2, Preview 6 | 7 | picam2 = Picamera2() 8 | 9 | preview_config = picam2.create_preview_configuration(main={"size": (1920, 1080)}) 10 | config = picam2.create_still_configuration(main={"size": (9152, 6944), "format": "RGB888"}, buffer_count=1) 11 | 12 | picam2.configure(preview_config) 13 | picam2.start_preview(Preview.QTGL) 14 | 15 | picam2.start() 16 | time.sleep(1) 17 | picam2.stop() 18 | 19 | picam2.configure(config) 20 | picam2.start() 21 | time.sleep(5) 22 | RGB888 = picam2.capture_array("main") 23 | cv2.imwrite("test.png", RGB888) 24 | -------------------------------------------------------------------------------- /AutofocusControl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import time 4 | 5 | from picamera2 import Picamera2, Preview 6 | 7 | picam2 = Picamera2() 8 | picam2.start_preview(Preview.QTGL) 9 | 10 | preview_config = picam2.create_preview_configuration() 11 | picam2.configure(preview_config) 12 | 13 | picam2.start() 14 | time.sleep(1) 15 | 16 | # If your libcamera-dev version is lower than 0.0.10, please use the following code. 17 | # picam2.set_controls({"AfTrigger": 0}) 18 | # If your libcamera-dev version is greater than or equal to 0.0.10, please use the following code. 19 | # AfMode Set the AF mode (manual, auto, continuous) 20 | picam2.set_controls({"AfMode": 1 ,"AfTrigger": 0}) 21 | 22 | time.sleep(5) 23 | -------------------------------------------------------------------------------- /CaptureExternalTrigger.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | from datetime import datetime 3 | import subprocess 4 | import signal 5 | import os 6 | import queue 7 | import RPi.GPIO as GPIO 8 | import time 9 | import threading 10 | from picamera2 import Picamera2, Preview 11 | 12 | # Flag for stopping threads 13 | stop_threads = False 14 | 15 | # Command for opening and closing trigger mode 16 | open_trigger_mode = "v4l2-ctl -d /dev/v4l-subdev0 -c trigger_mode=1" 17 | close_trigger_mode = "v4l2-ctl -d /dev/v4l-subdev0 -c trigger_mode=0" 18 | # Queue for storing captured images 19 | image_queue = queue.Queue(maxsize=100) 20 | 21 | Semaphore = threading.Semaphore(1) 22 | 23 | # Lock for thread synchronization 24 | lock = threading.Lock() 25 | 26 | # Function for handling keyboard interrupt signal 27 | def signal_handler(sig, frame): 28 | global stop_threads 29 | stop_threads = True 30 | os._exit(0) 31 | 32 | # Register the signal handler 33 | signal.signal(signal.SIGINT, signal_handler) 34 | 35 | # Function for running a command in the shell 36 | def run_cmd(cmd): 37 | print(f'{cmd}') 38 | try: 39 | subprocess.run(cmd, universal_newlines=True, check=False, shell=True, 40 | stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 41 | except RuntimeError as e: 42 | print(f'Error: {e}') 43 | except: 44 | print("Set up error!") 45 | 46 | # Close the trigger mode before starting the program 47 | run_cmd(close_trigger_mode) 48 | 49 | # Class for controlling GPIO pins 50 | class GPIOModule(): 51 | def __init__(self): 52 | self.ledPin = 3 53 | GPIO.setmode(GPIO.BCM) 54 | GPIO.setup(self.ledPin, GPIO.OUT) 55 | self.index_flag = True 56 | global stop_threads 57 | 58 | def run(self): 59 | # Wait for 3 seconds before starting the trigger 60 | time.sleep(3) 61 | print("Start Trigger! Press CTRL+C to exit") 62 | while True: 63 | time.sleep(0.2) 64 | try: 65 | val = input("enter your trig num: ") 66 | index = int(val) 67 | self.index_flag = True 68 | except: 69 | self.index_flag = False 70 | 71 | if self.index_flag: 72 | while index: 73 | index-=1 74 | GPIO.output(self.ledPin, GPIO.HIGH) 75 | time.sleep(0.001) 76 | GPIO.output(self.ledPin, GPIO.LOW) 77 | time.sleep(0.030) 78 | time.sleep(0.1) 79 | 80 | # Class for controlling the camera 81 | class CameraModule(): 82 | 83 | def run(self): 84 | # Initialize the Picamera2 object 85 | picam2 = Picamera2() 86 | # Disable preview to save resources 87 | picam2.start_preview(Preview.NULL) 88 | # Create a still configuration and configure the camera 89 | capture_config = picam2.create_still_configuration() 90 | picam2.configure(capture_config) 91 | # Start the camera 92 | picam2.start() 93 | 94 | # Wait for 2 seconds before opening the trigger mode 95 | time.sleep(2) 96 | run_cmd(open_trigger_mode) 97 | time.sleep(1) 98 | 99 | # Keep capturing images and add them to the queue 100 | while True: 101 | image = None 102 | try: 103 | image = picam2.capture_array("main") 104 | if image is not None: 105 | image_queue.put(image) 106 | print("Add image to queue.") 107 | Semaphore.release() 108 | except Exception as e: 109 | print(e) 110 | 111 | class myThread(threading.Thread): 112 | def __init__(self, threadID, name): 113 | threading.Thread.__init__(self) 114 | self.threadID = threadID 115 | self.name = name 116 | self.camera_module = CameraModule() 117 | self.gpio_module = GPIOModule() 118 | 119 | def run(self): 120 | if self.threadID == 1: 121 | self.camera_module.run() 122 | if self.threadID == 2: 123 | self.gpio_module.run() 124 | 125 | # Thread for saving images 126 | class SaveImageThread(threading.Thread): 127 | def __init__(self): 128 | threading.Thread.__init__(self) 129 | 130 | def run(self): 131 | while not stop_threads: 132 | Semaphore.acquire() 133 | if not image_queue.empty(): 134 | image = image_queue.get() 135 | cv2.imwrite("{}.jpg".format(datetime.now()), cv2.cvtColor(image, cv2.COLOR_RGB2BGR)) 136 | 137 | if __name__ == '__main__': 138 | # Create and start the threads 139 | thread1 = SaveImageThread() 140 | thread1.start() 141 | thread2 = myThread(1, "Thread-Camera") 142 | thread3 = myThread(2, "Thread-GPIO") 143 | thread2.start() 144 | thread3.start() 145 | # Wait for the threads to complete 146 | thread2.join() 147 | thread3.join() 148 | -------------------------------------------------------------------------------- /CaptureMultiCameraAdapterModule.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | from picamera2 import Picamera2, Preview 4 | import time 5 | 6 | for i in range(4): 7 | """ 8 | Only one camera can be turned on at a time, and four cameras cannot be turned on at the same time. 9 | If you need to switch cameras, you need to close the last opened camera first 'picam2.close()'. 10 | """ 11 | picam2 = Picamera2(camera_num=i) 12 | 13 | capture_config = picam2.create_still_configuration(main={"format": 'RGB888', "size": (1920, 1080)}) 14 | picam2.configure(capture_config) 15 | 16 | picam2.start() 17 | RGB888 = picam2.capture_array("main") 18 | picam2.switch_mode_and_capture_file(capture_config, "camera_{}.jpg".format(i)) 19 | picam2.stop() 20 | picam2.close() 21 | print("Camera {} save picture success".format(i)) 22 | -------------------------------------------------------------------------------- /CaptureOpencvExample.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import cv2 4 | 5 | from picamera2 import Picamera2 6 | 7 | cv2.startWindowThread() 8 | 9 | picam2 = Picamera2() 10 | picam2.configure(picam2.create_preview_configuration(main={"format": 'RGB888', "size": (640, 480)})) 11 | picam2.start() 12 | 13 | while True: 14 | im = picam2.capture_array() 15 | cv2.imshow("Camera", im) 16 | cv2.waitKey(1) 17 | 18 | cv2.destroyAllWindows() 19 | -------------------------------------------------------------------------------- /HatSwitchCameraTakePicture.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import cv2 4 | import sys 5 | import argparse 6 | from picamera2 import Picamera2 7 | import subprocess 8 | import time 9 | 10 | def run_cmd(cmd): 11 | print(f'{cmd}') 12 | try: 13 | subprocess.run(cmd, universal_newlines=True, check=False, shell=True, 14 | stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 15 | except RuntimeError as e: 16 | print(f'Error: {e}') 17 | except: 18 | print("Set up error!") 19 | 20 | argv = sys.argv[:] 21 | parser = argparse.ArgumentParser() 22 | parser.add_argument( 23 | "--choose", 24 | # action='store_true', 25 | nargs = "+", 26 | help="Select camera" 27 | ) 28 | args = parser.parse_args() 29 | 30 | 31 | picam2 = Picamera2() 32 | picam2.configure(picam2.create_preview_configuration(main={"format": 'RGB888', "size": (640, 480)})) 33 | picam2.start() 34 | 35 | # while True: 36 | im = picam2.capture_array() 37 | index = 0 38 | 39 | if args.choose: 40 | for i in range(len(args.choose)): 41 | # print(args.choose) 42 | if args.choose[i] == 'a': 43 | # picam2.stop() 44 | run_cmd("i2cset -y 10 0x24 0x24 0x02") 45 | time.sleep(0.5) 46 | im = picam2.capture_array() 47 | cv2.imwrite("camera_a_picture_{}.jpg".format(index), im) 48 | print("Camera A save picture success.") 49 | index += 1 50 | 51 | if args.choose[i] == 'b': 52 | run_cmd("i2cset -y 10 0x24 0x24 0x12") 53 | time.sleep(0.5) 54 | im = picam2.capture_array() 55 | cv2.imwrite("camera_b_picture_{}.jpg".format(index), im) 56 | print("Camera B save picture success.") 57 | index += 1 58 | 59 | if args.choose[i] == 'c': 60 | run_cmd("i2cset -y 10 0x24 0x24 0x22") 61 | time.sleep(0.5) 62 | im = picam2.capture_array() 63 | cv2.imwrite("camera_c_picture_{}.jpg".format(index), im) 64 | print("Camera C save picture success.") 65 | index += 1 66 | 67 | if args.choose[i] == 'd': 68 | run_cmd("i2cset -y 10 0x24 0x24 0x32") 69 | time.sleep(0.5) 70 | im = picam2.capture_array() 71 | cv2.imwrite("camera_d_picture_{}.jpg".format(index), im) 72 | print("Camera D save picture success.") 73 | index += 1 74 | 75 | print("The image is saved successfully and the program ends.") 76 | -------------------------------------------------------------------------------- /ManualfocusControl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | # To run this example, update libcamera-dev to version 0.0.12. 4 | 5 | import time 6 | 7 | from picamera2 import Picamera2, Preview 8 | 9 | picam2 = Picamera2() 10 | picam2.start_preview(Preview.QTGL) 11 | 12 | preview_config = picam2.create_preview_configuration() 13 | picam2.configure(preview_config) 14 | 15 | picam2.start() 16 | time.sleep(1) 17 | 18 | # AfMode: Set the AF mode (manual, auto, continuous) 19 | # LensPosition: Manual focus, Set the lens position. 20 | picam2.set_controls({"AfMode": 0, "LensPosition": 1}) 21 | time.sleep(5) 22 | picam2.set_controls({"AfMode": 0, "LensPosition": 5}) 23 | time.sleep(5) 24 | -------------------------------------------------------------------------------- /PrintAllCameraControl.py: -------------------------------------------------------------------------------- 1 | from picamera2 import Picamera2 2 | 3 | picam2 = Picamera2() 4 | controls = picam2.camera_controls 5 | print(controls) 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Picamera2_example 2 | Some picamera2 use cases 3 | 4 | The official picamera2 examples are not comprehensive, and all additional examples are based on the arducam camera. 5 | 6 | If you want to use it, please install the relevant dependencies according to the link below:
7 | https://www.arducam.com/docs/cameras-for-raspberry-pi/picamera2-with-arducam-v1-v2-hq-16mp-af-64mp-af-pivariety-cameras-guide/ 8 | 9 | ``` 10 | wget -O install_pivariety_pkgs.sh https://github.com/ArduCAM/Arducam-Pivariety-V4L2-Driver/releases/download/install_script/install_pivariety_pkgs.sh 11 | chmod +x install_pivariety_pkgs.sh 12 | ./install_pivariety_pkgs.sh -p libcamera_dev 13 | ./install_pivariety_pkgs.sh -p libcamera_apps 14 | sudo apt install -y python3-kms++ 15 | sudo apt install -y python3-pyqt5 16 | sudo apt install -y python3-prctl 17 | sudo apt install -y libatlas-base-dev 18 | sudo apt install -y ffmpeg 19 | sudo apt install -y python3-pip 20 | sudo pip3 install numpy --upgrade 21 | ``` 22 | -------------------------------------------------------------------------------- /SetExposureTime.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | from picamera2 import Picamera2, Preview 4 | 5 | EXPOURSE_TIME = 20000 6 | i = 1 7 | 8 | picam2 = Picamera2() 9 | # picam2.start_preview(Preview.QTGL) 10 | 11 | capture_config = picam2.create_still_configuration(main={"format": 'RGB888', "size": (1920, 1080)}) 12 | picam2.configure(capture_config) 13 | 14 | 15 | picam2.set_controls({"ExposureTime": EXPOURSE_TIME, "AnalogueGain": 1.0}) 16 | picam2.start() 17 | RGB888 = picam2.capture_array("main") 18 | print("Start save ldr_{:02d}.jpg".format(i)) 19 | picam2.switch_mode_and_capture_file(capture_config, "ldr_{:02d}.jpg".format(i)) 20 | picam2.stop() 21 | print("Save ldr_{:02d}.jpg success".format(i)) 22 | -------------------------------------------------------------------------------- /SetFrameRate.py: -------------------------------------------------------------------------------- 1 | import time 2 | from picamera2 import Picamera2, Preview 3 | 4 | picam2 = Picamera2() 5 | preview_config = picam2.create_preview_configuration(main={"size": (1920, 1080)}) 6 | picam2.configure(preview_config) 7 | 8 | picam2.start_preview(Preview.QTGL) 9 | 10 | FRAME_RATE = 37 11 | FRAME_RATE = 1000000 // FRAME_RATE 12 | 13 | picam2.start() 14 | picam2.set_controls({"FrameDurationLimits":(FRAME_RATE,FRAME_RATE)}) 15 | 16 | print(picam2.controls) 17 | time.sleep(20) 18 | -------------------------------------------------------------------------------- /SetTriggerMode.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import time 4 | import subprocess 5 | from picamera2 import Picamera2, Preview 6 | 7 | def run_cmd(cmd): 8 | """ 9 | Method for running the command line. 10 | """ 11 | print(f'{cmd}') 12 | try: 13 | result = subprocess.run(cmd, universal_newlines=True, check=False, shell=True, 14 | stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 15 | print(result.stdout) 16 | print("Set up successfully.") 17 | except RuntimeError as error: 18 | print(f'Error: {error}') 19 | else: 20 | print("Set up error!") 21 | 22 | SET_TRIGGRT_MODE = "v4l2-ctl -d /dev/v4l-subdev0 -c trigger_mode=0" 23 | run_cmd(SET_TRIGGRT_MODE) 24 | 25 | 26 | picam2 = Picamera2() 27 | picam2.start_preview(Preview.QTGL) 28 | 29 | preview_config = picam2.create_preview_configuration() 30 | picam2.configure(preview_config) 31 | picam2.start() 32 | time.sleep(5) 33 | -------------------------------------------------------------------------------- /ThreadRecordedVideo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # Live preview, enter `r` in the terminal to start recording video 3 | import time 4 | import threading 5 | 6 | from picamera2 import Picamera2 7 | from picamera2.encoders import H264Encoder 8 | from picamera2.outputs import FfmpegOutput 9 | from picamera2 import Picamera2, Preview 10 | 11 | 12 | 13 | picam2 = Picamera2() 14 | 15 | class myThread (threading.Thread): 16 | 17 | def __init__(self, threadID, name, delay): 18 | threading.Thread.__init__(self) 19 | self.threadID = threadID 20 | self.name = name 21 | self.delay = delay 22 | def run(self): 23 | if self.threadID == 1: 24 | self.preview() 25 | print(1) 26 | elif self.threadID == 2: 27 | self.keyboard_() 28 | def preview(self): 29 | global picam2 30 | picam2.start_preview(Preview.QTGL) 31 | preview_config = picam2.create_preview_configuration() 32 | picam2.configure(preview_config) 33 | picam2.start() 34 | def keyboard_(self): 35 | global picam2 36 | encoder = H264Encoder(10000000) 37 | output = FfmpegOutput('test.mp4', audio=True) 38 | r = input() 39 | if r == 'r': 40 | print(1) 41 | picam2.stop() 42 | video_config = picam2.create_video_configuration() 43 | picam2.configure(video_config) 44 | picam2.start_recording(encoder, output) 45 | time.sleep(10) 46 | picam2.stop_recording() 47 | 48 | thread1 = myThread(1, "Thread-1", 1) 49 | thread2 = myThread(2, "Thread-2", 2) 50 | 51 | thread1.start() 52 | thread2.start() 53 | thread1.join() 54 | thread2.join() 55 | -------------------------------------------------------------------------------- /imx708CaptureJpeg.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | import time 3 | 4 | from picamera2 import Picamera2, Preview 5 | 6 | # Here we load up the tuning for the HQ cam and alter the default exposure profile. 7 | # For more information on what can be changed, see chapter 5 in 8 | # https://datasheets.raspberrypi.com/camera/raspberry-pi-camera-guide.pdf 9 | 10 | tuning = Picamera2.load_tuning_file("imx708-b0311.json", "/opt/arducam") 11 | 12 | picam2 = Picamera2(tuning=tuning) 13 | picam2.configure(picam2.create_preview_configuration()) 14 | picam2.start_preview(Preview.QTGL) 15 | picam2.start() 16 | time.sleep(10) -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | opencv_python==4.6.0.66 2 | --------------------------------------------------------------------------------