Кадры, снятые камерой ELP, имеют неизвестный формат пикселей в формате FHD?Python

Программы на Python
Ответить
Anonymous
 Кадры, снятые камерой ELP, имеют неизвестный формат пикселей в формате FHD?

Сообщение Anonymous »

Я пытаюсь сделать один кадр каждые x секунд с моей USB-камеры. Имя камеры: ELP-USBFHD06H-SFV(5-50).
Код еще не готов на 100%, но я сейчас использую его таким образом ↓ ( fn вызывается из main.py в цикле)

Код: Выделить всё

import cv2
import subprocess

from time import sleep
from collections import namedtuple

from errors import *

class Camera:
def __init__(self, cam_index, res_width, res_height, pic_format, day_time_exposure_ms, night_time_exposure_ms):
Resolution = namedtuple("resolution", ["width", "height"])
self.manual_mode(True)

self.cam_index = cam_index
self.camera_resolution = Resolution(res_width, res_height)
self.picture_format = pic_format
self.day_time_exposure_ms = day_time_exposure_ms
self.night_time_exposure_ms = night_time_exposure_ms

self.started: bool = False
self.night_mode = False

self.cap = cv2.VideoCapture(self.cam_index, cv2.CAP_V4L2)
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, self.camera_resolution.width)
self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, self.camera_resolution.height)
self.cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*self.picture_format))

def start(self):
sleep(1)
if not self.cap.isOpened():
return CameraCupError()

self.set_exposure_time(self.day_time_exposure_ms)
self.set_brightness(0)
sleep(0.1)

self.started = True

def shot(self, picture_name, is_night):
if not self.started:
return InitializationError()

self.configure_mode(is_night)

# Clear buffer
for _ in range(5):
ret, _ = self.cap.read()

ret, frame = self.cap.read()

sleep(0.1)

if ret:
print(picture_name)
cv2.imwrite(picture_name, frame)
return True

else:
print("No photo")
return False

def release(self):
self.set_exposure_time(156)
self.set_brightness(0)
self.manual_mode(False)
self.cap.release()

def manual_mode(self, switch: bool):
if switch:
subprocess.run(["v4l2-ctl", "--set-ctrl=auto_exposure=1"])
else:
subprocess.run(["v4l2-ctl", "--set-ctrl=auto_exposure=3"])
sleep(1)

def configure_mode(self, is_night):
if is_night == self.night_mode:
return

if is_night:
self.night_mode = is_night
self.set_exposure_time(self.night_time_exposure_ms)
self.set_brightness(64)
else:
self.night_mode = is_night
self.set_exposure_time(self.day_time_exposure_ms)
self.set_brightness(0)
sleep(0.1)

def set_exposure_time(self, ms: int):
ms = int(ms)
default_val = 156

if ms < 1 or ms > 5000:
ms = default_val

self.cap.set(cv2.CAP_PROP_EXPOSURE, ms)

def set_brightness(self, value: int):
value = int(value)
default_val = 0

if value < -64 or value > 64:
value = default_val

self.cap.set(cv2.CAP_PROP_BRIGHTNESS, value)
Вот настройки камеры (файл yaml)

Код: Выделить всё

camera:
camera_index: 0
res_width: 1920
res_height: 1080
picture_format: "MJPG"
day_time_exposure_ms: 5
night_time_exposure_ms: 5000
photos_format: "jpg"

Я делаю некоторые настройки, такие как установка ручного режима для камеры, изменение экспозиции/яркости и сохранение кадра.
Также камера, вероятно, захватывает кадры в буфер (это не так). сохранение последнего кадра в реальном времени: это медленнее), поэтому мне приходится каждый раз очищать буфер. вот так

Код: Выделить всё

        # Clear buffer from old frames
for _ in range(5):
ret, _ = self.cap.read()

# Get a new frame
ret, frame = self.cap.read()
Что мне очень не нравится, но я мог бы найти способ получше (tldr: настройка буфера на 1 кадр на моей камере не работает).
Кадры, сохраненные этим методом, хорошо выглядят при разрешении 1920x1080. НО, когда я пытаюсь запустить команду ffmpeg, чтобы сделать таймлапс из сохраненного файла jpg, вот так

Код: Выделить всё

ffmpeg -framerate 20 -pattern_type glob -i "*.jpg" -c:v libx264 output.mp4
Я получил такую ​​ошибку

Код: Выделить всё

[image2 @ 0x555609c45240] Could not open file : 08:59:20.jpg
[image2 @ 0x555609c45240] Could not find codec parameters for stream 0 (Video: mjpeg, none(bt470bg/unknown/unknown)): unspecified size
Consider increasing the value for the 'analyzeduration' (0) and 'probesize' (5000000) options
Input #0, image2, from '*.jpg':
Duration: 00:00:00.05, start: 0.000000, bitrate: N/A
Stream #0:0: Video: mjpeg, none(bt470bg/unknown/unknown), 20 fps, 20 tbr, 20 tbn
Output #0, mp4, to 'output.mp4':
Output file #0 does not contain any stream
Кроме того, когда я пытаюсь скопировать файлы из Linux в Windows, я получаю странную ошибку при копировании и возможность пропустить изображение. Но даже когда я нажимаю кнопку пропуска, картинка копируется и ее можно открыть. Не знаю, что не так с форматом, но камера поддерживает MPEG с разрешением 1920x1080.

Код: Выделить всё

>>>  v4l2-ctl --all

Driver Info:
Driver name      : uvcvideo
Card type        : H264 USB Camera: USB Camera
Bus info         : usb-xhci-hcd.1-1
Driver version   : 6.6.51
Capabilities     : 0x84a00001
Video Capture
Metadata Capture
Streaming
Extended Pix Format
Device Capabilities
Device Caps      : 0x04200001
Video Capture
Streaming
Extended Pix Format
Media Driver Info:
Driver name      : uvcvideo
Model            : H264 USB Camera: USB Camera
Serial           : 2020032801
Bus info         : usb-xhci-hcd.1-1
Media version    : 6.6.51
Hardware revision: 0x00000100 (256)
Driver version   : 6.6.51
Interface Info:
ID               : 0x03000002
Type             : V4L Video
Entity Info:
ID               : 0x00000001 (1)
Name             : H264 USB Camera: USB Camera
Function         : V4L2 I/O
Flags            : default
Pad 0x0100000d   : 0: Sink
Link 0x0200001a: from remote pad 0x1000010 of entity 'Extension 4' (Video Pixel Formatter): Data, Enabled, Immutable
Priority: 2
Video input : 0 (Camera 1: ok)
Format Video Capture:
Width/Height      : 1920/1080
Pixel Format      : 'MJPG' (Motion-JPEG)
Field             : None
Bytes per Line    : 0
Size Image        : 4147789
Colorspace        : sRGB
Transfer Function : Default (maps to sRGB)
YCbCr/HSV Encoding: Default (maps to ITU-R 601)
Quantization      : Default (maps to Full Range)
Flags             :
Crop Capability Video Capture:
Bounds      : Left 0, Top 0, Width 1920, Height 1080
Default     : Left 0, Top 0, Width 1920, Height 1080
Pixel Aspect: 1/1
Selection Video Capture: crop_default, Left 0, Top 0, Width 1920, Height 1080, Flags:
Selection Video Capture: crop_bounds, Left 0, Top 0, Width 1920, Height 1080, Flags:
Streaming Parameters Video Capture:
Capabilities     : timeperframe
Frames per second: 15.000 (15/1)
Read buffers     : 0

User Controls

brightness 0x00980900 (int)    : min=-64 max=64 step=1 default=0 value=64
contrast 0x00980901 (int)    : min=0 max=64 step=1 default=32 value=32
saturation 0x00980902 (int)    : min=0 max=128 step=1 default=56 value=56
hue 0x00980903 (int)    : min=-40 max=40 step=1 default=0 value=0
white_balance_automatic 0x0098090c (bool)   : default=1 value=1
gamma 0x00980910 (int)    : min=72 max=500 step=1 default=100 value=100
gain 0x00980913 (int)    : min=0 max=100 step=1 default=0 value=0
power_line_frequency 0x00980918 (menu)   : min=0 max=2 default=1 value=1 (50 Hz)
0: Disabled
1: 50 Hz
2: 60 Hz
white_balance_temperature 0x0098091a (int)    : min=2800 max=6500 step=1 default=4600 value=4600 flags=inactive
sharpness 0x0098091b (int)    : min=0 max=6 step=1 default=3 value=3
backlight_compensation 0x0098091c (int)    : min=0 max=2 step=1 default=1 value=1

Camera Controls

auto_exposure 0x009a0901 (menu)   : min=0 max=3 default=3 value=1 (Manual Mode)
1: Manual Mode
3: Aperture Priority Mode
exposure_time_absolute 0x009a0902 (int)    : min=1 max=5000 step=1 default=156 value=5000
exposure_dynamic_framerate 0x009a0903 (bool)   : default=0 value=0
Я также пытался сохранить изображение с помощью ffmpeg на случай, если с opencv что-то не так, вот так:

Код: Выделить всё

ffmpeg -f v4l2 -framerate 30 -video_size 1920x1080 -i /dev/video0 -c:v libx264 -preset fast -crf 23 -t 00:01:00 output.mp4

Изображение сохраняется, но также изменяется его формат

Код: Выделить всё

[video4linux2,v4l2 @ 0x555659ed92b0] The V4L2 driver changed the video from 1920x1080 to 800x600
[video4linux2,v4l2 @ 0x555659ed92b0] The driver changed the time per frame from 1/30 to 1/15
Но формат выглядит правильно, если вернуть его в FHD с помощью v4l2

Код: Выделить всё

>>>  v4l2-ctl --device=/dev/video0 --set-fmt-video=width=1920,height=1080,pixelformat=MJPG
>>> v4l2-ctl --get-fmt-video

Format Video Capture:
Width/Height      : 1920/1080
Pixel Format      : 'MJPG' (Motion-JPEG)
Field             : None
Bytes per Line    : 0
Size Image        : 4147789
Colorspace        : sRGB
Transfer Function : Default (maps to sRGB)
YCbCr/HSV Encoding: Default (maps to ITU-R 601)
Quantization      : Default (maps to Full Range)
Flags             :
Я не уверен, что может быть не так с форматом/камерой, и не думаю, что у меня достаточно информации, чтобы это понять.
Я пытался использовать ffmpeg вместо opencv, а также изменил несколько настроек в конфигурации opencv cup.


Подробнее здесь: https://stackoverflow.com/questions/791 ... mat-at-fhd
Ответить

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

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

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

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

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