Trackpy tp.batch() 给出生成器已经执行的错误

Trackpy tp.batch() gives generator already executing error

我正在尝试使用 trackpy 跟踪视频中的一些粒子。 我正在关注网站上的演练: http://soft-matter.github.io/trackpy/v0.4.2/tutorial/walkthrough.html

处理几帧后(通常大约 14 帧,有时 0 帧),它给我一个值错误:“生成器已经在执行”

我不知道如何解决这个问题,希望有人能解决。

Python:3.9.4 Trackpy:0.5.0

完整错误:

ValueError                                Traceback (most recent call last)
<ipython-input-8-ff6dcf7a7595> in <module>
----> 1 f = tp.batch(frames[100:300], masksize, minmass=minmass, invert=True);

~\.conda\envs\trackpyenv\lib\site-packages\trackpy\feature.py in batch(frames, diameter, output, meta, processes, after_locate, **kwargs)
    556         all_features = []
    557         for i, features in enumerate(map_func(curried_locate, frames)):
--> 558             image = frames[i]
    559             if hasattr(image, 'frame_no') and image.frame_no is not None:
    560                 frame_no = image.frame_no

~\.conda\envs\trackpyenv\lib\site-packages\slicerator\__init__.py in __getitem__(self, key)
    234         if not (isinstance(key, slice) or
    235                 isinstance(key, collections.Iterable)):
--> 236             return self._get(self._map_index(key))
    237         else:
    238             rel_indices, new_length = key_to_indices(key, len(self))

~\.conda\envs\trackpyenv\lib\site-packages\slicerator\__init__.py in _get(self, key)
    205 
    206     def _get(self, key):
--> 207         return self._ancestor[key]
    208 
    209     def _map_index(self, key):

~\.conda\envs\trackpyenv\lib\site-packages\slicerator\__init__.py in __getitem__(self, i)
    478         indices, new_length = key_to_indices(i, len(self))
    479         if new_length is None:
--> 480             return self._get(indices)
    481         else:
    482             return Slicerator(self, indices, new_length, self._propagate_attrs)

~\.conda\envs\trackpyenv\lib\site-packages\slicerator\__init__.py in _get(self, key)
    459         # We need to copy here: else any _proc_func that acts inplace would
    460         # change the ancestor value.
--> 461         return self._proc_func(*(copy(a[key]) for a in self._ancestors))
    462 
    463     def __repr__(self):

~\.conda\envs\trackpyenv\lib\site-packages\slicerator\__init__.py in <genexpr>(.0)
    459         # We need to copy here: else any _proc_func that acts inplace would
    460         # change the ancestor value.
--> 461         return self._proc_func(*(copy(a[key]) for a in self._ancestors))
    462 
    463     def __repr__(self):

~\.conda\envs\trackpyenv\lib\site-packages\slicerator\__init__.py in __getitem__(self, i)
    186                 indices, new_length = key_to_indices(i, len(self))
    187                 if new_length is None:
--> 188                     return self._get(indices)
    189                 else:
    190                     return cls(self, indices, new_length, propagate_attrs)

~\.conda\envs\trackpyenv\lib\site-packages\pims\base_frames.py in __getitem__(self, key)
     96         """__getitem__ is handled by Slicerator. In all pims readers, the data
     97         returning function is get_frame."""
---> 98         return self.get_frame(key)
     99 
    100     def __iter__(self):

~\.conda\envs\trackpyenv\lib\site-packages\pims\base_frames.py in get_frame(self, i)
    590         coords.update(**{k: v for k, v in zip(self.iter_axes, iter_coords)})
    591 
--> 592         result = self._get_frame_wrapped(**coords)
    593         if hasattr(result, 'metadata'):
    594             metadata = result.metadata

~\.conda\envs\trackpyenv\lib\site-packages\pims\imageio_reader.py in get_frame_2D(self, **coords)
    100     def get_frame_2D(self, **coords):
    101         i = coords['t'] if 't' in coords else 0
--> 102         frame = self.reader.get_data(i)
    103         return Frame(frame, frame_no=i, metadata=frame.meta)
    104 

~\.conda\envs\trackpyenv\lib\site-packages\imageio\core\format.py in get_data(self, index, **kwargs)
    344             self._BaseReaderWriter_last_index = index
    345             try:
--> 346                 im, meta = self._get_data(index, **kwargs)
    347             except StopIteration:
    348                 raise IndexError(index)

~\.conda\envs\trackpyenv\lib\site-packages\imageio\plugins\ffmpeg.py in _get_data(self, index)
    379             else:
    380                 if (index < self._pos) or (index > self._pos + 100):
--> 381                     self._initialize(index)
    382                 else:
    383                     self._skip_frames(index - self._pos - 1)

~\.conda\envs\trackpyenv\lib\site-packages\imageio\plugins\ffmpeg.py in _initialize(self, index)
    393             # Close the current generator, and thereby terminate its subprocess
    394             if self._read_gen is not None:
--> 395                 self._read_gen.close()
    396 
    397             iargs = []

ValueError: generator already executing

我偶然发现了相同(或类似)的问题。 根本原因似乎是试图使用多个进程来执行批处理代码,而某些内部函数调用不是线程安全的。 一种解决方法是通过使用 processes=1 调用 batch 来禁用多进程,例如:

f = tp.batch(frames[100:300], masksize, minmass=minmass, invert=True, processes=1);

参考trackpy.batch

将其称为解决方法,因为这会导致代码连续执行,一次一帧。再一次,总比不执行好...