85 lines
2.9 KiB
Plaintext
85 lines
2.9 KiB
Plaintext
def get_sensor_size_from_camera():
|
||
"""从相机API获取传感器尺寸"""
|
||
try:
|
||
import v4l2
|
||
import fcntl
|
||
|
||
# 打开相机设备
|
||
fd = open('/dev/video0', 'rb')
|
||
|
||
# 获取相机信息
|
||
cp = v4l2.v4l2_capability()
|
||
fcntl.ioctl(fd, v4l2.VIDIOC_QUERYCAP, cp)
|
||
|
||
# 获取相机格式
|
||
fmt = v4l2.v4l2_format()
|
||
fmt.type = v4l2.V4L2_BUF_TYPE_VIDEO_CAPTURE
|
||
fcntl.ioctl(fd, v4l2.VIDIOC_G_FMT, fmt)
|
||
|
||
# 获取传感器信息
|
||
sensor_info = v4l2.v4l2_sensor_info()
|
||
fcntl.ioctl(fd, v4l2.VIDIOC_G_SENSOR_INFO, sensor_info)
|
||
|
||
return {
|
||
'width_mm': sensor_info.physical_width / 1000, # 转换为mm
|
||
'height_mm': sensor_info.physical_height / 1000
|
||
}
|
||
except Exception as e:
|
||
print(f"无法从相机API获取传感器尺寸: {e}")
|
||
return None
|
||
|
||
def calibrate_sensor_size(real_object_size_mm, object_distance_mm):
|
||
"""通过已知物体标定传感器尺寸"""
|
||
def capture_calibration_image():
|
||
# 捕获标定图像
|
||
cap = cv2.VideoCapture(0)
|
||
ret, frame = cap.read()
|
||
cap.release()
|
||
return frame
|
||
|
||
def measure_object_pixels(frame):
|
||
# 测量物体在图像中的像素尺寸
|
||
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
|
||
edges = cv2.Canny(gray, 50, 150)
|
||
contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
||
|
||
if contours:
|
||
largest_contour = max(contours, key=cv2.contourArea)
|
||
x, y, w, h = cv2.boundingRect(largest_contour)
|
||
return h # 返回物体高度(像素)
|
||
return None
|
||
|
||
# 捕获标定图像
|
||
frame = capture_calibration_image()
|
||
if frame is None:
|
||
return None
|
||
|
||
# 测量物体像素尺寸
|
||
object_pixels = measure_object_pixels(frame)
|
||
if object_pixels is None:
|
||
return None
|
||
|
||
# 使用相似三角形原理计算传感器尺寸
|
||
frame_height = frame.shape[0] # 图像高度(像素)
|
||
focal_length_mm = 35 # 假设焦距为35mm,需要根据实际相机参数调整
|
||
|
||
sensor_height_mm = (real_object_size_mm * focal_length_mm) / (object_distance_mm * object_pixels / frame_height)
|
||
|
||
return sensor_height_mm
|
||
|
||
SENSOR_SIZES = {
|
||
'1/4"': {'width_mm': 3.2, 'height_mm': 2.4},
|
||
'1/3"': {'width_mm': 4.8, 'height_mm': 3.6},
|
||
'1/2.3"': {'width_mm': 6.17, 'height_mm': 4.55},
|
||
'1/1.8"': {'width_mm': 7.18, 'height_mm': 5.32},
|
||
'2/3"': {'width_mm': 8.8, 'height_mm': 6.6},
|
||
'1"': {'width_mm': 13.2, 'height_mm': 8.8},
|
||
'4/3"': {'width_mm': 17.3, 'height_mm': 13},
|
||
'APS-C': {'width_mm': 23.6, 'height_mm': 15.6},
|
||
'Full Frame': {'width_mm': 36, 'height_mm': 24}
|
||
}
|
||
|
||
def get_sensor_size(sensor_format):
|
||
"""根据传感器格式获取尺寸"""
|
||
return SENSOR_SIZES.get(sensor_format, None)
|