首页 > 解决方案 > 优化裁剪功能

问题描述

我正在使用以下代码裁剪图像并检索非矩形补丁。

def crop_image(img,roi):
    height = img.shape[0]
    width = img.shape[1]

    mask = np.zeros((height, width), dtype=np.uint8)
    points = np.array([roi])
    cv2.fillPoly(mask, points, (255))

    res = cv2.bitwise_and(img, img, mask=mask)

    rect = cv2.boundingRect(points)  # returns (x,y,w,h) of the rect
    cropped = res[rect[1]: rect[1] + rect[3], rect[0]: rect[0] + rect[2]]

    return cropped, res

投资回报率是[(1053, 969), (1149, 1071), (883, 1075), (813, 983)]。上面的代码有效但是如何优化代码的速度?它太慢了。有没有其他更好的方法来裁剪非矩形补丁?

标签: pythonopencvoptimizationcrop

解决方案


我看到两个可以优化的部分。

  1. 第一步可以应用将图像裁剪到边界矩形边界。益处?您大大减小了您正在使用的图像的大小。您只需将 roi 的点转换为 rect 的 x,y 就可以了。
  2. 在 bitwise_and 操作中,您将图像与自身“与”并检查每个像素是否允许掩码输出它。我想这是花费最多时间的地方。相反,您可以直接与蒙版“和”并节省您宝贵的时间(无需额外的蒙版检查步骤)。同样,为了能够做到这一点,进行一个小的调整,掩码图像应该具有与输入图像(包括通道)完全相同的形状。

编辑: 修改代码以支持输入图像中的任意数量的通道

下面的代码做了这两件事:

def crop_image(img, roi):
height = img.shape[0]
width = img.shape[1]
channels = img.shape[2] if len(img.shape) > 2 else 1

points = np.array([roi])

rect = cv2.boundingRect(points)

mask_shape = (rect[3], rect[2]) if channels == 1 else (rect[3], rect[2], img.shape[2])

#Notice how the mask image size is now the size of the bounding rect
mask = np.zeros(mask_shape, dtype=np.uint8)

#tranlsate the points so that their origin is the bounding rect top left point
for p in points[0]:
    p[0] -= rect[0]
    p[1] -= rect[1]


mask_filling = tuple(255 for _ in range(channels))
cv2.fillPoly(mask, points, mask_filling)

cropped = img[rect[1]: rect[1] + rect[3], rect[0]: rect[0] + rect[2]]

res = cv2.bitwise_and(cropped, mask)

return cropped, res

推荐阅读