picamera2选取某些区域对焦
必须知道的参数
ScalerCropMaximum
scaler_crop_maximum = picam2.camera_properties['ScalerCropMaximum']
设定的参数不同,比如你想要的展示图片的大小;camera会自动选择【参考的图像画幅区域:我们这里叫激活区域吧】,获取这个区域后,进行缩放裁剪展示给你 所需要的大小。
比如某摄像头全分辨率是4608 x 2592,你先预览一个实时窗口,大小为1080x720
展示·
关注properties:(768,432,3072,1728)
意思应该是,取得全画幅4608 x 2592中,以(768,432)为左上点,以(3072,1728)为宽高的区域,
然后进行缩放为1080x720
AfMetering
通过ROI区域对焦
picam2.controls.set_controls( { "AfMetering" : controls.AfMeteringEnum.Windows} )
AfWindows
以ScalerCropMaximum的图像为坐标系进行操作,找到窗口,进行对焦。
picam2.set_controls({"AfWindows": [adjustedcoord]})
总结
先获取ScalerCropMaximum,得到激活区域。
[如果需要选择对焦窗口,在这里以ScalerCropMaximum为坐标系进行操作]
然后进行scaler缩放到你需要的尺寸,
然后展示display
课外参考
https://github.com/raspberrypi/picamera2/issues/915
import time
sys.path.append('/usr/lib/python3/dist-packages/')
from picamera2 import Picamera2, Preview, MappedArray
from libcamera import controls
picam2 = Picamera2()
import cv2
import numpy as np
# Set display size and create variables for later
lores = (1280, 800)
width, height = lores
# start cam
picam2.start_preview(Preview.DRM, x=100, y=100, width=1280, height=800)
preview_config = picam2.create_preview_configuration(main={"size": lores})
picam2.configure(preview_config)
picam2.start()
# print properties - including scalar crop max
properties = picam2.camera_properties
print(properties)
# print metadata
metadata = picam2.capture_metadata()
print(metadata)
# set afmetering to windows so it can be called
picam2.controls.set_controls( { "AfMetering" : controls.AfMeteringEnum.Windows} )
# turn scalercropmax into a variable
scaler_crop_maximum = picam2.camera_properties['ScalerCropMaximum']
# set some example ROI
coord1 = (0,0, width // 2, height)
coord2 = (width // 2, height // 4, width // 2, height // 2)
coord3 = (0, height // 4, width // 2, height // 2)
coord4 = (100, 100, width, height)
coord5 = (1000,100, 500, 200)
# function for printing variables consistently
def print_coordinates(coordinates, name):
print(name.upper())
print(f"x_offset = {coordinates[0]}")
print(f"y_offset = {coordinates[1]}")
print(f"width = {coordinates[2]}")
print(f"height = {coordinates[3]}")
# function to attempt to scale variables designed for preview into scalercropmax size for AfWindows
def AccountForScalerCrop(coord, scaler_crop_maximum, lores):
x_offset, y_offset, width, height = coord
print_coordinates(coord, "coord")
# scaler_crop_maximum represents a larger image than the image we use so we need to account
x_offset_scm, y_offset_scm, width_scm, height_scm = scaler_crop_maximum
print_coordinates(scaler_crop_maximum, "SCM")
# create a scale so that you can scale the preview to the SCM
yscale = int(scaler_crop_maximum[3]) / int(lores[1])
xscale = int(scaler_crop_maximum[2]) / int(lores[0])
print("yscale, xscale",yscale, xscale)
# scale coords to SCM
y_offset_scaled = int(y_offset * yscale)
height_scaled = int(height * yscale)
x_offset_scaled = int(x_offset * xscale)
width_scaled = int(width * xscale)
coordscaled = (x_offset_scaled, y_offset_scaled, width_scaled, height_scaled)
print_coordinates(coordscaled, "coordscaled")
adjustedcoord = (x_offset_scm + x_offset_scaled, y_offset_scm + y_offset_scaled, width_scaled, height_scaled)
print_coordinates(adjustedcoord, "adjustedcoord")
return adjustedcoord
# function to focus cam based on scaled coords and draw overlays for coords
def focusarea(coord, scaler_crop_maximum, lores):
adjustedcoord = AccountForScalerCrop(coord, scaler_crop_maximum, lores)
picam2.set_controls({"AfWindows": [adjustedcoord]})
print("focusing cam")
job = picam2.autofocus_cycle(wait=False)
# Now do some other things, and when you finally want to be sure the autofocus cycle is finished:
success = picam2.wait(job)
# query lens position after completion
LensPosition = picam2.capture_metadata().get("LensPosition")
print("LENS POSITION:", LensPosition)
x_offset, y_offset, width, height = coord
# create overlay the size of the preview
overlay = np.zeros((lores[1], lores[0], 4), dtype=np.uint8)
overlay[y_offset:height+y_offset,x_offset:width+x_offset] = (0, 255, 0, 64)
picam2.set_overlay(overlay)
time.sleep(5)
# create list of coordinates
coordinates = [coord1, coord2, coord3, coord4, coord5]
# loop through coordinates
for i, coord in enumerate(coordinates, start=1):
print(f">>>>>>>>FOCUSING COORD{i}")
focusarea(coord, scaler_crop_maximum, lores)
print("script finished")```