LaboratoireMecaniqueLille / crappy

Command and Real-time Acquisition Parallelized in Python
https://crappy.readthedocs.io/en/stable/
GNU General Public License v2.0
78 stars 16 forks source link

nom des fichiers images #98

Closed rian44s closed 6 months ago

rian44s commented 6 months ago

Bonjour Antoine,

Lorsque j'utilise le block crappy.blocks.Camera('CameraGstreamer'), le nom utilisé automatiquement pour l'enregistrement des images est quelque chose comme: (%i_%f, nb_image,t(s))

serait-il possible d'avoir quelque chose comme:

(image_%4.4d, nb_image), e.g. image_0001.tiff afin d'avoir un padding de zero devant les numéros images et enlever le temps. C'est problématique pour nos routines de corrélation d'image.

Par ailleurs ou puis-je trouver les blocks permettant de faire automatiquement une interpolation de la force, du temps ou autre, aux pas de temps images ?

Merci d'avance, Rian

WeisLeDocto commented 6 months ago

Bonjour Rian,

serait-il possible d'avoir quelque chose comme: (image_%4.4d, nb_image), e.g. image_0001.tiff

On m'a déjà remonté ce problème, il sera réglé dans la prochaine release de Crappy (2.0.5). Le format envisagé est le suivant (en notation f-string): f'{nr:06d}_{t:.3f}.tiff'. L'information temporelle est importante pour les essais où l'acqusition d'images ne se fait pas à intervalles réguliers, et où deux images consécutives peuvent être distantes dans les temps.

Dans la version 2.0, j'ai supprimé la possibilité pour les utilisateurs de choisir le nom des images (possibilité présente en 1.5). Je ne pense pas la rétablir tel qu'elle existait (l'utilisateur fournit une str formattée). Eventuellement, la possibilité pour l'utilisateur de renseigner une fonction (qu'il crée lui-même) prenant en entrée le temps et l'index et retournant la str dans le format souhaité est envisageable. Je pensais garder ça pour un futur Camera Block plus avancé (todo #61), le Camera Block actuel de base a déjà beaucoup d'options.

Tu peux utiliser ce code pour renommer tes images en attendant :

```python # coding: utf-8 from pathlib import Path from shutil import move import argparse from re import fullmatch if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument('src', type=Path, nargs=1) parser.add_argument('dst', type=Path, nargs=1) args = parser.parse_args() source = args.src[0] destination = args.dst[0] for img in source.glob('*.tiff'): i, = fullmatch(r'(\d+)_\d+\.\d+\.tiff', img.name).groups() move(img, img.parent / f'image_{int(i):04d}.tiff') ``` Usage (le dossier source peut être le même que destination): ```bash python rename.py chemin_du_dossier_source chemin_du_dossier_destination ```


Par ailleurs ou puis-je trouver les blocks permettant de faire automatiquement une interpolation de la force, du temps ou autre, aux pas de temps images ?

Je n'avais jamais envisagé ce besoin auparavant, c'est vrai que ce serait pas mal. Habituellement, le Block Multiplexer permet de synchroniser plusieurs signaux dans une même base de temps. Ca fonctionne si le traitement d'images est effectué par Crappy, puisqu'il y a des valeurs de sortie à synchroniser. Mais dans le cas du Camera Block de base qui ne fait qu'acquérir des images il n'y a pas de sortie.

C'est toujours possible de régler le Block Multiplexer pour interpoler les valeurs de force etc. à la même fréquence que l'acquisition d'images, mais il n'y aura pas de synchronisation avec l'acquisition à proprement parler. Seules les fréquences seront identiques, avec un déphasage possible. D'ailleurs quelle est la fréquence cible pour l'acquisition des images ? Ca joue beaucoup sur la possibilité même de faire quoi que ce soit de "synchronisé" en Python.

rian44s commented 6 months ago

Bonjour,

Merci beaucoup pour ton bout de code. Ca fonctionne parfaitement.

Pour le multiplexer, je ne cherche pas une synchro a proprement parlé. SI j'ai bien compris:

Si je devais le faire moi même je ferais:

from scipy import interpolate

Interpolator_F= interpolate.interp1d(t_F, F,kind='linear') Interpolator_Pos= interpolate.interp1d(t_Pos, Pos,kind='linear') Fi = Interpolator_F(t_Image) Posi = Interpolator_Pos(t_Image) save-> asci (Fi, posi, image_name)

Donc si votre block multiplexer le fait je suis preneur sinon je fais moi meme en post traitement. Ca permet juste in fine, si je fais de la corrélation de tracer facilement F(t) vs Epsilon(t) Tu en penses quoi ?

Bonne journée,

Rian

On 22/02/2024 00:21, Antoine Weisrock wrote:

Bonjour Rian,

serait-il possible d'avoir quelque chose comme:
(image_%4.4d, nb_image), e.g. image_0001.tiff

On m'a déjà remonté ce problème, il sera réglé dans la prochaine release de Crappy (2.0.5). Le format envisagé est le suivant (en notation f-string): |f'{nr:06d}_{t:.3f}.tiff'|. L'information temporelle est importante pour les essais où l'acqusition d'images ne se fait pas à intervalles réguliers, et où deux images consécutives peuvent être distantes dans les temps.

Dans la version 2.0, j'ai supprimé la possibilité pour les utilisateurs de choisir le nom des images (possibilité présente en 1.5 https://github.com/LaboratoireMecaniqueLille/crappy/blob/95ca19e74ebfcfe1cf4b697e7059a19e6d520b03/crappy/blocks/camera.py#L58). Je ne pense pas la rétablir tel qu'elle existait (l'utilisateur fournit une |str| formattée). Eventuellement, la possibilité pour l'utilisateur de renseigner une fonction (qu'il crée lui-même) prenant en entrée le temps et l'index et retournant la |str| dans le format souhaité est envisageable. Je pensais garder ça pour un futur |Camera Block| plus avancé (todo #61 https://github.com/LaboratoireMecaniqueLille/crappy/issues/61), le |Camera Block| actuel de base a déjà beaucoup d'options.

Tu peux utiliser ce code pour renommer tes images en attendant :

coding: utf-8

from pathlib import Path from shutil import move import argparse from re import fullmatch

if name == "main":

 parser  =  argparse.ArgumentParser()
 parser.add_argument('src',type=Path,nargs=1)
 parser.add_argument('dst',type=Path,nargs=1)
 args  =  parser.parse_args()

 source  =  args.src[0]
 destination  =  args.dst[0]

 for  img  in  source.glob('*.tiff'):
     i,=  fullmatch(r'(\d+)_\d+\.\d+\.tiff',img.name).groups()
     move(img,img.parent  /  f'image_{int(i):04d}.tiff')

Usage (le dossier source peut être le même que destination):

python rename.py chemin_du_dossier_source chemin_du_dossier_destination

Par ailleurs ou puis-je trouver les blocks permettant de faire
automatiquement une interpolation de la force, du temps ou autre,
aux pas de temps images ?

Je n'avais jamais envisagé ce besoin auparavant, c'est vrai que ce serait pas mal. Habituellement, le Block |Multiplexer| https://crappy.readthedocs.io/en/stable/crappy_docs/blocks.html#multiplexer permet de synchroniser plusieurs signaux dans une même base de temps. Ca fonctionne si le traitement d'images est effectué par Crappy, puisqu'il y a des valeurs de sortie à synchroniser. Mais dans le cas du |Camera Block| de base qui ne fait qu'acquérir des images il n'y a pas de sortie.

C'est toujours possible de régler le Block |Multiplexer| pour interpoler les valeurs de force etc. à la même fréquence que l'acquisition d'images, mais il n'y aura pas de synchronisation avec l'acquisition à proprement parler. Seules les fréquences seront identiques, avec un déphasage possible. D'ailleurs quelle est la fréquence cible ppur l'acquisition des images ? Ca joue beaucoup sur la possibilité même de faire quoi que ce soit de "synchronisé" en Python.

— Reply to this email directly, view it on GitHub https://github.com/LaboratoireMecaniqueLille/crappy/issues/98#issuecomment-1958306403, or unsubscribe https://github.com/notifications/unsubscribe-auth/ASUMVRVRMXN3GAKXNLUTQS3YUZ6QLAVCNFSM6AAAAABDT2ZMCGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSNJYGMYDMNBQGM. You are receiving this because you authored the thread.Message ID: @.***>

-- Email Signature Logo https://www.cnrs.fr/fr/page-daccueil Logo https://gem.ec-nantes.fr/ Logo https://www.ec-nantes.fr/ Logo https://www.univ-nantes.fr/
Rian SEGHIR | Chargé de Recherche CNRS

+332 40 37 1669 @.*** <mailto:{email}> Nantes Université, Ecole Centrale Nantes, CNRS, GeM, UMR 6183 1 Rue de la Noë, 44300 Nantes LinkedIn icon https://www.linkedin.com/in/rian-seghir-082b48102/ ReasearchGate icon https://scholar.google.com/citations?hl=fr&user=xh9n0PsAAAAJ Orcid icon https://orcid.org/0000-0002-2946-0161

WeisLeDocto commented 6 months ago

Le Block Multiplexer tel qu'il existe actuellement donne la même importance à tous les labels à interpoler, et les interpole à une fréquence prédéfinie indépendemment de la fréquence d'acquisition réelle de chaque label.

Ce que toi tu voudrais c'est un équivalent mais qui prend un label comme référence, et interpole tous les autres sur la base de temps du label de référence. Ce n'est pas possible en l'état.

Ce n'est pas difficile à implémenter, et je trouve l'idée intéressante et utile. Je pense que ça mérite un autre Block, intégrer ça en option dans le Multiplexer risque de ne pas être clair. Une idée de nom pour ce nouveau Block ? crappy.blocks.Synchronizer ? @jeffwitz

Dans tous les cas il te manque deux choses:

Je posterai des updates sur ce thread.

WeisLeDocto commented 6 months ago

On m'a déjà remonté ce problème, il sera réglé dans la prochaine release de Crappy (2.0.5). Le format envisagé est le suivant (en notation f-string): f'{nr:06d}_{t:.3f}.tiff'.

Nouveau format de nom de fichier merged dans #104, toujours planifié pour la release 2.0.5 à venir.

Dans tous les cas il te manque deux choses:

Planifié aussi pour 2.0.5, développements à venir.

WeisLeDocto commented 6 months ago

Dans tous les cas il te manque deux choses:

Le nouveau Block Synchronizer a été ajouté dans #108, et l'envoi de signaux de synchronisation à chaque sauvegarde d'image a été ajouté dans #107. Tout est donc en place pour effectuer des interpolations aux pas de temps images.

Tout ça figurera dans la release 2.0.5 de Crappy, à paraître aujourd'hui ou demain.

Exemple

Le script ci-dessous fonctionne pour moi en version de développement. Les images sont sauvegardées dans un dossier temporaire. ```python # coding: utf-8 import crappy from tempfile import TemporaryDirectory if __name__ == '__main__': temp_dir = TemporaryDirectory() temp_dir.__enter__() sig = crappy.blocks.Generator(({'type': 'Sine', 'freq': 0.1, 'amplitude': 2, 'condition': 'delay=20'},), cmd_label='signal', freq=7) cam = crappy.blocks.Camera('FakeCamera', config=True, display_images=False, save_images=True, save_folder=temp_dir.name, freq=10) sync = crappy.blocks.Synchronizer(reference_label='img_index', time_label='t(s)', labels_to_sync='signal', freq=5) graph = crappy.blocks.Grapher(('t(s)', 'signal'), interp=False) crappy.link(sig, sync) crappy.link(cam, sync) crappy.link(sync, graph) crappy.start() temp_dir.__exit__(None, None, None) ```

Je ferme cette issue puisque tous les points ont été résolus, tu peux la rouvrir si jamais tu recontres un problème sur un des aspects discutés.

rian44s commented 6 months ago

Bonjour Antoine et Jeff,

Bon je galère. J'ai tout cassé :) J'ai tenté le synchronise mais mon code crash.

Voici le log et le code vous en pensez quoi ? Je n'ai pas compris comment ça fonctionne ?

ps: J'ai TP lundi :(

WeisLeDocto commented 6 months ago

Je crois que tu ne peux pas joindre de fichiers via email, il faut soit que tu composes un message sur l'interface web et que tu y inclues ton code, soit que tu passes par un autre canal. En tout cas là je n'ai pas accès à tes fichiers.

WeisLeDocto commented 6 months ago

Extrait du fichier de log, et ça devrait aussi apparaître dans ton terminal :

Traceback (most recent call last):
  File "/home/rseghir/.local/lib/python3.10/site-packages/crappy/blocks/meta_block/block.py", line 802, in run
    self.prepare()
  File "/home/rseghir/.local/lib/python3.10/site-packages/crappy/blocks/ioblock.py", line 218, in prepare
    raise IOError('Error ! The IOBlock is neither an input nor an output !')
OSError: Error ! The IOBlock is neither an input nor an output !

Ton Block IOBlock n'a aucun Link entrant ou sortant. Je crois qu'il te manque juste crappy.link(load_cell, sync).