Как включить восстановление «рыбий глаз» в кодировщик H264 picamera2?Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Как включить восстановление «рыбий глаз» в кодировщик H264 picamera2?

Сообщение Anonymous »

В настоящее время я работаю над проектом, который требует минимальной загрузки ЦП на rpi5 и широкого поля зрения. Мне нужно несколько выходов, как описано в одном из примеров. Чтобы уменьшить накладные расходы, я подумал, что могу объединить функцию кодирования кодера H264 с обратным преобразованием «рыбий глаз» из библиотеки cv2, применив класс-оболочку вокруг кодера H264, который перехватывает кадры перед кодированием и восстанавливает их перед передачей кодировщику. К сожалению, кадры, которые я могу перехватить, имеют формат, который я не совсем понимаю. Кроме того, я действительно не знаю, как вернуть неискаженные кадры обратно в конвейер.
На данный момент мой код дает сбой во время операции изменения формы, потому что размер кадра 540000, но я пытаюсь чтобы изменить форму массива с включенным шагом. Поэтому я распечатал формат кадра и формат конфигурации потока.

Форма кадра: (360, 500, 3), dtype: uint8, min: 0, max:255 .

Однако конфигурация потока имеет формат: RGB888, размер: (500, 360), шаг: 1536, размер кадра: 552960.

/>
На самом деле мне бы хотелось преобразовать кадр в формат, в котором я могу применить восстановление. Я также не знаю, как вернуть кадр в тот же формат, что и раньше, и передать его обратно в поток.
Были ли у кого-нибудь подобные проблемы или альтернативный подход к восстановлению искажения кадров во время используете picamera2? Заранее спасибо.
import os
import cv2
import numpy as np
from picamera2 import Picamera2
from picamera2.outputs import FfmpegOutput
from picamera2.encoders import H264Encoder
import time

class H264EncoderWithUndistortion(H264Encoder):
def __init__(self, map1, map2, *args, **kwargs):
"""
Initializes the encoder with undistortion and optional debugging.
:param map1: First undistortion map for cv2.remap.
:param map2: Second undistortion map for cv2.remap.
"""
super().__init__(*args, **kwargs)
self.map1 = map1
self.map2 = map2

def _undistort_frame(self, raw_frame):
"""
Applies undistortion to Bayer raw frames.
:param raw_frame: Raw Bayer frame as a numpy array.
:return: Undistorted Bayer frame as a numpy array.
"""
return cv2.remap(raw_frame, self.map1, self.map2, interpolation=cv2.INTER_LINEAR)

def _encode(self, stream, request):
# Access stream configuration
stream_config = picam2.stream_configuration(stream)
height, width = stream_config["size"]
stride = stream_config["stride"]

# Access the raw frame buffer
frame = request.make_array(stream)

#print frame properties
print(frame.size)
print(f"Frame shape: {frame.shape}, dtype: {frame.dtype}, min: {frame.min()}, max: {frame.max()}")
print(picam2.stream_configuration("main"))
# Handle stride
frame_with_stride = frame.reshape((height, stride)) # Include padding
valid_width = width * 3 # Actual bytes per row
frame = frame_with_stride[:, :valid_width].reshape((height, width, 3))

# Temporarily skip undistortion for debugging
undistorted_frame = self._undistort_frame(frame)

# Debug undistorted frame data
print(f"Undistorted frame min: {undistorted_frame.min()}, max: {undistorted_frame.max()}")

# Visualize the frames for debugging
cv2.imshow("Undistorted Frame", undistorted_frame)
if cv2.waitKey(1) == ord("q"):
print("Quit visualization")
cv2.imshow("Raw Frame", frame)
if cv2.waitKey(1) == ord("q"):
print("Quit visualization")

# Encode the undistorted frame
super()._encode(stream, request)

# Define the output folder and file path
output_folder = os.path.expanduser('~/Documents/recordings')
os.makedirs(output_folder, exist_ok=True)
output_file = f'{output_folder}/DEMO.mp4'

# Initialize the camera
picam2 = Picamera2()
video_config = picam2.create_video_configuration(
main={"size": (500, 360), "format": "RGB888"},
controls={"FrameRate": 30, "Saturation": 0.0}
)
picam2.configure(video_config)

# Load fisheye calibration data
K = np.array([
[247.490210, 0.365535, 252.210439],
[0.000000, 247.791476, 179.082768],
[0.000000, 0.000000, 1.000000]
])
D = np.array([
[-0.053639],
[0.119409],
[-0.234838],
[0.138188]
])
h, w = 360, 500
new_K = cv2.fisheye.estimateNewCameraMatrixForUndistortRectify(K, D, (w, h), None)
map1, map2 = cv2.fisheye.initUndistortRectifyMap(K, D, np.eye(3), new_K, (w, h), cv2.CV_16SC2)

# Create the custom encoder
encoder =H264EncoderWithUndistortion(map1, map2, bitrate=400000)

# Set up the output
output1 = FfmpegOutput(output_file)
encoder.output = [output1] #--> would define multiple outputs

# Start recording
picam2.start_encoder(encoder)
picam2.start()

time.sleep(10)

# Stop recording
picam2.stop_encoder()
picam2.stop()
cv2.destroyAllWindows()
print(f"Recording saved to {output_file}")


Подробнее здесь: https://stackoverflow.com/questions/792 ... -picamera2
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»