4 videoWidget, a module for pymecavideo:
5 a program to track moving points
in a video frameset
7 Copyright (C) 2007 Jean-Baptiste Butet <ashashiwa
@gmail.com>
8 Copyright (C) 2023 Georges Khaznadar <georgesk
@debian.org>
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.
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.
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/>.
24from PyQt6.QtCore import QThread, pyqtSignal, QLocale, QTranslator, Qt, \
25 QSize, QTimer, QObject, QRect, QPoint, QPointF
26from PyQt6.QtGui
import QKeySequence, QIcon, QPixmap, QImage, QPainter, \
27 QCursor, QPen, QColor, QFont, QResizeEvent, QShortcut
28from PyQt6.QtWidgets
import QApplication, QMainWindow, QWidget, QLayout, \
29 QFileDialog, QTableWidgetItem, QInputDialog, QLineEdit, QMessageBox, \
30 QTableWidgetSelectionRange
35from version
import Version
36from vecteur
import vecteur
37from echelle
import Echelle_TraceWidget
38from image_widget
import ImageWidget
39from globdef
import cible_icon, DOCUMENT_PATH, inhibe
40from cadreur
import openCvReader
41from toQimage
import toQImage
43import interfaces.icon_rc
47 Cette classe permet de gérer une séquence d'images extraites d'une vidéo
48 et les pointages qu
'on peut réaliser à la souris ou automatiquement,
49 pour suivre les mouvements d'un ou plusieurs objets.
52 def __init__(self, parent):
53 ImageWidget.__init__(self, parent)
54 self.setMouseTracking(
True)
60 self.setMouseTracking(
True)
62 "red",
"blue",
"cyan",
"magenta",
"yellow",
"gray",
"green"] *2
68 donne une vision partielle de l'instance courante
70 result = {a : str(getattr(self,a)) for a
in dir(self) \
71 if not callable(getattr(self,a))
and \
72 not isinstance(getattr(self,a), QObject)}
74 return f
"VideoPointeeWidget({result})"
78 Connecte le videoWidget au widget principal de son onglet,
79 et son débogueur ; self.pw devient un pointeur vers ce widget
80 @param w le widget principal de l
'onglet de pointage
90 def resizeEvent(self, e):
91 self.
dbg.p(2,
"rentre dans 'resizeEvent'")
92 self.
pw.update_imgedit.emit(
94 if e.oldSize() != QSize(-1, -1):
95 ratiow = self.width()/e.oldSize().width()
96 ratioh = self.height()/e.oldSize().height()
97 self.
pw.update_origine.emit(ratiow, ratioh)
102 enregistre le point de l'évènement souris, si self.pointageOK
103 est vrai ; voir self.extract_image pour voir les conditions
106 Si self.refait_point est vrai (on a été délégué depuis un
107 bouton refaire, du tableau de coordonnées, alors on rebascule
108 éventuellement vers l'onglet coordonnées, quand le dernier
111 if event.button() == Qt.MouseButton.LeftButton:
112 self.
pw.fin_pointage_manuel.emit(event)
115 def mouseMoveEvent(self, event):
116 self.
pw.update_zoom.emit(
vecteur(qPoint = event.position()))
119 def paintEvent(self, event):
130 5,
"In videoWidget, paintEvent, self.pw.data :%s" % self.
pw.data)
132 for date
in self.
pw.data:
133 for obj
in self.
pw.data[date]:
134 point = self.
pw.data[date][obj]
136 painter.setPen(QColor(self.
couleurs[int(obj)-1]))
137 painter.setFont(QFont(
"", 10))
138 painter.translate(point.x, point.y)
139 painter.drawLine(-2, 0, 2, 0)
140 painter.drawLine(0, -2, 0, 2)
141 painter.translate(-10, +10)
142 painter.drawText(0, 0, str(obj))
143 painter.translate(-point.x + 10, -point.y - 10)
147 painter.setPen(QColor(
"green"))
149 round(self.
pw.origine.x) + 5, round(self.
pw.origine.y) + 15,
"O")
150 painter.translate(0, 0)
151 painter.translate(round(self.
pw.origine.x), round(self.
pw.origine.y))
152 p1 = QPoint(round(self.
pw.sens_X * (-40)), 0)
153 p2 = QPoint(round(self.
pw.sens_X * (40)), 0)
154 p3 = QPoint(round(self.
pw.sens_X * (36)), 2)
155 p4 = QPoint(round(self.
pw.sens_X * (36)), -2)
157 painter.drawPolyline(p1, p2, p3, p4, p2)
158 painter.rotate(self.
pw.sens_X * self.
pw.sens_Y * (-90))
159 painter.drawPolyline(p1, p2, p3, p4, p2)
165 Crée l'en-tête du fichier pymecavideo
166 On recopie sous forme de commentaires préfixée par "# "
167 tout le fichier de configuration sauf la ligne
"[DEFAULT]"
168 puis on ajoute le message
169 @param msg le message
170 @return le texte de l
'en-tête (multi-ligne)
172 self.dbg.p(2, "rentre dans 'entete_fichier'")
173 config = open(self.
pw.prefs.conffile).readlines()
174 return "".join([
"# "+l
for l
in config[1:]]) +
"# " + msg +
"\n"
178 place une image dans le widget, en conservant le ratio de cette image
180 @param ratio le ratio à respecter
181 @param largeurFilm la largeur originale de la video en pixel
182 @return l
'image, redimensionnée selon le ratio
184 self.dbg.p(2, "rentre dans 'placeImage'")
185 self.
image_w = min(self.width(), round(self.height() * ratio))
188 self.setMouseTracking(
True)
une classe pour des vecteurs 2D ; les coordonnées sont flottantes, et on peut accéder à celles-ci par...