Bonjour,

Les fonctions imread et imdecode d'opencv se comportent mal au décodage des fichiers jpeg2000 .jp2

Un petit example sans thread qui fonctionne très bien:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import multiprocessing.pool
import cv2
import numpy as np
import tqdm
 
img = np.random.randint(0, 65335, (1024, 1024), dtype=np.uint16)
_, img_data = cv2.imencode(".jp2", img)
n = 100
 
def read(i):
    image = cv2.imdecode(buffer, cv2.IMREAD_ANYDEPTH | cv2.IMREAD_GRAYSCALE)
 
list(tqdm.tqdm(map(read, range(n)), total=n, desc="main thread main process"))
with multiprocessing.pool.Pool() as pool:
   list(tqdm.tqdm(pool.imap_unordered(read, range(n)), total=n, desc="main thread child process"))
Et attention, c'est la que la magie opère... Voici un example buggé, essayez d'interrompre avec ctrl+c, ça va segfault; si le programme ne se fige pas déjà par lui même!


Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import multiprocessing.pool
import cv2
import numpy as np
import tqdm
 
img = np.random.randint(0, 65335, (1024, 1024), dtype=np.uint16)
_, img_data = cv2.imencode(".jp2", img)
n = 100
 
def read(i):
    image = cv2.imdecode(buffer, cv2.IMREAD_ANYDEPTH | cv2.IMREAD_GRAYSCALE)
 
with multiprocessing.pool.ThreadPool() as pool:
   list(tqdm.tqdm(pool.imap_unordered(read, range(n)), total=n, desc="child thread main process"))

Il semblerai que metre un `time.sleep(0.5)` dans le read arrange un peu les choses, mais c'est vraiment cracra comme réparation.
J'ai aussi tenté de relancer un processus à chaque fois pour se retrouver dans le thread principal mais cela n'améliore rien du tout:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
def read(i):
    with multiprocessing.pool.Pool() as pool:
        image = pool.apply(cv2.imdecode, args=(buffer, cv2.IMREAD_ANYDEPTH | cv2.IMREAD_GRAYSCALE))
Version 4.10.0 de cv2. Le comportement est le même sur python 3.9, 3.10, 3.11. Testé sur Mint, Ubuntu et Debian.

Une idée ? Est-ce que ça se comporte pareillement chez vous ?