OpenCV расширяет подачу веб-камеры вместо использования полного разрешения - PullRequest
4 голосов
/ 12 июня 2019

У меня есть веб-камера 1080p (Logitech v-u0032), и я создаю программу, которая сохраняет данные из канала каждые X секунд, однако изображения имеют черные полосы по бокам, и разрешение, по-видимому, ниже, чем при использовании встроенного в Windows приложения камеры. оба выходных файла имеют разрешение 1920x1080 пикселей, но разница в реальном разрешении очень заметна

Я искал способы изменить разрешение, но OpenCV, кажется, всегда масштабируется до нового разрешения

import cv2
import numpy as np
import datetime
import time
import os

cv2.namedWindow("Unregistered Hypercam")
vc = cv2.VideoCapture(0)

vc.set(3, 1920) # Set the horizontal resolution
vc.set(4, 1080) # Set the vertical resolution
vc.set(5, 10)   # Set the framerate

if vc.isOpened():
    rval, frame = vc.read()
else:
    rval = False

lastSave = time.time()

def mfold(name):
    try:  
         os.mkdir(name)
    except OSError:  
         x = 0
    else:  
        print ("Successfully created the directory %s " % fold)

while rval:
    cv2.imshow("Unregistered Hypercam", frame)
    rval, frame = vc.read()
    now = datetime.datetime.now()

    if time.time() > lastSave + 10:
        lastSave = time.time()
        fold = '\\snapshots\\' # This will create folder C:\snapshots
        mfold(fold)
        cv2.imwrite(fold + str(now.year) + '.' + str(now.month) + '.' + str(now.day) + '  ' + str(now.hour) + 'h_' + str(now.minute) + 'm_' + str(now.second) + 's.png', frame)

    key = cv2.waitKey(20)
    if key == 27:
        break

cv2.destroyWindow("Unregistered Hypercam")

Изображения размытые и нерезкие с черными полосами и нигде не похожи на изображения, сделанные с помощью приложения камеры Windows

1 Ответ

0 голосов
/ 12 июня 2019

image

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

Настройка разрешения кадра при сохранении соотношения сторон

# Resizes a image and maintains aspect ratio
def maintain_aspect_ratio_resize(image, width=None, height=None, inter=cv2.INTER_AREA):
    # Grab the image size and initialize dimensions
    dim = None
    (h, w) = image.shape[:2]

    # Return original image if no need to resize
    if width is None and height is None:
        return image

    # We are resizing height if width is none
    if width is None:
        # Calculate the ratio of the height and construct the dimensions
        r = height / float(h)
        dim = (int(w * r), height)
    # We are resizing width if height is none
    else:
        # Calculate the ratio of the 0idth and construct the dimensions
        r = width / float(w)
        dim = (width, int(h * r))

    # Return the resized image
    return cv2.resize(image, dim, interpolation=inter)

Вы можете использовать это, чтобы настроить ширину или высоту

rval, frame = vc.read()

resize_width = maintain_aspect_ratio_resize(frame, width=500)
resize_height = maintain_aspect_ratio_resize(frame, height=500)

Поток и сохранить виджет видео

from threading import Thread
import cv2

class VideoWriterObject(object):
    def __init__(self, src=0):
        # Create a VideoCapture object
        self.capture = cv2.VideoCapture(src)

        # Default resolutions of the frame are obtained (system dependent)
        self.frame_width = int(self.capture.get(3))
        self.frame_height = int(self.capture.get(4))

        # Set up codec and output video settings
        self.codec = cv2.VideoWriter_fourcc('M','J','P','G')
        self.output_video = cv2.VideoWriter('output.avi', self.codec, 30, (self.frame_width, self.frame_height))

        # Start the thread to read frames from the video stream
        self.thread = Thread(target=self.update, args=())
        self.thread.daemon = True
        self.thread.start()

    def update(self):
        # Read the next frame from the stream in a different thread
        while True:
            if self.capture.isOpened():
                (self.status, self.frame) = self.capture.read()

    def show_frame(self):
        # Display frames in main program
        if self.status:
            cv2.imshow('frame', self.frame)

        # Press Q on keyboard to stop recording
        key = cv2.waitKey(1)
        if key == ord('q'):
            self.capture.release()
            self.output_video.release()
            cv2.destroyAllWindows()
            exit(1)

    def save_frame(self):
        # Save obtained frame into video output file
        self.output_video.write(self.frame)

if __name__ == '__main__':
    video_stream_widget = VideoWriterObject(0)
    while True:
        try:
            video_stream_widget.show_frame()
            video_stream_widget.save_frame()
        except AttributeError:
            pass
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...