Obwohl ich in der Nicht-IT-Abteilung der Fertigungsindustrie arbeite, arbeite ich mit einem Bewusstsein für KI und IoT. Ich arbeite in der Nähe des produktionstechnischen Auftrags, der sich in der Nähe des Produktionsstandorts befindet, aber eines der Probleme bei der Systematisierung ist, dass er nicht mit dem Gewinn für die Fabrik in Einklang gebracht wird. Ich möchte etwas tun, aber wenn ich es schätze, sind die Einführungskosten hoch (die Arbeitskosten sind oft hoch ...) und ich kann aufgeben. Daher denke ich, dass der folgende Inhalt gut ist, um ihn unter dem Gesichtspunkt der Verbesserung der Fähigkeiten zu erstellen.
Wir sind bestrebt, eine Echtzeitverarbeitung (Binärisierung, Berechnung / Anzeige einer bestimmten Entfernung usw.) für das am Produktionsstandort aufgezeichnete aufgezeichnete Video durchzuführen und das Ergebnis anzuzeigen. Überraschenderweise kann es den Mitarbeitern vor Ort helfen, selbst einfach verarbeitete Videobilder problemlos zu erstellen.
Nun, es ist lange her, aber der Umriss dieser Zeit ist wie folgt.
Der vorherige Artikel ist hier.
Machen Sie das Bild binär. Weiterhin kann der kürzeste Abstand zwischen zwei Regionen berechnet werden (Ver1.1). https://qiita.com/Fumio-eisan/items/10c54af7a925b403f59f
Führen Sie zunächst den Vorgang zum Anzeigen des Videos durch. Dieses Mal werden wir das Video mit der folgenden Aufnahme etwa 7 Sekunden lang verarbeiten.
video.ipynb
#Einfach anzeigen
import cv2
import sys
file_path = 'sample_.mov'
delay = 1
window_name = 'frame'
cap = cv2.VideoCapture(file_path)
text = 'text.wmv'
if not cap.isOpened():
sys.exit()
while True:
ret, frame = cap.read()
# if not ret: #Wenn Sie diese beiden Zeilen einfügen, endet sie mit einer Videowiedergabe.
# break
if ret:
frame = cv2.resize(frame, dsize=(600, 400))
cv2.imshow(window_name, frame)
if cv2.waitKey(delay) & 0xFF == ord('q'):
break
else:
cap.set(cv2.CAP_PROP_POS_FRAMES, 0)
cv2.destroyWindow(window_name)
Es ist in Ordnung, wenn Sie den Pfad des Videos beschreiben, das Sie in file_path anzeigen möchten. Bei diesem Programm wird das Video weiterhin in einer Endlosschleife abgespielt. Sie können die Videowiedergabe stoppen, indem Sie die Taste q drücken.
In Bezug auf die Anzeige des Videos drehen wir nach dem folgenden Verfahren.
Es ist geworden. Ich werde später eine Notiz schreiben, aber da sie für jeden Frame in 3 verarbeitet wird, müssen Sie vorsichtig sein, wenn Sie den Telop (anzuzeigender Wert usw.) ändern möchten, den Sie jede Sekunde oder alle paar Sekunden anzeigen möchten.
video.ipynb
cv2.putText(frame, text,(100, 30), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 255, 0), thickness=2)
Über diese Anzeige ist eine Untertitelausgabe möglich. Die Argumente sind wie folgt.
Lassen Sie es uns jetzt binarisieren und in Schwarzweiß anzeigen. Die Methode ist in Ordnung, wenn Sie die oberen und unteren Grenzen der zu extrahierenden Farbe wie das Bild definieren und mit der Methode cv2.inRange () definieren.
video.ipynb
#Binarisierungsprozess
import cv2
import sys
camera_id = 0
delay = 1
window_name = 'frame'
file_path = 'sample_.mov'
cap = cv2.VideoCapture(file_path)
import numpy as np
bgrLower = np.array([0, 100, 100]) #Untere Grenze der zu extrahierenden Farbe(BGR)
bgrUpper = np.array([250,250, 250])
if not cap.isOpened():
sys.exit()
while True:
ret, frame = cap.read()
if not ret:
break
frame = cv2.resize(frame, dsize=(600, 400))
img_mask = cv2.inRange(frame, bgrLower, bgrUpper)
contours, hierarchy = cv2.findContours(img_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours.sort(key=lambda x: cv2.contourArea(x), reverse=True)
#target_contour = max(contours, key=lambda x: cv2.contourArea(x))
#img_mask = cv2.line(img_mask, (250,300), (350,300), (120,120,120), 10) #Das zweite Argument ist der Startpunkt, das dritte Argument ist der Endpunkt, das vierte Argument ist die Farbe und das fünfte Argument ist die Linienstärke.
#img_mask=cv2.drawContours(img_mask,contours[0:2],-1,(120,120,120),5)
cv2.imshow(window_name, img_mask)
#cv2.imshow(window_name,img_mask, [contours[0],contours[1]])
if cv2.waitKey(delay) & 0xFF == ord('q'):
break
cv2.destroyWindow(window_name)
Ich konnte erfolgreich binarisieren.
Nun, das ist das Hauptthema. Definieren Sie zwischen den umschlossenen Bereichen wie unten gezeigt und ermitteln Sie den Abstand zwischen ihnen. Und ich möchte diesen Wert entsprechend ausgeben.
video.ipynb
contours, hierarchy = cv2.findContours(img_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)#Grenzzeichnung
contours.sort(key=lambda x: cv2.contourArea(x), reverse=True)#Grenzen sortieren
Schließen Sie den weißen Bereich mit der Methode cv2.findContours () ein. Der Rückgabewert wird in Konturen gespeichert. Sortieren Sie dann die Konturen nach Fläche.
video.ipynb
x1=np.unravel_index(np.argmax(contours[0],axis=0), contours[0].shape)
x2=np.unravel_index(np.argmax(contours[1],axis=0), contours[0].shape)
img_mask = cv2.line(img_mask, tuple(x1[0][0]), tuple(x2[0][0]), (120,120,120), 3)
Ruft die Koordinaten ab, die den Bereich umgeben. Gibt x1 und x2 mit argmax zurück, das den Maximalwert der Koordinaten in Konturen [0], [1] annimmt (der Wert, bei dem entweder x oder y das Maximum ist). Im Fall von argmax wird es auf eine Dimension abgeflacht (unabhängig von den x- und y-Koordinaten in einer Dimension bestimmt), sodass die Methode unravel_index () den Index als Koordinaten zurückgibt.
Durch tatsächliches Einfügen der Koordinaten mit der Methode cv2.line () werden die Koordinaten dann verbunden.
(Ergänzung) Verstehen Sie die in Konturen gespeicherten Zahlenwerte
Es ist so kompliziert.
Lassen Sie uns nun diesen berechneten Wert auf dem Bildschirm anzeigen. Normalerweise kann es mit der Methode cv2.putText () angezeigt werden. Wenn es jedoch unverändert bleibt, wird der Wert für jeden Frame berechnet und angezeigt. Dadurch wird der Wert flackernd und schwer zu erkennen. Als Gegenmaßnahme können Sie den Wert für jede bestimmte Anzahl von Frames aktualisieren und anzeigen. Das Folgende wird ausgeführt, damit der Wert in 30 Frames (in diesem Fall ungefähr jede Sekunde) unter Verwendung der if-Syntax aktualisiert wird.
video.ipynb
if idx % 30 == 0:
text =str(math.floor(np.linalg.norm(x1[0][0]-x2[0][0])))
cv2.putText(img_mask, text,(300, 100), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (255, 255, 255), thickness=3)
Hier ist das Ergebnis der Verarbeitung und Ausgabe auf diese Weise.
Ursprünglich wünschte ich mir, ich könnte Weiß oder Schwarz für jeden der beiden Bereiche Weiß und Schwarz einen Wert geben, aber ich könnte ihn nicht gut anpassen. Zusätzlich wurde eine Linie zwischen den Bereichen des Adapters gezogen, bei der es sich um den weißen Teil handelt (diesmal ist es eine Sache, aber er ist in zwei Bereiche unterteilt), und es war auch möglich, einen numerischen Wert auszugeben, der den Abstand angibt.
Nun, diesmal habe ich ein Programm erstellt, das während der Verarbeitung des Videos abgespielt werden soll. Der Punkt war, dass es nicht möglich war, eine schwere Verarbeitung durchzuführen, da diese Frame für Frame verarbeitet wurde. Ursprünglich wollte ich die kürzeste Entfernung zwischen Regionen finden und diese Entfernung subtrahieren, aber ich konnte sie nicht so oft implementieren. Da es viele Artikel gab, in denen OpenCV selbst in c ++ zusammengefasst war, fiel mir die Suche schwer. ..
Das Programm ist unten gespeichert. https://github.com/Fumio-eisan/movie_20200406
Recommended Posts