Même si je travaille dans le département non informatique de l'industrie manufacturière, je suis venu travailler avec une conscience de l'IA et de l'IoT. Je travaille à proximité du poste de technologie de production, qui est proche du site de fabrication, mais l'un des problèmes de la systématisation est qu'elle n'est pas équilibrée avec le profit de l'usine. Il y a quelque chose que je veux faire, mais si je l'estime, le coût d'introduction sera élevé (les coûts de main-d'œuvre sont souvent élevés ...) et je risque d'abandonner. Par conséquent, le contenu suivant est ce que je pense qu'il est bon de le faire du point de vue de l'amélioration des compétences.
Nous visons à effectuer un traitement en temps réel (binarisation, calcul / affichage d'une certaine distance, etc.) sur la vidéo enregistrée utilisée sur le site de fabrication et à afficher le résultat. Étonnamment, il peut aider les travailleurs sur site à produire facilement des images vidéo traitées, même simples.
Eh bien, cela fait longtemps, mais les grandes lignes de cette période sont les suivantes.
L'article précédent est ici.
Rendre l'image binarisée. De plus, la distance la plus courte entre deux régions peut être calculée (Ver1.1). https://qiita.com/Fumio-eisan/items/10c54af7a925b403f59f
Tout d'abord, effectuez le processus d'affichage de la vidéo. Cette fois, nous traiterons la vidéo avec la capture suivante pendant environ 7 secondes.
video.ipynb
#Afficher simplement
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: #Si vous insérez ces deux lignes, cela se terminera par une lecture vidéo.
# 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)
C'est OK si vous décrivez le chemin de la vidéo que vous souhaitez afficher dans file_path. Dans le cas de ce programme, la vidéo continuera à jouer dans une boucle infinie. Vous pouvez arrêter la lecture vidéo en appuyant sur la touche q.
Concernant l'affichage de la vidéo, nous tournons selon la procédure suivante.
Il est devenu. J'écrirai une note plus tard, mais comme elle est traitée pour chaque image en 3., vous devez être prudent si vous voulez changer le telop (valeur à afficher, etc.) que vous souhaitez afficher toutes les secondes ou toutes les quelques secondes.
video.ipynb
cv2.putText(frame, text,(100, 30), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 255, 0), thickness=2)
La sortie des sous-titres est possible grâce à cet affichage. Les arguments sont les suivants. 1er argument: image vidéo, 2ème argument: texte à afficher, 3ème argument: position x, y, 4ème argument: police, 5ème argument: taille des caractères, 6ème argument: informations de couleur BGR, 7ème argument : Epaisseur des lettres
Maintenant, binarisons-le et affichons-le en noir et blanc. La méthode est OK si vous définissez les limites supérieure et inférieure de la couleur à extraire comme l'image et la définissez avec la méthode cv2.inRange ().
video.ipynb
#Processus de binarisation
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]) #Limite inférieure de couleur à extraire(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) #Le deuxième argument est le point de départ, le troisième argument est le point final, le quatrième argument est la couleur et le cinquième argument est l'épaisseur de la ligne.
#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)
J'ai réussi à binariser avec succès.
Eh bien, c'est le sujet principal. Définissez entre les zones fermées comme indiqué ci-dessous et trouvez la distance qui les sépare. Et je voudrais afficher cette valeur le cas échéant.
video.ipynb
contours, hierarchy = cv2.findContours(img_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)#Dessin des limites
contours.sort(key=lambda x: cv2.contourArea(x), reverse=True)#Trier les limites
Entourez la zone blanche avec la méthode cv2.findContours (). La valeur de retour est stockée dans les contours. Triez ensuite les contours par zone.
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)
Obtient les coordonnées entourant la zone. Renvoie x1 et x2 avec argmax, qui prend la valeur maximale des coordonnées dans les contours [0], [1](la valeur où x ou y est le maximum). Dans le cas de argmax, il est aplati à une dimension (déterminée dans une dimension indépendamment des coordonnées x et y), donc la méthode unravel_index () renvoie l'index sous forme de coordonnées.
Ensuite, insérez réellement les coordonnées avec la méthode cv2.line () pour connecter les coordonnées.
(Supplément) Comprendre les valeurs numériques stockées dans les contours
C'est compliqué comme ça.
Maintenant, affichons cette valeur calculée à l'écran. Normalement, il peut être affiché par la méthode cv2.putText (). Cependant, si elle est laissée telle quelle, la valeur de chaque image sera calculée et affichée. Cela rendra la valeur vacillante et difficile à voir. En guise de contre-mesure, vous pouvez mettre à jour la valeur à chaque certain nombre d'images et l'afficher. Ce qui suit est effectué pour que la valeur soit mise à jour dans 30 images (environ toutes les secondes dans ce cas) en utilisant la syntaxe if.
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)
Voici le résultat du traitement et de la sortie de cette manière.
À l'origine, j'aurais aimé pouvoir donner une valeur au blanc ou au noir pour chacune des deux zones du blanc et du noir, mais je ne pouvais pas bien l'ajuster. De plus, une ligne a été tracée entre les zones de l'adaptateur, qui est la partie blanche (cette fois, c'est une chose, mais elle est divisée en deux zones), et il était également possible de sortir une valeur numérique indiquant la distance.
Eh bien, cette fois, j'ai créé un programme à lire pendant le traitement de la vidéo. Le fait était qu'il n'était pas possible d'effectuer un traitement lourd car il était traité image par image. À l'origine, je voulais trouver la distance la plus courte entre les régions et soustraire cette distance, mais je ne pouvais pas vraiment l'implémenter. De plus, il y avait de nombreux articles dans lesquels OpenCV lui-même était résumé en c ++, j'ai donc eu du mal à chercher. ..
Le programme est stocké ci-dessous. https://github.com/Fumio-eisan/movie_20200406