Pymecavideo 8.0
Étude cinématique à l'aide de vidéos
echelle.py
1# -*- coding: utf-8 -*-
2"""
3 echelle, a module for pymecavideo:
4 a program to track moving points in a video frameset
5
6 Copyright (C) 2007 Jean-Baptiste Butet <ashashiwa@gmail.com>
7
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20"""
21
22from math import sqrt
23import os
24
25from PyQt6.QtCore import QThread, pyqtSignal, QLocale, QTranslator, Qt, QSize, QTimer, QObject, QRect
26from PyQt6.QtGui import QKeySequence, QIcon, QPixmap, QImage, QPainter, QShortcut, QColor, QCursor
27from PyQt6.QtWidgets import QApplication, QMainWindow, QWidget, QLayout, QFileDialog, QTableWidgetItem, QInputDialog, QLineEdit, QMessageBox, QTableWidgetSelectionRange
28
29from vecteur import vecteur
30from globdef import cible_icon
31
32class echelle(QObject):
33 def __init__(self, p1=vecteur(0, 0), p2=vecteur(0, 0)):
34 self.p1, self.p2 = p1, p2
36 # si les deux points sont distincts, l'échelle est faite
37 return
38
39 def __str__(self):
40 """
41 donne une vision partielle de l'instance courante
42 """
43 return f"echelle(p1 = {self.p1}, p2 = {self.p2}, longueur_reelle_etalon = {self.longueur_reelle_etalon})"
44
45 def __bool__(self):
46 """
47 @return vrai si l'échelle a été faite
48 """
49 return self.p1 != self.p2 and (self.p1 - self.p2).norme > 1
50
51 def __str__(self):
52 return "echelle(%s,%s,%s m)" % (self.p1, self.p2, self.longueur_reelle_etalon)
53
54 def longueur_pixel_etalon(self):
55 return (self.p1 - self.p2).norme
56
57 def isUndef(self):
58 """
59 Vrai si l'échelle n'est pas définie, c'est à dire si
60 p1 et p2 sont confondus.
61 """
62 return not self
63
64 def mParPx(self):
65 """renvoie le nombre de mètre par pixel"""
66 if not self.isUndef():
68 else:
69 return 1
70
71 def pxParM(self):
72 """renvoie le nombre de pixel par mètre"""
73 if not self.isUndef():
75 else:
76 return 1
77
78 def etalonneReel(self, l):
79 """
80 Définit la longueur en mètre de l'étalon
81 @param l longueur en mètre
82 """
83 self.longueur_reelle_etalon = float(l)
84 return
85
86
87class EchelleWidget(QWidget):
88 """
89 Widget qui permet de définir l'échelles
90
91 Paramètres du constructeur :
92 @param parent le widget video
93 @param pw widget principal de l'onglet pointage
94 @param app pointeur vers l'application
95
96 Propiétés
97 @prop self.p1 vecteur
98 @prop self.p2 vecteur
99 ...
100 """
101 def __init__(self, parent, pw):
102 QWidget.__init__(self, parent)
103 self.app = pw.app # la fenêtre principale
104 self.video = parent # l'afficheur de vidéo
105 self.pw = pw # le widget de l'onglet de pointage
106 self.image=None
107 self.setGeometry(
108 QRect(0, 0, self.video.image_w, self.video.image_h))
109 self.largeur = self.video.image_w
110 self.hauteur = self.video.image_h
111 self.setAutoFillBackground(False)
112 self.p1 = vecteur()
113 self.p2 = vecteur()
114 self.pos_echelle = vecteur()
115 cible_pix = QPixmap(cible_icon).scaledToHeight(32)
116 cible_cursor = QCursor(cible_pix)
117 self.setCursor(cible_cursor)
118 self.cropX2 = None
119 self.setMouseTracking(True)
120 self.pressed = False
121 return
122
123 def paintEvent(self, event):
124 if self.p1.x <= 0 or self.p2.x <= 0: return
125 painter = QPainter()
126 painter.begin(self)
127
128 painter.setPen(QColor("red"))
129 painter.drawLine(round(self.p1.x), round(self.p1.y),
130 round(self.p2.x), round(self.p2.y))
131 painter.end()
132 return
133
134 def mousePressEvent(self, event):
135 if event.button() != Qt.MouseButton.LeftButton:
136 self.p1 = vecteur(-1, -1)
137 self.close()
138 self.p1 = vecteur(qPoint = event.position())
139 self.pressed = True
140 return
141
142 def mouseMoveEvent(self, event):
143 p = vecteur(qPoint = event.position())
144 self.pw.update_zoom.emit(p)
145 if self.pressed:
146 self.p2 = p
147 self.update()
148 return
149
150 def mouseReleaseEvent(self, event):
151 p = vecteur(qPoint = event.position())
152 self.pressed = False
153 if event.button() == Qt.MouseButton.LeftButton and self.p1.x >= 0:
154 self.p2 = p
155 self.pw.echelle_image.p1 = self.p1.copy()
156 self.pw.echelle_image.p2 = self.p2.copy()
157
158 self.pw.affiche_echelle()
159 self.app.affiche_statut.emit(self.tr("Échelle définie"))
160 self.pw.echelle_modif.emit(self.tr("Refaire l'échelle"), "background-color:orange;")
161 self.pw.index_du_point = 0
162
163 self.pw.feedbackEchelle()
164 self.app.stopRedimensionnement.emit()
165 if self.pw.data: # si on a déjà pointé une position au moins
166 self.app.affiche_statut.emit(self.tr(
167 "Vous pouvez continuer votre acquisition"))
168 self.app.coord.recalculLesCoordonnees()
169
170 self.close()
171 self.pw.apres_echelle.emit()
172 return
173
174class Echelle_TraceWidget(QWidget):
175 """
176 Un widget transparent qui sert seulement à tracer l'échelle
177
178 Paramètres du constructeur :
179 @param parent un videoWidget
180 @param p1 origine de l'étalon
181 @param p2 extrémité de l'étalon
182 """
183 def __init__(self, parent, p1, p2):
184 QWidget.__init__(self, parent)
185 self.video = parent
186 self.image = None
187 self.setGeometry(
188 QRect(0, 0, self.video.image_w, self.video.image_h))
189 self.setAutoFillBackground(False)
190 self.p1 = p1
191 self.p2 = p2
192 self.setMouseTracking(True)
193
194 def maj(self):
195 self.setGeometry(
196 QRect(0, 0, self.video.image_w, self.video.image_h))
197
198 def paintEvent(self, event):
199 if self.p1.x <= 0 or self.p2.x <= 0: return
200
201 painter = QPainter()
202 painter.begin(self)
203 painter.setPen(QColor("green"))
204 painter.drawLine(round(self.p1.x), round(self.p1.y),
205 round(self.p2.x), round(self.p2.y))
206 painter.end()
207 return
Widget qui permet de définir l'échelles.
Definition: echelle.py:100
Un widget transparent qui sert seulement à tracer l'échelle.
Definition: echelle.py:182
def pxParM(self)
renvoie le nombre de pixel par mètre
Definition: echelle.py:72
def longueur_pixel_etalon(self)
Definition: echelle.py:54
def etalonneReel(self, l)
Définit la longueur en mètre de l'étalon.
Definition: echelle.py:82
def __str__(self)
donne une vision partielle de l'instance courante
Definition: echelle.py:42
def mParPx(self)
renvoie le nombre de mètre par pixel
Definition: echelle.py:65
def isUndef(self)
Vrai si l'échelle n'est pas définie, c'est à dire si p1 et p2 sont confondus.
Definition: echelle.py:61
def __bool__(self)
Definition: echelle.py:48
une classe pour des vecteurs 2D ; les coordonnées sont flottantes, et on peut accéder à celles-ci par...
Definition: vecteur.py:44