189 lines
9.2 KiB
Python
189 lines
9.2 KiB
Python
|
# Creation Date: 02.03.2022
|
||
|
# Author: Kenan Gömek
|
||
|
# This script takes pictures with Picameras VideoPort like it will be used to work with OpenCV and saves it with OpenCV to have the real use case pictures.
|
||
|
# This script is designed for shooting manually images with 'i'
|
||
|
# Press 'q' to exit
|
||
|
# Change camera parameters with v,b,n,m,x,c,o. See code for more information.
|
||
|
|
||
|
|
||
|
import cv2 as cv
|
||
|
import picamera
|
||
|
from picamera.array import PiRGBArray
|
||
|
from fractions import Fraction
|
||
|
|
||
|
import time
|
||
|
from datetime import datetime
|
||
|
import os
|
||
|
|
||
|
import numpy as np
|
||
|
import matplotlib.pyplot as plt
|
||
|
|
||
|
|
||
|
# Define camera settings
|
||
|
|
||
|
# divide origin resoluton by a number, to have the origin aspect ratio
|
||
|
# RESOLUTION = (3280, 2464) # Max Photo-Resolution CAM03 and CAM04 # no image with PiCamera Videoport at this Resolution.. Probably GPU Memory and CPU issues.
|
||
|
# RESOLUTION = (1640,1232) # 2nd best Resolution for CAM03 and CAM04 with FUll FOV (2x2 binning) # Mode 4
|
||
|
SENSOR_MODE = 4 # corresponding sensor mode to resolution 1640x1232
|
||
|
# OUTPUT_RESOLUTION = (960, 720)
|
||
|
OUTPUT_RESOLUTION = (416, 320)
|
||
|
#OUTPUT_RESOLUTION = (416, 320) # (1640x1232)/4=(410,308)
|
||
|
# (410,308) is being upscaled to (416,320) from ISP (warning in bash), but image will have still (410,308) pixels.
|
||
|
# OUTPUT_RESOLUTION = (820, 616) # (1640x1232)/2=(820,616)
|
||
|
# bash: frame size rounded up from 820x616 to 832x624
|
||
|
|
||
|
|
||
|
AWB_MODE = 'off' # Auto white balance mode
|
||
|
# AWB_GAINS = (Fraction(485, 256), Fraction(397, 256)) # White Balance Gains to have colours read correctly: (red, blue)
|
||
|
AWB_GAINS = (1.395, 1.15) # White Balance Gains to have colours read correctly: (red, blue). Int, float or fraction are valid.
|
||
|
BRIGHTNESS = 25 # sets the brightness setting of the camera. default is 50. [0-100]
|
||
|
# the brighter, the brighter the LEDs and the higher the RGB values and vice versa!
|
||
|
CONTRAST = 100 # sets the contrast setting of the camera. The default value is 0. [-100 ... 100]
|
||
|
|
||
|
# ISO = 100 # ISO value
|
||
|
ISO = 320 # ISO value
|
||
|
EXPOSURE_MODE = 'off'
|
||
|
FRAMERATE = 25 # frames per second. 40 fps is max for sensor mode 4
|
||
|
|
||
|
SLEEP_TIME = 2 # Time for sleep-mode for the camera in seconds. My default: 2 s
|
||
|
|
||
|
# Define Funcions
|
||
|
def take_image_picamera_opencv(shutter_speed):
|
||
|
folder_exists=False
|
||
|
# Initialise Camera
|
||
|
with picamera.PiCamera() as camera:
|
||
|
with PiRGBArray(camera) as output:
|
||
|
# Set camera settings
|
||
|
camera.sensor_mode = SENSOR_MODE # force camera into desired sensor mode
|
||
|
camera.resolution = OUTPUT_RESOLUTION # frame will be resized from GPU to this resolution. No CPU usage!
|
||
|
camera.framerate = FRAMERATE
|
||
|
|
||
|
camera.awb_mode = AWB_MODE
|
||
|
camera.awb_gains = AWB_GAINS
|
||
|
|
||
|
camera.iso = ISO
|
||
|
camera.shutter_speed = shutter_speed
|
||
|
# it was found that, you have to set the right shutter speed at the first initalisation of the current runtime of the program.
|
||
|
# The gains (analog, digital) will adjust to this set up.
|
||
|
# After the gains are fixed, they will never change! even if you change the shutter speed during the runtime.
|
||
|
# To get consistent brightness values, set the right shutter speed at initalisation once.
|
||
|
|
||
|
time.sleep(SLEEP_TIME) # wait for iso gains and digital_gain and analog_gain to settle before fixing the gains with exposure_mode = off
|
||
|
camera.exposure_mode = EXPOSURE_MODE
|
||
|
|
||
|
time.sleep(1) # wait before applying brightness and contrast
|
||
|
camera.brightness = BRIGHTNESS
|
||
|
camera.contrast = CONTRAST
|
||
|
time.sleep(SLEEP_TIME) # Camera warm-up time to apply settings
|
||
|
|
||
|
# camera.start_preview() # show camera preview through PiCamera interface
|
||
|
# camera.annotate_frame_num=True # Controls whether the current frame number is drawn as an annotation.
|
||
|
|
||
|
for frameidx, frame in enumerate(camera.capture_continuous(output, format='bgr', use_video_port=True)):
|
||
|
framenumber = frameidx+1 # frameidx starts with 0, framenumber with 1
|
||
|
image = frame.array # raw NumPy array without JPEG encoding
|
||
|
|
||
|
camera_exposure_speed = camera.exposure_speed # Retrieves the current shutter speed of the camera.
|
||
|
|
||
|
cv.imshow("Current Frame", image) # display the image without text
|
||
|
|
||
|
output.truncate(0) # clear the stream for next frame
|
||
|
|
||
|
# Only uncomment following code if you display the image. No errors if not commented, but higher fps if commented.
|
||
|
# if q is pressed, break from loop.
|
||
|
pressed_key = cv.waitKey(2) & 0xff
|
||
|
if pressed_key == ord('q'):
|
||
|
break
|
||
|
elif pressed_key == ord('i'): # Take image from manipulated image if i is pressed
|
||
|
if not folder_exists:
|
||
|
path_saveFolder, folder_exists = create_folder_for_captures()
|
||
|
|
||
|
now = datetime.now(); d1 = now.strftime("%Y-%m-%d %H-%M-%S.%f")[:-3]
|
||
|
cv.imwrite(f"{path_saveFolder}/img_ss{shutter_speed}_iso{ISO}_res{OUTPUT_RESOLUTION[0]}x{OUTPUT_RESOLUTION[1]}_Date {d1}.png", image)
|
||
|
print('took image!')
|
||
|
elif pressed_key == ord('v'): # increase shutterspeed by 5
|
||
|
shutter_speed = round(shutter_speed+5)
|
||
|
camera.shutter_speed = shutter_speed
|
||
|
time.sleep(2) # wait to shutter speed is applied before querying exposure speed
|
||
|
exposure_speed = camera.exposure_speed
|
||
|
print(f"shutter speed set to: {shutter_speed}")
|
||
|
print(f"retrieved shutter speed: {exposure_speed}")
|
||
|
elif pressed_key == ord('b'): # increase shutterspeed by 50
|
||
|
shutter_speed = round(shutter_speed+50)
|
||
|
camera.shutter_speed = shutter_speed
|
||
|
print(f"shutter speed set to: {shutter_speed}")
|
||
|
time.sleep(2) # wait to shutter speed is applied before querying exposure speed
|
||
|
exposure_speed = camera.exposure_speed
|
||
|
print(f"retrieved shutter speed: {exposure_speed}")
|
||
|
elif pressed_key == ord('n'): # increase shutterspeed by 500
|
||
|
shutter_speed = round(shutter_speed+500)
|
||
|
print(f"shutter speed set to: {shutter_speed}")
|
||
|
time.sleep(2) # wait to shutter speed is applied before querying exposure speed
|
||
|
exposure_speed = camera.exposure_speed
|
||
|
print(f"retrieved shutter speed: {exposure_speed}")
|
||
|
elif pressed_key == ord('m'): # max shutterspeed
|
||
|
shutter_speed = round(1/FRAMERATE*1e6)
|
||
|
camera.shutter_speed = shutter_speed
|
||
|
print(f"shutter speed set to: {shutter_speed}")
|
||
|
time.sleep(2) # wait to shutter speed is applied before querying exposure speed
|
||
|
exposure_speed = camera.exposure_speed
|
||
|
print(f"retrieved shutter speed: {exposure_speed}")
|
||
|
elif pressed_key == ord('x'): # decrease shutterspeed by 500
|
||
|
shutter_speed = round(shutter_speed-500)
|
||
|
camera.shutter_speed = shutter_speed
|
||
|
print(f"shutter speed set to: {shutter_speed}")
|
||
|
time.sleep(2) # wait to shutter speed is applied before querying exposure speed
|
||
|
exposure_speed = camera.exposure_speed
|
||
|
print(f"retrieved shutter speed: {exposure_speed}")
|
||
|
elif pressed_key == ord('c'): # decrease shutterspeed by 50
|
||
|
shutter_speed = round(shutter_speed-50)
|
||
|
camera.shutter_speed = shutter_speed
|
||
|
print(f"shutter speed set to: {shutter_speed}")
|
||
|
time.sleep(2) # wait to shutter speed is applied before querying exposure speed
|
||
|
exposure_speed = camera.exposure_speed
|
||
|
print(f"retrieved shutter speed: {exposure_speed}")
|
||
|
elif pressed_key == ord('o'): # set shutterspeed to 0
|
||
|
shutter_speed = 0
|
||
|
camera.shutter_speed = shutter_speed
|
||
|
print(f"shutter speed set to: {shutter_speed}")
|
||
|
time.sleep(2) # wait to shutter speed is applied before querying exposure speed
|
||
|
exposure_speed = camera.exposure_speed
|
||
|
print(f"retrieved shutter speed: {exposure_speed}")
|
||
|
|
||
|
|
||
|
def create_folder_for_captures():
|
||
|
# Create folder for saving the captured pictures
|
||
|
now = datetime.now(); d1 = now.strftime("%Y-%m-%d %H-%M")
|
||
|
path_cwd = os.getcwd()
|
||
|
|
||
|
path_saveFolder = path_cwd+r"/Capture_"+d1
|
||
|
try:
|
||
|
os.mkdir(path_saveFolder)
|
||
|
folder_exists = True
|
||
|
except OSError:
|
||
|
print("Error! Ending script.")
|
||
|
quit()
|
||
|
|
||
|
return path_saveFolder, folder_exists
|
||
|
|
||
|
|
||
|
# Start Script
|
||
|
|
||
|
# start capture series for different shutter speeds
|
||
|
print('start caputure...')
|
||
|
|
||
|
take_image_picamera_opencv(shutter_speed=50)
|
||
|
# take_image_picamera_opencv(shutter_speed=round(1/FRAMERATE*1e6)) # max shutter-speed depending on fps: 1/2 fps = 500 000 µs
|
||
|
|
||
|
# End Script
|
||
|
|
||
|
cv.destroyAllWindows()
|
||
|
|
||
|
print('Script finished')
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|