我目前正在使用 12 兆像素的 Raspberry Pi Camera V3 进行 DIY 书籍扫描仪项目。我尝试过使用 libcamera 和 picamera2 来捕获图像,但遇到性能问题。每张图像的捕获过程需要超过 6 秒,这对于我的应用来说并不理想。
是否有人在树莓派上使用相机来捕获图像但不从视频帧中捕获? 我需要 12 mp,因为我需要书页图像中尽可能多的细节。
我认为当我使用代码时,相机在树莓派中打开和关闭,但我没有找到让它保持打开状态的东西。好吧,可能是主题,但智能手机上的相同传感器可以在不到一秒的时间内以相同的分辨率捕获。
import subprocess
import os
import re
import time
import RPi.GPIO as GPIO
output_folder = "your_output_folder" # Replace with your desired output folder
base_filename = "image"
file_extension = "jpg"
gpio_pin = 18 # GPIO pin to use
if not os.path.exists(output_folder):
os.makedirs(output_folder)
# Find the last image file in the folder
existing_files = [f for f in os.listdir(output_folder) if f.endswith(f".{file_extension}")]
if existing_files:
last_file = max(existing_files, key=lambda x: int(re.search(r'\d+', x).group()))
last_number = int(re.search(r'\d+', last_file).group())
else:
last_number = 0
GPIO.setmode(GPIO.BCM)
GPIO.setup(gpio_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
while True:
GPIO.wait_for_edge(gpio_pin, GPIO.FALLING)
# Record the start time
start_time = time.time()
# Increment the counter
last_number += 1
# Generate the output filename
output_filename = f"{base_filename}{last_number:04d}.{file_extension}"
output_path = os.path.join(output_folder, output_filename)
# Run the libcamera-jpeg command
command = ["libcamera-jpeg", "-n", "-o", output_path]
subprocess.run(command)
# Calculate and print the elapsed time with 1 decimal place
end_time = time.time()
elapsed_time = round(end_time - start_time, 1)
print(f"Image captured: {output_filename}, Elapsed Time: {elapsed_time} seconds")
结果
User
[0:24:08.427953396] [2517] INFO Camera camera_manager.cpp:284 libcamera v0.1.0+118-563cd78e
[0:24:08.581691708] [2523] WARN RPiSdn sdn.cpp:39 Using legacy SDN tuning - please consider moving SDN inside rpi.denoise
[0:24:08.588225484] [2523] INFO RPI vc4.cpp:444 Registered camera /base/soc/i2c0mux/i2c@1/imx708@1a to Unicam device /dev/media3 and ISP device /dev/media0
[0:24:08.588380899] [2523] INFO RPI pipeline_base.cpp:1142 Using configuration file '/usr/share/libcamera/pipeline/rpi/vc4/rpi_apps.yaml'
Mode selection for 2304:1296:12:P
SRGGB10_CSI2P,1536x864/0 - Score: 3400
SRGGB10_CSI2P,2304x1296/0 - Score: 1000
SRGGB10_CSI2P,4608x2592/0 - Score: 1900
Stream configuration adjusted
[0:24:08.591796900] [2517] INFO Camera camera.cpp:1183 configuring streams: (0) 2304x1296-YUV420 (1) 2304x1296-SBGGR10_CSI2P
[0:24:08.592701680] [2523] INFO RPI vc4.cpp:608 Sensor: /base/soc/i2c0mux/i2c@1/imx708@1a - Selected sensor format: 2304x1296-SBGGR10_1X10 - Selected unicam format: 2304x1296-pBAA
Mode selection for 4608:2592:12:P
SRGGB10_CSI2P,1536x864/0 - Score: 10600
SRGGB10_CSI2P,2304x1296/0 - Score: 8200
SRGGB10_CSI2P,4608x2592/0 - Score: 1000
[0:24:13.816165872] [2517] INFO Camera camera.cpp:1183 configuring streams: (0) 4608x2592-YUV420 (1) 4608x2592-SBGGR10_CSI2P
[0:24:13.824487022] [2523] INFO RPI vc4.cpp:608 Sensor: /base/soc/i2c0mux/i2c@1/imx708@1a - Selected sensor format: 4608x2592-SBGGR10_1X10 - Selected unicam format: 4608x2592-pBAA
Still capture image received
Image captured: image0040.jpg, Elapsed Time: 9.4 seconds
这是针对树莓派5的 使用一台相机 v3
import keyboard
from picamera2 import Picamera2, Preview
import time
from datetime import datetime
from datetime import datetime
from libcamera import controls
import os
picam2 = Picamera2() # if u have one camera it will try to check it
#if u have alrerd two connected and wanna use only one use Picamera2(1) or Picamera2(1)
config = picam2.create_still_configuration(buffer_count=3)
picam2.configure(config)
picam2.start_preview(Preview.QTGL)
preview_config = picam2.create_preview_configuration({"size": (4096, 2592)})
picam2.configure(preview_config)
picam2.start()
picam2.set_controls({"AfMode": controls.AfModeEnum.Continuous })
try:
while True:
# Wait for the space key to be pressed
keyboard.wait("space")
# Record the start time
start_time = time.time()
# Capture an image
timeStamp = datetime.now().strftime("%Y%m%d-%H%M%S.%f")[:-4]
filename = f"z_img_{timeStamp}.jpg"
request = picam2.capture_request(flush=False )
request.save('main', filename)
request.release()
# Get the size of the captured image in bytes
file_size_bytes = os.path.getsize(filename)
# Convert the file size to megabytes
file_size_mb = file_size_bytes / (1024 ** 2)
# Record the end time
end_time = time.time()
# Calculate and print the time taken and the size of the image in megabytes
capture_time = end_time - start_time
print(f"Image captured: {filename}, Time taken: {capture_time:.2f} seconds, Size: {file_size_mb:.2f} MB")
except KeyboardInterrupt:
pass
finally:
# Clean up
picam2.stop_preview()
picam2.stop()
适用于两个摄像头 v3
import keyboard
from picamera2 import Picamera2, Preview
import time
from datetime import datetime
from libcamera import controls
import os
def capture_image(picam2, filename_prefix):
# Record the start time
start_time = time.time()
# Capture an image
timeStamp = datetime.now().strftime("%Y%m%d-%H%M%S.%f")[:-4]
filename = f"{filename_prefix}_img_{timeStamp}.jpg"
request = picam2.capture_request(flush=False)
request.save('main', filename)
request.release()
# Get the size of the captured image in bytes
file_size_bytes = os.path.getsize(filename)
# Convert the file size to megabytes
file_size_mb = file_size_bytes / (1024 ** 2)
# Record the end time
end_time = time.time()
# Calculate and print the time taken and the size of the image in megabytes
capture_time = end_time - start_time
print(f"Image captured: {filename}, Time taken: {capture_time:.2f} seconds, Size: {file_size_mb:.2f} MB")
# Set up the first camera
picam1 = Picamera2(1)
config1 = picam1.create_still_configuration(buffer_count=3)
picam1.configure(config1)
picam1.start_preview(Preview.QTGL)
preview_config1 = picam1.create_preview_configuration({"size": (4096, 2592)})
picam1.configure(preview_config1)
picam1.start()
picam1.set_controls({"AfMode": controls.AfModeEnum.Continuous})
# Set up the second camera
picam2 = Picamera2(0)
config2 = picam2.create_still_configuration(buffer_count=3)
picam2.configure(config2)
picam2.start_preview(Preview.QTGL)
preview_config2 = picam2.create_preview_configuration({"size": (4096, 2592)})
picam2.configure(preview_config2)
picam2.start()
picam2.set_controls({"AfMode": controls.AfModeEnum.Continuous})
try:
while True:
# Wait for the space key to be pressed
keyboard.wait("space")
# Capture images from both cameras
capture_image(picam1, "y")
capture_image(picam2, "x")
except KeyboardInterrupt:
pass
finally:
# Close QtGL preview windows
picam1.stop_preview()
picam2.stop_preview()
# Clean up both cameras
picam1.stop()
picam2.stop()
为了校准相机,我在使用我们制作的脚本之前使用 app_capture_overlay.py
如果你想要镜头与玻璃相对,你必须看到镜子上镜头的中间