Pymecavideo 8.0
Étude cinématique à l'aide de vidéos
suivi_auto.py
1# -*- coding: utf-8 -*-
2
3"""
4 suivi_auto, a module for pymecavideo:
5 a program to track moving points in a video frameset
6
7 Copyright (C) 2007 Jean-Baptiste Butet <ashashiwa@gmail.com>
8 Copyright (C) 2023 Georges Khaznadar <georgesk@debian.org>
9
10 This program is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
22"""
23
24from PyQt6.QtCore import QThread, pyqtSignal, QLocale, QTranslator, Qt, QSize, QTimer, QObject, QRect, QPoint, QPointF
25from PyQt6.QtGui import QKeySequence, QIcon, QPixmap, QImage, QPainter, QPen, QColor, QShortcut, QCursor
26from PyQt6.QtWidgets import QApplication, QMainWindow, QWidget, QLayout, QFileDialog, QTableWidgetItem, QInputDialog, QLineEdit, QMessageBox, QTableWidgetSelectionRange
27
28from vecteur import vecteur
29from globdef import cible_icon
30
31import os.path
32
33class MonRect:
34 def __init__(self, x1 = None, y1 = None, x2 = None, y2 = None):
35 self.x1 = x1
36 self.y1 = y1
37 self.x2 = x2
38 self.y2 = y2
39 return
40
41 def coords(self):
42 return self.x1, self.y1, self.x2, self.y2
43
44 def paint(self, painter):
45 """
46 méthode de dessin
47 @param painter un QPainter actif
48 """
49 # trace un rectangle
50 painter.drawRect(round(self.x1), round(self.y1),
51 round(self.x2 - self.x1),
52 round(self.y2 - self.y1))
53 # puis trace les diagonales
54 painter.drawLine(round(self.x1), round(self.y1),round(self.x2), round(self.y2))
55 painter.drawLine(round(self.x1), round(self.y2),round(self.x2), round(self.y1))
56 return
57
58
59class SelRectWidget(QWidget):
60 """
61 Sert au retour visuel quand l'utilisateur doit sélectionner une
62 zone rectangulaire pour le suivi automatique
63
64 paramètres du constructeur:
65 @param parent le widget parent, qui est un videoWidget
66 @param pw un poitageWidget
67 """
68 def __init__(self, parent, pw):
69 """make a rectangle near point to be tracked"""
70 QWidget.__init__(self, parent)
71 self.video = parent
72 self.pw = pw
73 self.echelle = self.video.image_w/pw.largeurFilm
74 self.setGeometry(
75 QRect(0, 0, self.video.image_w, self.video.image_h))
76 self.setAutoFillBackground(False)
77 cible_pix = QPixmap(cible_icon).scaledToHeight(32)
78 cible_cursor = QCursor(cible_pix)
79 self.setCursor(cible_cursor)
80 self.setMouseTracking(True)
81 self.rects = []
82 self.dragging = False
83 return
84
85 def mousePressEvent(self, event):
86 p = vecteur(qPoint = event.position())
87 self.rects.append(MonRect(p.x, p.y, p.x, p.y))
88 self.dragging = True
89 self.update()
90 return
91
92 def mouseMoveEvent(self, event):
93 p = vecteur(qPoint = event.position())
94 self.pw.update_zoom.emit(p)
95
96 if self.dragging:
97 self.rects[-1].x2 = p.x
98 self.rects[-1].y2 = p.y
99 self.update()
100 return
101
102 def mouseReleaseEvent(self, event):
103 self.dragging = False
104 self.pw.motifs_auto.append(self.getMotif())
105 self.pw.selection_motif_done.emit()
106 self.update()
107 return
108
109 def getMotif(self):
110 """
111 récupère le motif qui servira à la reconnaissance automatique
112 sur les images successives.
113 @result un morceau d'image au format openCV, directement tiré du film
114 """
115 # on a un rectangle délimité par un pointage sur le videoWidget
116 # qui a pu être redimensionné ; il faut en déduire un rectangle
117 # dans l'image vidéo originale, d'où la division par self.echelle
118 x1, y1, x2, y2 = self.rects[-1].coords()
119 x = round(min(x1, x2) / self.echelle)
120 y = round(min(y1, y2) / self.echelle)
121 w = round(abs(x2-x1) / self.echelle)
122 h = round(abs(y2-y1) / self.echelle)
123 # on récupère la bonne image du film et on la découpe
124 ok, image_opencv = self.pw.cvReader.getImage(
125 self.pw.index, self.video.rotation, rgb=False)
126 return image_opencv[y:y+h,x:x+w]
127
128 def paintEvent(self, event):
129 if self.rects:
130 painter = QPainter()
131 painter.begin(self)
132 for rect in self.rects[:-1]:
133 painter.setPen(QColor("red"))
134 rect.paint(painter)
135 painter.setPen(QColor("green"))
136 self.rects[-1].paint(painter)
137 painter.end()
138 return
def paint(self, painter)
méthode de dessin
Definition: suivi_auto.py:48
Sert au retour visuel quand l'utilisateur doit sélectionner une zone rectangulaire pour le suivi auto...
Definition: suivi_auto.py:67
def __init__(self, parent, pw)
make a rectangle near point to be tracked
Definition: suivi_auto.py:69
def getMotif(self)
récupère le motif qui servira à la reconnaissance automatique sur les images successives.
Definition: suivi_auto.py:114
une classe pour des vecteurs 2D ; les coordonnées sont flottantes, et on peut accéder à celles-ci par...
Definition: vecteur.py:44