Pymecavideo 8.0
Étude cinématique à l'aide de vidéos
detect.py
1# -*- coding: utf-8 -*-
2"""
3 detect, a module for pymecavideo:
4 this module implements the automatic detection of moving objects.
5
6 Copyright (C) 2010 Jean-Baptiste Butet <ashashiwa@gmail.com>
7 Copyright (C) 2007-2023 Georges Khaznadar <georgesk.debian.org>
8
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.
13
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.
18
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/>.
21"""
22
23import os.path
24import tempfile
25import time
26
27import cv2
28import numpy as np
29
30from globdef import *
31from vecteur import vecteur
32
33
34# @time_it
35def filter_picture(part, image, zone_proche=None):
36 """
37 Trouve la position d'une image partielle dans une image donnée
38 @param part une images partielle (au format d'openCV)
39 @param image une image où chercher (même format)
40 @param zone_proche un vecteur près duquel pourrait bien se trouver
41 l'image recherchée ; peut être None, auquel cas on recherche dans
42 toute l'image (ACTUELLEMENT ON N'EN TIENT PAS COMPTE)
43 @return les coordonnées d'un point, résultant du suivi automatique
44 du motif partiel dans l'image.
45 """
46 point = detect_part(part, image, zone_proche) # TODO 130ms
47 return point
48
49# @time_it
50
51
52
53# @time_it
54def detect_part(part, image, point=None):
55 """
56 Détecte une image partielle dans une image complète
57 @param part l'image partielle, le motif à trouver
58 @param image l'image totale où l'on cherche le motif.
59 @param point s'il est défini, un point près duquel il est plus probable
60 de trouver ce qu'on cherche ; ce point est en haut à gauche de l'image
61 partielle
62 @return l'emplacement où se trouve le motif recherché
63 """
64 if point:
65 # on choisit un rayon assez petit par rapport à la taille de l'image
66 # afin de faire la première recherche dans un extrait de l'image
67 r = (image.shape[0]+image.shape[1]) // 10
68 centre = (point[0] + part.shape[0] // 2, point[1] + part.shape[1] // 2)
69 hg = (centre[0] - r, centre[1] - r) # haut gauche
70 bd = (centre[0] + r, centre[1] + r) # bas droite
71 extrait = image[hg[1]:bd[1], hg[0]:bd[0], :]
72 # on vérifie que l'extrait soit assez grand
73 if extrait.shape[0] > part.shape[0] and \
74 extrait.shape[1] > part.shape[1]:
75 matched = cv2.matchTemplate(extrait, part, cv2.TM_SQDIFF)
76 m, M, minloc, maxloc = cv2.minMaxLoc(matched)
77 # si le minimum `m` est assez bas, on considère qu'on a trouvé
78 tolerance = 120 * part.shape[0] * part.shape[1]
79 if m < tolerance:
80 return (minloc[0]+hg[0], minloc[1]+hg[1])
81
82 ####### si ça n'a pas marché on recherche dans toute l'image ########
83 matched = cv2.matchTemplate(image, part, cv2.TM_SQDIFF)
84 m, M, minloc, maxloc = cv2.minMaxLoc(matched)
85 return minloc