def rawObservation(self, filename, frame_rate=15, video_time=1, shutterSpeed=30000): # Analog and digital gain parameters (not exposed in picamera-1.13) MMAL_PARAMETER_ANALOG_GAIN = mmal.MMAL_PARAMETER_GROUP_CAMERA + 0x59 MMAL_PARAMETER_DIGITAL_GAIN = mmal.MMAL_PARAMETER_GROUP_CAMERA + 0x5A # Full resolution with PiCamera(resolution=(3280, 2464), framerate=frame_rate, sensor_mode=2, clock_mode='raw') as camera: # Set fixed white balance # (gain choices from absolute radiometric calibration by Pagnutti et al.) camera.awb_mode = 'off' camera.awb_gains = (Fraction(525, 325), Fraction(425, 325)) # Set fixed analog and digital gains # Max analog gain: Fraction(2521,256) # Note: will want minimum gain (1?) for Sun, maximum analog gain for Earth/Moon mmal.mmal_port_parameter_set_rational( camera._camera.control._port, MMAL_PARAMETER_ANALOG_GAIN, to_rational(Fraction(2521, 256))) mmal.mmal_port_parameter_set_rational(camera._camera.control._port, MMAL_PARAMETER_DIGITAL_GAIN, to_rational(1)) # Set shutter speed [us] # Note: will want minimum shutter speed (19us) for Sun, slower for Earth/Moon camera.shutter_speed = shutterSpeed # Wait for parameter changes to take effect, then lock gains # (locking gains may not be required) time.sleep(1) camera.exposure_mode = 'off' # t0 = time.monotonic() # Host time when recording is commanded camera.start_recording(filename, format='mjpeg') lastTimestamp = camera.timestamp lastIndex = -1 # Loop over expected frames for n in range(video_time * frame_rate): # {video_time} seconds f = camera.frame # If no new frame yet, sleep for half a frame while f is None or f.index == lastIndex or f.frame_type == PiVideoFrameType.sps_header: f = camera.frame time.sleep((1 / frame_rate) / 2) lastIndex = f.index lastTimestamp = f.timestamp camera.stop_recording() # Timestamp is in microseconds, relative to last system reboot (default clock_mode='raw') return (filename, lastTimestamp)
def set_gain(camera, analog=1, digital=1): MMAL_PARAMETER_ANALOG_GAIN = mmal.MMAL_PARAMETER_GROUP_CAMERA + 0x59 MMAL_PARAMETER_DIGITAL_GAIN = mmal.MMAL_PARAMETER_GROUP_CAMERA + 0x5A ret1 = mmal.mmal_port_parameter_set_rational(camera._camera.control._port, MMAL_PARAMETER_ANALOG_GAIN, to_rational(analog)) ret2 = mmal.mmal_port_parameter_set_rational(camera._camera.control._port, MMAL_PARAMETER_DIGITAL_GAIN, to_rational(digital)) if ret1 == 4 or ret2 == 4: raise exc.PiCameraMMALError(ret, "Are you running the latest version of the userland libraries?") elif ret1 != 0 or ret2 != 0: raise exc.PiCameraMMALError(ret)
def set_gain(camera, gain, value): """Set the analog gain of a PiCamera. camera: the picamera.PiCamera() instance you are configuring gain: either MMAL_PARAMETER_ANALOG_GAIN or MMAL_PARAMETER_DIGITAL_GAIN value: a numeric value that can be converted to a rational number. """ if gain not in [MMAL_PARAMETER_ANALOG_GAIN, MMAL_PARAMETER_DIGITAL_GAIN]: raise ValueError("The gain parameter was not valid") ret = mmal.mmal_port_parameter_set_rational(camera._camera.control._port, gain, to_rational(value)) if ret == 4: raise exc.PiCameraMMALError(ret, "Are you running the latest version of the userland libraries? Gain setting was introduced in late 2017.") elif ret != 0: raise exc.PiCameraMMALError(ret)
def set_gain(camera, gain, value): """Set the analog gain of a PiCamera. camera: the picamera.PiCamera() instance you are configuring gain: either MMAL_PARAMETER_ANALOG_GAIN or MMAL_PARAMETER_DIGITAL_GAIN value: a numeric value that can be converted to a rational number. """ if gain not in [MMAL_PARAMETER_ANALOG_GAIN, MMAL_PARAMETER_DIGITAL_GAIN]: raise ValueError("The gain parameter was not valid") ret = mmal.mmal_port_parameter_set_rational(camera._camera.control._port, gain, to_rational(value)) if ret == 4: raise exc.PiCameraMMALError( ret, "Are you running the latest version of the userland libraries? Gain setting was introduced in late 2017." ) elif ret != 0: raise exc.PiCameraMMALError(ret)
def set_gain(camera, gain, value): """Set the analog gain of a PiCamera. camera: the picamera.PiCamera() instance you are configuring gain: either MMAL_PARAMETER_ANALOG_GAIN or MMAL_PARAMETER_DIGITAL_GAIN value: a numeric value that can be converted to a rational number. """ # lazy loading so node does not complain from picamera import mmal, mmalobj, exc from picamera.mmalobj import to_rational # keys must match the _name attribute of the corresponding class SENSOR_GAINS = { "analog_gain": mmal.MMAL_PARAMETER_GROUP_CAMERA + 0x59, "digital_gain": mmal.MMAL_PARAMETER_GROUP_CAMERA + 0x5A } ## logging.info(f"Setting {gain} to {value}") if gain not in ["analog_gain", "digital_gain"]: raise ValueError("The gain parameter was not valid") gain_int = SENSOR_GAINS[gain] rational_value = to_rational(value) port = camera._camera.control._port logging.warning(gain_int) logging.warning(rational_value) logging.warning(port) ret = mmal.mmal_port_parameter_set_rational(port, gain_int, rational_value) # PLEASE NOTE # if queried now, it will still show the old value time.sleep(2) if ret == 4: raise exc.PiCameraMMALError( ret, "Are you running the latest version of the userland libraries? Gain setting was introduced in late 2017." ) elif ret != 0: raise exc.PiCameraMMALError(ret)
def camThread(stop_event, calibrate_event, out_q, en_q): signal.signal(signal.SIGINT, signal.SIG_IGN) # Load the cascade face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') if debug: print("\nLoaded cascade") #Sets up the camera with PiCamera() as camera: camera.resolution = (640, 480) camera.framerate = 5 camera.exposure_mode = 'night' #Sets digital gain to 8.0 mmal.mmal_port_parameter_set_rational( camera._camera.control._port, mmal.MMAL_PARAMETER_GROUP_CAMERA + 0x5A, to_rational(8.0)) rawCapture = PiRGBArray(camera, size=(640, 480)) width = camera.resolution[0] time_stamp_old = time.perf_counter() calibrate_event.wait() #Waits for the motor to finnish calibrating for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True): #print(f"target fps: {camera.framerate}, dg: {camera.digital_gain}, exposure: {camera.exposure_mode}") # Read the frame img = frame.array # Convert to grayscale gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Detect the faces faces = face_cascade.detectMultiScale(gray, 1.1, 4) # Draw the rectangle around each face and detects decides if it wants to go left or right enable = False for (x, y, w, h) in faces: enable = True if args.show: cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2) center = (x + w / 2, y + h / 2) if center[0] <= width / 2: if debug: print("Left half of image") out_q.put(GPIO.HIGH) else: if debug: print("Right half of image") out_q.put(GPIO.LOW) en_q.put(enable) # Display if args.show: cv2.imshow('img', img) # Stop if escape key is pressed k = cv2.waitKey(30) & 0xff if k == 27: break # clear the stream in preparation for the next frame rawCapture.truncate(0) rawCapture.seek(0) #Calculates and prints the FPS to std out if args.fps: time_stamp_new = time.perf_counter() fps = 1 / (time_stamp_new - time_stamp_old) sys.stdout.write("\rFPS: {0} ".format(round(fps, 1))) sys.stdout.flush() time_stamp_old = time_stamp_new #shuts the thread off if stop_event.is_set(): break