Zusätzlich zum vorherigen Artikel fügen wir einen Regions-ROI (Region of Interest) hinzu, der als Operationsziel ausgewählt werden soll, und einen Prozess (Maske), der nur auf einen bestimmten Teil abzielt.
Sie können die Verarbeitung auf ein bestimmtes Teil (eine bestimmte Maske) in der ROI anwenden. Die Maskenauswahl konvertiert das Bild in HSV, sodass Sie mit jedem Schieberegler einen numerischen Wert auswählen können. Der Maskenteil wird in einem separaten Fenster angezeigt, damit Sie ihn überprüfen können.
Bei der Auswahl von Rot müssen zwei Bereiche von Farbtonwerten ausgewählt werden, z. B. 0-20 und 110-255. Erstellen Sie daher ein Kontrollkästchen mit dem Namen "Farbtonumkehrung". Wenn das Kontrollkästchen aktiviert ist, Der Wert außerhalb der beiden Schieberegler wird als Maskenbereich festgelegt.
Der Bereich zwischen dem linken und rechten Schieberegler von Hue ist der Maskenbereich.
Die Außenseite des linken und rechten Schiebereglers von Hue ist der Maskenbereich. Sie können den Maskenbereich invertieren.
Sie können einen bestimmten Bereich von Videos als DIVX, MJEG, GIF speichern.
Wählen Sie die zu ladende Datei über die GUI aus.
import PySimpleGUI as sg
import cv2
import numpy as np
from PIL import Image
from pathlib import Path
def file_read():
'''
Wählen Sie eine Datei aus und laden Sie sie
'''
fp = ""
#GUI-Layout
layout = [
[
sg.FileBrowse(key="file"),
sg.Text("Datei"),
sg.InputText()
],
[sg.Submit(key="submit"), sg.Cancel("Exit")]
]
#WINDOW-Generation
window = sg.Window("Dateiauswahl", layout)
#Ereignisschleife
while True:
event, values = window.read(timeout=100)
if event == 'Exit' or event == sg.WIN_CLOSED:
break
elif event == 'submit':
if values[0] == "":
sg.popup("Es wurde keine Datei eingegeben.")
event = ""
else:
fp = values[0]
break
window.close()
return Path(fp)
HSV-Konvertierung → Die Maskenverarbeitung wird zu einer Funktion. Erstellen Sie eine Maske aus den Min- und Max-Werten von H, S und V, die von der GUI empfangen wurden, und erstellen Sie ein Maskenbild mit cv2.bitwize_and ().
def hsv(frame, H_max, H_min, S_max, S_min, V_max, V_min, reverse=False):
frame_hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
if reverse:
lower1 = np.array([0, int(S_min), int(V_min)])
upper1 = np.array([int(H_min), int(S_max), int(V_max)])
mask1 = cv2.inRange(frame_hsv, lower1, upper1)
lower2 = np.array([int(H_max), int(S_min), int(V_min)])
upper2 = np.array([255, int(S_max), int(V_max)])
mask2 = cv2.inRange(frame_hsv, lower2, upper2)
mask = mask1 + mask2
frame = cv2.bitwise_and(frame, frame, mask=mask)
# mask = cv2.bitwise_and(frame, mask, mask=mask)
else:
lower = np.array([int(H_min), int(S_min), int(V_min)])
upper = np.array([int(H_max), int(S_max), int(V_max)])
mask = cv2.inRange(frame_hsv, lower, upper)
frame = cv2.bitwise_and(frame, frame, mask=mask)
return frame
class Main:
def __init__(self):
self.fp = file_read()
self.cap = cv2.VideoCapture(str(self.fp))
#Video-Speicherflagge
self.rec_flg = False
#Holen Sie sich das erste Bild
#Überprüfen Sie, ob es erhältlich ist
self.ret, self.f_frame = self.cap.read()
self.cap.set(cv2.CAP_PROP_POS_FRAMES, 0)
#Wenn Sie den Rahmen erhalten können, erhalten Sie verschiedene Parameter
if self.ret:
self.cap.set(cv2.CAP_PROP_POS_FRAMES, 0)
#Erfassung von Videoinformationen
self.fps = self.cap.get(cv2.CAP_PROP_FPS)
self.width = int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH))
self.height = int(self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
self.total_count = self.cap.get(cv2.CAP_PROP_FRAME_COUNT)
# ROI
self.frames_roi = np.zeros((5, self.height, self.width))
Bereiten Sie als Maskenbild ein Graustufenmaskenbild mit der gleichen Größe wie der ROI vor.
#Definition des Maskenbildes
self.mask = np.zeros_like(self.f_frame[:, :, 0])
#Originalgröße speichern
self.org_width = self.width
self.org_height = self.height
#Rahmenbezogen
self.frame_count = 0
self.s_frame = 0
self.e_frame = self.total_count
#Bildausschnittposition
self.x1 = 0
self.y1 = 0
self.x2 = self.width
self.y2 = self.height
#Pause-Flag spielen
self.stop_flg = False
#Kontrolle der Mausbewegung
#Ob die Maustaste gedrückt wird
self.mouse_flg = False
self.event = ""
#Gibt an, ob die Berechnung auf den ROI angewendet werden soll
self.roi_flg = True
cv2.namedWindow("Movie")
#Rückrufregistrierung für Mausereignisse
cv2.setMouseCallback("Movie", self.onMouse)
#Beenden Sie, wenn der Frame nicht erhalten werden konnte
else:
sg.Popup("Fehler beim Lesen der Datei.")
return
#Mausereignis
def onMouse(self, event, x, y, flags, param):
#Links Klick
if event == cv2.EVENT_LBUTTONDOWN:
self.x1 = self.x2 = x
self.y1 = self.y2 = y
#Beginnen Sie mit dem Zeichnen eines Rechtecks. Drücken Sie einmal die Maus, um ein Rechteck zu zeichnen.
self.mouse_flg = True
#Unterbrechen Sie die Berechnung des ROI-Teils
self.roi_flg = False
return
elif event == cv2.EVENT_LBUTTONUP:
#Beenden Sie die Aktualisierung von Rechtecken
self.mouse_flg = False
#Starten Sie die Berechnung zum ROI
self.roi_flg = True
#Wenn die ROI-Auswahl 0 ist, setzen Sie sie zurück und beenden Sie die ROI-Berechnung.
if (
x == self.x1
or y == self.y1
or x <= 0
or y <= 0
):
self.x1 = 0
self.y1 = 0
self.x2 = self.width
self.y2 = self.height
return
# x1 <Mach es x2
elif self.x1 < x:
self.x2 = x
else:
self.x2 = self.x1
self.x1 = x
if self.y1 < y:
self.y2 = y
else:
self.y2 = self.y1
self.y1 = y
#ROI-Bereich anzeigen
print(
"ROI x:{0}:{1} y:{2}:{3}".format(
str(self.x1),
str(self.x2),
str(self.y1),
str(self.y2)
)
)
return
#Zeigt das Rechteck weiterhin an, wenn die Maus gedrückt wird
if self.mouse_flg:
self.x2 = x
self.y2 = y
return
def run(self):
# GUI #######################################################
#GUI-Layout
#Tab 1
T1 = sg.Tab("Basic", [
[
sg.Text("Resize ", size=(13, 1)),
sg.Slider(
(0.1, 4),
1,
0.01,
orientation='h',
size=(40, 15),
key='-RESIZE SLIDER-',
enable_events=True
)
],
[
sg.Checkbox(
'blur',
size=(10, 1),
key='-BLUR-',
enable_events=True
),
sg.Slider(
(1, 10),
1,
1,
orientation='h',
size=(40, 15),
key='-BLUR SLIDER-',
enable_events=True
)
],
])
T2 = sg.Tab("processing", [
[
sg.Checkbox(
'gray',
size=(10, 1),
key='-GRAY-',
enable_events=True
)
],
])
Bereiten Sie eine Registerkarte für die Maskenverarbeitung vor. Wenn mit dem Optionsfeld Maskierung ausgewählt ist, wird die Maskierung durchgeführt.
T3 = sg.Tab("mask", [
[
sg.Radio(
'Rectangle',
"RADIO2",
key='-RECTANGLE_MASK-',
default=True,
size=(8, 1)
),
sg.Radio(
'Masking',
"RADIO2",
key='-MASKING-',
size=(8, 1)
)
],
[
sg.Checkbox(
"Blue",
size=(10, 1),
default=True,
key='-BLUE_MASK-',
enable_events=True
),
sg.Checkbox(
"Green",
size=(10, 1),
default=True,
key='-GREEN_MASK-',
enable_events=True
),
sg.Checkbox(
"Red",
size=(10, 1),
default=True,
key='-RED_MASK-',
enable_events=True
)
],
[
sg.Text(
'hsv',
size=(10, 1),
key='-HSV_MASK-',
enable_events=True
),
sg.Button('Blue', size=(10, 1)),
sg.Button('Green', size=(10, 1)),
sg.Button('Red', size=(10, 1))
],
[
sg.Checkbox(
'Hue Reverse',
size=(10, 1),
key='-Hue Reverse_MASK-',
enable_events=True
)
],
[
sg.Text('Hue', size=(10, 1), key='-Hue_MASK-'),
sg.Slider(
(0, 255),
0,
1,
orientation='h',
size=(19.4, 15),
key='-H_MIN SLIDER_MASK-',
enable_events=True
),
sg.Slider(
(1, 255),
125,
1,
orientation='h',
size=(19.4, 15),
key='-H_MAX SLIDER_MASK-',
enable_events=True
)
],
[
sg.Text('Saturation', size=(10, 1), key='-Saturation_MASK-'),
sg.Slider(
(0, 255),
50,
1,
orientation='h',
size=(19.4, 15),
key='-S_MIN SLIDER_MASK-',
enable_events=True
),
sg.Slider(
(1, 255),
255,
1,
orientation='h',
size=(19.4, 15),
key='-S_MAX SLIDER_MASK-',
enable_events=True
)
],
[
sg.Text('Value', size=(10, 1), key='-Value_MASK-'),
sg.Slider(
(0, 255),
50,
1,
orientation='h',
size=(19.4, 15),
key='-V_MIN SLIDER_MASK-',
enable_events=True
),
sg.Slider(
(1, 255),
255,
1,
orientation='h',
size=(19.4, 15),
key='-V_MAX SLIDER_MASK-',
enable_events=True
)
]
])
T4 = sg.Tab("Save", [
[
sg.Button('Write', size=(10, 1)),
sg.Radio(
'DIVX',
"RADIO1",
key='-DIVX-',
default=True,
size=(8, 1)
),
sg.Radio('MJPG', "RADIO1", key='-MJPG-', size=(8, 1)),
sg.Radio('GIF', "RADIO1", key='-GIF-', size=(8, 1))
],
[
sg.Text('Caption', size=(10, 1)),
sg.InputText(
size=(32, 50),
key='-CAPTION-',
enable_events=True
)
]
])
layout = [
[
sg.Text("Start", size=(8, 1)),
sg.Slider(
(0, self.total_count - 1),
0,
1,
orientation='h',
size=(45, 15),
key='-START FRAME SLIDER-',
enable_events=True
)
],
[
sg.Text("End ", size=(8, 1)),
sg.Slider(
(0, self.total_count - 1), self.total_count - 1,
1,
orientation='h',
size=(45, 15),
key='-END FRAME SLIDER-',
enable_events=True
)
],
[sg.Slider(
(0, self.total_count - 1),
0,
1,
orientation='h',
size=(50, 15),
key='-PROGRESS SLIDER-',
enable_events=True
)],
[
sg.Button('<<<', size=(5, 1)),
sg.Button('<<', size=(5, 1)),
sg.Button('<', size=(5, 1)),
sg.Button('Play / Stop', size=(9, 1)),
sg.Button('Reset', size=(7, 1)),
sg.Button('>', size=(5, 1)),
sg.Button('>>', size=(5, 1)),
sg.Button('>>>', size=(5, 1))
],
[
sg.Text("Speed", size=(6, 1)),
sg.Slider(
(0, 240),
10,
10,
orientation='h',
size=(19.4, 15),
key='-SPEED SLIDER-',
enable_events=True
),
sg.Text("Skip", size=(6, 1)),
sg.Slider(
(0, 300),
0,
1,
orientation='h',
size=(19.4, 15),
key='-SKIP SLIDER-',
enable_events=True
)
],
[sg.HorizontalSeparator()],
[
sg.TabGroup(
[[T1, T2, T3, T4]],
tab_background_color="#ccc",
selected_title_color="#fff",
selected_background_color="#444",
tab_location="topleft"
)
],
[sg.Output(size=(65, 5), key='-OUTPUT-')],
[sg.Button('Clear')]
]
#Fenster generieren
window = sg.Window('OpenCV Integration', layout, location=(0, 0))
#Anzeige von Videoinformationen
self.event, values = window.read(timeout=0)
print("Die Datei wurde gelesen.")
print("File Path: " + str(self.fp))
print("fps: " + str(int(self.fps)))
print("width: " + str(self.width))
print("height: " + str(self.height))
print("frame count: " + str(int(self.total_count)))
#Hauptschleife#########################################################
try:
while True:
#Laden von GUI-Ereignissen
self.event, values = window.read(
timeout=values["-SPEED SLIDER-"]
)
#Ereignis im Fenster anzeigen
if self.event != "__TIMEOUT__":
print(self.event)
#Beenden, wenn die Schaltfläche Beenden gedrückt wird oder wenn die Schaltfläche zum Schließen des Fensters gedrückt wird
if self.event in ('Exit', sg.WIN_CLOSED, None):
break
#Video neu laden
#Funktioniert, wenn der Startrahmen eingestellt ist
if self.event == 'Reset':
self.cap.set(cv2.CAP_PROP_POS_FRAMES, self.s_frame)
self.frame_count = self.s_frame
window['-PROGRESS SLIDER-'].update(self.frame_count)
self.video_stabilization_flg = False
self.stab_prepare_flg = False
#Reflektieren Sie weiterhin Änderungen am Fortschrittsregler
continue
#Video exportieren
if self.event == 'Write':
self.rec_flg = True
self.cap.set(cv2.CAP_PROP_POS_FRAMES, self.s_frame)
self.frame_count = self.s_frame
window['-PROGRESS SLIDER-'].update(self.frame_count)
if values["-GIF-"]:
images = []
else:
#Als Video speichern
#Codeauswahl
#DIVX hat eine hohe Komprimierungsrate
#MJEG kann mit ImageJ analysiert werden
if values["-DIVX-"]:
codec = "DIVX"
elif values["-MJPG-"]:
codec = "MJPG"
fourcc = cv2.VideoWriter_fourcc(*codec)
out = cv2.VideoWriter(
str((
self.fp.parent / (self.fp.stem + '_' + codec + '.avi')
)),
fourcc,
self.fps,
(int(self.x2 - self.x1), int(self.y2 - self.y1))
)
continue
if self.event == 'Stabilization':
self.cap.set(cv2.CAP_PROP_POS_FRAMES, self.s_frame)
self.frame_count = self.s_frame
window['-PROGRESS SLIDER-'].update(self.frame_count)
self.play_count = int(self.e_frame - self.s_frame)
self.video_stabilization_flg = True
continue
#Rahmenbetrieb################################################
#Priorität wird gegeben, wenn der Schieberegler direkt geändert wird
if self.event == '-PROGRESS SLIDER-':
#Stellen Sie die Frame-Anzahl auf den Fortschrittsbalken ein
self.frame_count = int(values['-PROGRESS SLIDER-'])
self.cap.set(cv2.CAP_PROP_POS_FRAMES, self.frame_count)
if values['-PROGRESS SLIDER-'] > values['-END FRAME SLIDER-']:
window['-END FRAME SLIDER-'].update(
values['-PROGRESS SLIDER-'])
#Wenn Sie den Startrahmen ändern
if self.event == '-START FRAME SLIDER-':
self.s_frame = int(values['-START FRAME SLIDER-'])
self.cap.set(cv2.CAP_PROP_POS_FRAMES, self.s_frame)
self.frame_count = self.s_frame
window['-PROGRESS SLIDER-'].update(self.frame_count)
if values['-START FRAME SLIDER-'] > values['-END FRAME SLIDER-']:
window['-END FRAME SLIDER-'].update(
values['-START FRAME SLIDER-'])
self.e_frame = self.s_frame
#Wenn Sie den Endrahmen ändern
if self.event == '-END FRAME SLIDER-':
if values['-END FRAME SLIDER-'] < values['-START FRAME SLIDER-']:
window['-START FRAME SLIDER-'].update(
values['-END FRAME SLIDER-'])
self.s_frame = self.e_frame
#Rahmeneinstellungen beenden
self.e_frame = int(values['-END FRAME SLIDER-'])
if self.event == '<<<':
self.frame_count = np.maximum(0, self.frame_count - 150)
window['-PROGRESS SLIDER-'].update(self.frame_count)
self.cap.set(cv2.CAP_PROP_POS_FRAMES, self.frame_count)
if self.event == '<<':
self.frame_count = np.maximum(0, self.frame_count - 30)
window['-PROGRESS SLIDER-'].update(self.frame_count)
self.cap.set(cv2.CAP_PROP_POS_FRAMES, self.frame_count)
if self.event == '<':
self.frame_count = np.maximum(0, self.frame_count - 1)
window['-PROGRESS SLIDER-'].update(self.frame_count)
self.cap.set(cv2.CAP_PROP_POS_FRAMES, self.frame_count)
if self.event == '>':
self.frame_count = self.frame_count + 1
window['-PROGRESS SLIDER-'].update(self.frame_count)
self.cap.set(cv2.CAP_PROP_POS_FRAMES, self.frame_count)
if self.event == '>>':
self.frame_count = self.frame_count + 30
window['-PROGRESS SLIDER-'].update(self.frame_count)
self.cap.set(cv2.CAP_PROP_POS_FRAMES, self.frame_count)
if self.event == '>>>':
self.frame_count = self.frame_count + 150
window['-PROGRESS SLIDER-'].update(self.frame_count)
self.cap.set(cv2.CAP_PROP_POS_FRAMES, self.frame_count)
#Wenn der Zähler den Endrahmen überschreitet, starten Sie ihn vom Startrahmen aus neu
if self.frame_count >= self.e_frame:
self.cap.set(cv2.CAP_PROP_POS_FRAMES, self.s_frame)
self.frame_count = self.s_frame
window['-PROGRESS SLIDER-'].update(self.frame_count)
continue
#Unterbrechen Sie das Laden des Videos mit der Stopp-Taste
if self.event == 'Play / Stop':
self.stop_flg = not self.stop_flg
#Wenn das Stopp-Flag nicht gesetzt ist und ein Ereignis eintritt, zählen Sie mit
#Beenden Sie den Vorgang
#Wenn die Stopp-Taste gedrückt wird, wird die Videoverarbeitung gestoppt, aber etwas
#Wenn ein Ereignis auftritt, aktualisieren Sie nur das Image
#Gleiches gilt für die Bedienung der Maus
if(
(
self.stop_flg
and self.event == "__TIMEOUT__"
and self.mouse_flg is False
)
):
window['-PROGRESS SLIDER-'].update(self.frame_count)
continue
#Frames überspringen
if not self.stop_flg and values['-SKIP SLIDER-'] != 0:
self.frame_count += values["-SKIP SLIDER-"]
self.cap.set(cv2.CAP_PROP_POS_FRAMES, self.frame_count)
#Rahmen laden##############################################
self.ret, self.frame = self.cap.read()
self.valid_frame = int(self.frame_count - self.s_frame)
#Wenn der letzte Frame über sich selbst ist.s_Vom Rahmen fortsetzen
if not self.ret:
self.cap.set(cv2.CAP_PROP_POS_FRAMES, self.s_frame)
self.frame_count = self.s_frame
continue
#Beschreiben Sie anschließend die Verarbeitung für den Frame##################################
#Führen Sie zunächst die Verarbeitung für den gesamten Frame durch##############################
#Größe ändern
self.width = int(self.org_width * values['-RESIZE SLIDER-'])
self.height = int(self.org_height * values['-RESIZE SLIDER-'])
self.frame = cv2.resize(self.frame, (self.width, self.height))
if self.event == '-RESIZE SLIDER-':
self.x1 = self.y1 = 0
self.x2 = self.width
self.y2 = self.height
#Führen Sie die Verarbeitung für den ROI durch##########################################
if self.roi_flg:
self.frame_roi = self.frame[
self.y1:self.y2, self.x1:self.x2, :
]
Beschreiben Sie die Maskenverarbeitung. Die Farbspezifikation ist in RGB anstelle von HSV. Nachdem Sie die Farbe mit RGB festgelegt haben, können Sie den Maskenbereich mit V (Helligkeit) von HSV festlegen. In diesem Fall sollte Hue den gesamten Bereich von 0 bis 255 angeben und nur V ändern.
#Verarbeitung zu MASK-Bildern##################################################################
if values['-MASKING-']:
#RGB-Trennung
self.mask = np.copy(self.frame_roi)
if not values['-BLUE_MASK-']:
self.mask[:, :, 0] = 0
if not values['-GREEN_MASK-']:
self.mask[:, :, 1] = 0
if not values['-RED_MASK-']:
self.mask[:, :, 2] = 0
Beschreibt die Maskenverarbeitung im HSV. Mit den Schaltflächen Rot, Grün und Blau können Sie jede Farbe innerhalb eines bestimmten Bereichs auswählen. Sie können das Objekt maskieren, indem Sie den Schwellenwert anpassen, während Sie das Originalvideo und das Maskenvideo ansehen.
if self.event == 'Blue':
window['-H_MIN SLIDER_MASK-'].update(70)
window['-H_MAX SLIDER_MASK-'].update(110)
window['-S_MIN SLIDER_MASK-'].update(70)
window['-S_MAX SLIDER_MASK-'].update(255)
window['-V_MIN SLIDER_MASK-'].update(0)
window['-V_MAX SLIDER_MASK-'].update(255)
window['-Hue Reverse_MASK-'].update(False)
if self.event == 'Green':
window['-H_MIN SLIDER_MASK-'].update(20)
window['-H_MAX SLIDER_MASK-'].update(70)
window['-S_MIN SLIDER_MASK-'].update(70)
window['-S_MAX SLIDER_MASK-'].update(255)
window['-V_MIN SLIDER_MASK-'].update(0)
window['-V_MAX SLIDER_MASK-'].update(255)
window['-Hue Reverse_MASK-'].update(False)
if self.event == 'Red':
window['-H_MIN SLIDER_MASK-'].update(20)
window['-H_MAX SLIDER_MASK-'].update(110)
window['-S_MIN SLIDER_MASK-'].update(70)
window['-S_MAX SLIDER_MASK-'].update(255)
window['-V_MIN SLIDER_MASK-'].update(0)
window['-V_MAX SLIDER_MASK-'].update(255)
window['-Hue Reverse_MASK-'].update(True)
self.mask = hsv(
self.mask,
values['-H_MAX SLIDER_MASK-'],
values['-H_MIN SLIDER_MASK-'],
values['-S_MAX SLIDER_MASK-'],
values['-S_MIN SLIDER_MASK-'],
values['-V_MAX SLIDER_MASK-'],
values['-V_MIN SLIDER_MASK-'],
values['-Hue Reverse_MASK-']
)
#Graustufen
self.mask = cv2.cvtColor(
self.mask,
cv2.COLOR_BGR2GRAY
)
#Verwischen
if values['-BLUR-']:
self.frame_roi = cv2.GaussianBlur(
self.frame_roi, (21, 21), values['-BLUR SLIDER-']
)
if values['-GRAY-']:
self.frame_roi = cv2.cvtColor(
self.frame_roi,
cv2.COLOR_BGR2GRAY
)
self.frame_roi = cv2.cvtColor(
self.frame_roi,
cv2.COLOR_GRAY2BGR
)
Wenden Sie die Verarbeitung nur auf den Maskenbereich innerhalb des ROI an. Ich verwende cv2.bitwise_not verschachtelt, aber es gibt möglicherweise einen besseren Weg, dies zu tun.
if values['-MASKING-']:
# frame_Tragen Sie die Maske in Roi auf
#Nur der Maskenverarbeitungsteil ist ein Rahmen_Wechseln Sie zu Roi
self.frame_roi = cv2.bitwise_not(
cv2.bitwise_not(self.frame_roi),
self.frame[self.y1:self.y2, self.x1:self.x2, :],
mask=self.mask
)
#Geben Sie den verarbeiteten ROI an den Frame zurück
self.frame[self.y1:self.y2, self.x1:self.x2, :] = self.frame_roi
#Video speichern
if self.rec_flg:
#Schneiden Sie das Roi nach der Verwacklungskorrektur wieder aus
self.frame_roi = self.frame[
self.y1:self.y2, self.x1:self.x2, :
]
if values["-GIF-"]:
images.append(
Image.fromarray(
cv2.cvtColor(
self.frame_roi, cv2.COLOR_BGR2RGB
)
)
)
else:
out.write(self.frame_roi)
#Anzeige beim Speichern
cv2.putText(
self.frame,
str("Now Recording"),
(20, 60),
cv2.FONT_HERSHEY_SIMPLEX,
0.5,
(10, 10, 255),
1,
cv2.LINE_AA
)
# e_Beenden Sie, wenn es ein Rahmen wird
if self.frame_count >= self.e_frame - values["-SKIP SLIDER-"] - 1:
if values["-GIF-"]:
images[0].save(
str((self.fp.parent / (self.fp.stem + '.gif'))),
save_all=True,
append_images=images[1:],
optimize=False,
duration=1000 // self.fps,
loop=0
)
else:
out.release()
self.rec_flg = False
#Anzeige der Anzahl der Frames und der verstrichenen Sekunden
cv2.putText(
self.frame, str("framecount: {0:.0f}".format(self.frame_count)), (
15, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (240, 230, 0), 1, cv2.LINE_AA
)
cv2.putText(
self.frame, str("time: {0:.1f} sec".format(
self.frame_count / self.fps)), (15, 40), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (240, 230, 0), 1, cv2.LINE_AA
)
#Bei der Berechnung des ROI oder beim Drücken der linken Maustaste
#Zeichne ein Rechteck
if self.roi_flg or self.mouse_flg:
cv2.rectangle(
self.frame,
(self.x1, self.y1),
(self.x2 - 1, self.y2 - 1),
(128, 128, 128)
)
Das Maskenbild wird nur angezeigt, wenn Maskierung ausgewählt ist.
#Bild anzeigen
cv2.imshow("Movie", self.frame)
if values['-MASKING-']:
cv2.imshow("Mask", cv2.cvtColor(self.mask, cv2.COLOR_GRAY2BGR))
cv2.setWindowProperty("Mask", cv2.WND_PROP_VISIBLE, 0)
elif not values['-MASKING-'] and cv2.getWindowProperty("Mask", cv2.WND_PROP_VISIBLE):
cv2.destroyWindow("Mask")
if self.stop_flg:
self.cap.set(cv2.CAP_PROP_POS_FRAMES, self.frame_count)
else:
self.frame_count += 1
window['-PROGRESS SLIDER-'].update(self.frame_count + 1)
#Andere Verarbeitung###############################################
#Protokollfenster löschen
if self.event == 'Clear':
window['-OUTPUT-'].update('')
finally:
cv2.destroyWindow("Movie")
cv2.destroyWindow("Mask")
self.cap.release()
window.close()
if __name__ == '__main__':
Main().run()
Lassen Sie uns rote Objekte mit Python erkennen Wikipedia: HSV-Farbraum Alpha-Überblendung und Maskierung von Bildern mit Python, OpenCV, NumPy
Recommended Posts