代码之家  ›  专栏  ›  技术社区  ›  scrutari

OpenCV返回关键点的python多进程问题

  •  0
  • scrutari  · 技术社区  · 7 年前

    我在用 multiprocess Python模块与OpenCV算法(例如ORB检测器/描述符)并行处理。这个 多进程 cv2.KeyPoint

    下面是可以用来重现错误的最小示例(您将需要一个名为 lena.png 为了让它工作):

    import numpy as np
    
    from cv2 import ORB_create, imread, cvtColor, COLOR_BGR2GRAY
    from multiprocess import Pool
    
    feature = ORB_create(nfeatures=4)
    
    def proc(img):
        return feature.detect(img)
    
    def good(feat, frames):
        return map(proc, frames)
    
    def bad(feat, frames):
        # this starts a worker process
        # and then collects result
        # but something is lost on the way
        pool = Pool(4)
        return pool.map(proc, frames)
    
    if __name__ == '__main__':
        # it doesn't matter how many images
        # a list of images is required to make use of
        # pool from multiprocess module
        rgb_images = map(lambda fn: imread(fn), ['lena.png'])
        grey_images = map(lambda img: cvtColor(img, COLOR_BGR2GRAY), rgb_images)
        good_kp = good(feature, grey_images)
        bad_kp = bad(feature, grey_images)
    
        # this will fail because elements in
        # bad_kp will all contain zeros
        for i in range(len(grey_images)):
        for x, y in zip(good_kp[i], bad_kp[i]):
                # these should be the same
                print('good: pt=%s angle=%s size=%s - bad: pt=%s angle=%s size=%s' % (x.pt, x.angle, x.size, y.pt, y.angle, y.size))
                assert x.pt == y.pt
    

    平台:CentOS 7.6和Windows 10 x64

    版本:

    • Python版本:2.7.15

    • 多进程:0.70.6.1

    有办法解决这个问题吗?标准的使用 multiprocessing

    1 回复  |  直到 7 年前
        1
  •  0
  •   scrutari    7 年前

    经过一番分析,结果证明这个问题是由……引起的 cv2.KeyPoint question 以及相应的 answer . 问题是 pickle dill 无法使用此类。

    一个简单的解决方案是避免发送 在工人和主进程之间。如果这不方便,那么应该将每个关键点的数据包装在一个简单的Python结构或字典中并传递它。

    包装器的示例可以是:

    import cv2
    class KeyPoint(object):
    
        def __init__(self, kp):
            # type: (cv2.KeyPoint) -> None
            x, y = kp.pt
            self.pt = float(x), float(y)
            self.angle = float(kp.angle) if kp.angle is not None else None
            self.size = float(kp.size) if kp.size is not None else None
            self.response = float(kp.response) if kp.response is not None else None
            self.class_id = int(kp.class_id) if kp.class_id is not None else None
            self.octave = int(kp.octave) if kp.octave is not None else None
    
       def to_opencv(self):
            # type: () -> cv2.KeyPoint
            kp = cv2.KeyPoint()
            kp.pt = self.pt
            kp.angle = self.angle
            kp.size = self.size
            kp.response = self.response
            kp.octave = self.octave
            kp.class_id = self.class_id
            return kp