3 trajWidget, a module for pymecavideo:
4 a program to track moving points
in a video frameset
6 Copyright (C) 2007 Jean-Baptiste Butet <ashashiwa
@gmail.com>
7 Copyright (C) 2022 Georges Khaznadar <georgesk
@debian.org>
9 This program
is free software: you can redistribute it
and/
or modify
10 it under the terms of the GNU General Public License
as published by
11 the Free Software Foundation, either version 3 of the License,
or
12 (at your option) any later version.
14 This program
is distributed
in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License
for more details.
19 You should have received a copy of the GNU General Public License
20 along
with this program. If
not, see <http://www.gnu.org/licenses/>.
22from math import sqrt, atan2, degrees
24from PyQt6.QtCore import QThread, pyqtSignal, QLocale, QTranslator, Qt, QSize, QTimer, QRect, QPoint, QPointF
25from PyQt6.QtGui import QKeySequence, QIcon, QPixmap, QImage, QPicture, QPainter, QColor, QFont, QPainterPath, QPen, QFontMetrics, QShortcut
26from PyQt6.QtWidgets import QApplication, QMainWindow, QWidget, QLayout, QFileDialog, QTableWidgetItem, QInputDialog, QLineEdit, QMessageBox, QTableWidgetSelectionRange
28from image_widget import ImageWidget
29from vecteur import vecteur
30from globdef import pattern_float
32class trajWidget(ImageWidget):
34 Classe pour l'élément qui remplit l'essentiel de l
'onglet trajectoire
35 paramètres du constructeur :
37 @param parent un des layouts de l
'onglet
39 def __init__(self, parent):
40 ImageWidget.__init__(self, parent)
43 self.setCursor(Qt.CursorShape.ArrowCursor)
44 self.setAutoFillBackground(
True)
45 self.
couleurs = [
"red",
"blue",
"cyan",
"magenta",
"yellow",
"gray",
"green",
"red",
"blue",
"cyan",
"magenta",
46 "yellow",
"gray",
"green"]
47 self.setMouseTracking(
True)
61 def prepare_vecteurs_pour_paint(self):
62 if self.trajectoire.checkBoxVectorSpeed.isChecked():
63 vitesse = self.trajectoire.checkBoxScale.currentText().replace(
65 if not pattern_float.match(vitesse):
return
66 self.
speedToDraw = self.pointage.vecteursVitesse(float(vitesse))
69 def mouseMoveEvent(self, event):
72 if self.trajectoire.radioButtonNearMouse.isChecked():
77 color = QColor(
"white"), bgcolor = QColor(
"lightGray"),
82 Trace un texte (self.painter doit être actif !)
85 @param text le teste à tracer
86 @param color couleur de texte (defaut : Qt.white)
87 @param bgcolor couleur de fond (par défaut : Qt.lightGray) ;
88 peut être
None pour pas de fond
89 @param fontsize taille de police (par défaut : 12)
90 @param fontfamily famille de police (par défaut:
None)
91 @param center (faux par défaut) centrage horizontal demandé
94 font = QFont(fontfamily, fontsize, weight = 700)
97 font.setPointSize(fontsize)
99 font_metrics = QFontMetrics(font)
100 r = font_metrics.boundingRect(text)
101 text_width = r.width()
102 text_height = r.height()
104 offset_x = 0
if center ==
False else text_width // 2
108 x-5-offset_x, y-text_height-5,
109 text_width+10, text_height+10)
110 self.
painter.drawText(x-offset_x, y, text)
116 self.
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
119 couleur_de_fond = QColor(
"white")
121 couleur_de_fond = QColor(
"grey")
124 QRect(0, 0, self.video.image_w, self.video.image_h), couleur_de_fond)
129 self.
painter.setPen(QColor(
"green"))
146 self.
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
151 text = f
"Δt = {self.pointage.deltaT:.3f} s"
152 self.
paintText(self.width() - x1 - 100, y1, text)
153 text = f
"t = {self.pointage.deltaT*(self.trajectoire.spinBox_chrono.value()-1):.3f} s"
154 self.
paintText(self.width() - x1 - 100, 2 * y1, text)
157 self.
painter.setPen(QColor(
"black"))
158 if self.pointage.echelle_image :
159 longueur = round((self.pointage.echelle_image.p1 - self.pointage.echelle_image.p2).norme)
160 self.
painter.drawLine(x1, y1-10, x1, y1+10)
161 self.
painter.drawLine(x1, y1, longueur+x1, y1)
162 self.
painter.drawLine(longueur+x1, y1-10, longueur+x1, y1+10)
163 text =
"d = {0:.2e} m".format(self.pointage.echelle_image.longueur_reelle_etalon)
165 max(x1+round(longueur/2), 0), y1+30,
167 color = QColor(
"black"),
174 "échelle non précisée",
175 color = QColor(
"black"),
184 self.
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
185 pen = QPen(QColor(
"blue"))
188 if self.pointage.echelle:
190 round(self.pointage.echelle_trace.p1.x),
191 round(self.pointage.echelle_trace.p1.y),
192 round(self.pointage.echelle_trace.p2.x),
193 round(self.pointage.echelle_trace.p2.y))
195 echelle =
"d = {0:.2e} m".format(
196 self.pointage.echelle_image.longueur_reelle_etalon)
199 round(self.pointage.echelle_trace.p1.x),
200 round((self.pointage.echelle_trace.p1.y + self.pointage.echelle_trace.p2.y)/2)+20,
204 fontfamily =
"Times",
208 self.
paintText(x1, y1+20,
"échelle non précisée",
209 color = QColor(
"blue"),
211 fontfamily =
"Times",
222 self.
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
225 data = self.pointage.data
226 def cb_point(i, t, j, obj, p, v):
228 fonction de rappel pour usage avec iteration_data du videoWidget
235 self.
painter.setFont(QFont(
"", 10))
237 round(p.x + self.
origine.x - obj_reference.x),
238 round(p.y + self.
origine.y - obj_reference.y))
240 self.
painter.setPen(QColor(
"black"))
241 self.
painter.drawLine(-4, 0, 4, 0)
242 self.
painter.drawLine(0, -4, 0, 4)
243 self.
painter.translate(-10, +10)
247 self.
painter.drawText(decal, 5,
"M"+
"'"*j+str(i))
250 self.
painter.drawLine(-2, 0, 2, 0)
251 self.
painter.drawLine(0, -2, 0, 2)
252 self.
painter.translate(-10, +10)
253 self.
painter.drawText(0, 0, str(j + 1))
255 round(-p.x - self.
origine.x + obj_reference.x) + 10,
256 round(-p.y - self.
origine.y + obj_reference.y) - 10)
259 self.pointage.iteration_data(
None, cb_point)
266 self.
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
267 self.
painter.setPen(QColor(
"green"))
271 p1 = QPoint(round(self.pointage.sens_X * (-40)), 0)
272 p2 = QPoint(round(self.pointage.sens_X * (40)), 0)
273 p3 = QPoint(round(self.pointage.sens_X * (36)), 2)
274 p4 = QPoint(round(self.pointage.sens_X * (36)), -2)
276 self.
painter.drawPolyline(p1, p2, p3, p4, p2)
277 self.
painter.rotate(self.pointage.sens_X *
278 self.pointage.sens_Y * (-90))
279 self.
painter.drawPolyline(p1, p2, p3, p4, p2)
280 self.
painter.rotate(self.pointage.sens_X *
281 self.pointage.sens_Y * (90))
289 self.trajectoire.checkBoxVectorSpeed.isChecked():
292 if org == ext:
continue
297 if self.trajectoire.radioButtonNearMouse.isChecked():
299 if ecart.manhattanLength() > 20:
continue
302 self.
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
303 self.
painter.setPen(QColor(self.video.couleurs[int(obj) - 1]))
306 p1 = ext - vec * 0.1 + ortho * 0.05
307 p2 = p1 - ortho * 0.1
une classe pour des vecteurs 2D ; les coordonnées sont flottantes, et on peut accéder à celles-ci par...