图像处理:如何在目的地使用简单的蒙版进行变形?
Image Processing: how to imwarp with simple mask on destination?
关注,这次只在Python-
我正在寻找一种方法来将纹理映射到目标图像中的一个小区域,该区域由 4 个角定义为 (x, y) 像素坐标。该区域不一定是矩形的。它是一些矩形在图像平面上的透视投影。
我想将一些(矩形)纹理映射到由这些角定义的蒙版中。
直接通过 forward-mapping 纹理 will not work properly 映射,因为源像素将映射到目标中的 non-integer 个位置。
这个问题一般是inverse-warping从目的到源,然后根据某种插值着色
Opencv 的 warpPerspective
在这里不起作用,因为它不能带掩码。
Inverse-warping 整个目的地然后掩码是不可接受的,因为大部分计算都是多余的。
- 是否有 built-in opencv(或其他)函数可以满足上述要求?
- 如果不是,有什么好方法可以从由角定义的 ROI 中获取像素列表,以便将其传递给
projectPoints
?
示例背景图片:
我想用其他纹理填充红线勾勒出的区域(由其角定义),比如这个
它们之间的映射可以通过使用 cv2.getPerspectiveTransform
将纹理的角点映射到 ROI 角点来获得
对于后代,这里是如何仅在扭曲角点的 bbox 内前后扭曲像素,正如@Micka 所建议的那样。
这里banner
是草图,banner_coords_2d
是image
上红色区域的角,就是表情包
def transform_banner(banner_coords_2d, banner, image):
# show_points_on_image("banner corners", image, banner_coords_2d)
banner_height, banner_width, _ = banner.shape
src_banner_points = np.float32([
[0, 0],
[banner_width - 1, 0],
[0, banner_height - 1],
[banner_width - 1, banner_height - 1],
])
# only warp to size of bbox of warped corners, not all of the image
warped_left = np.round(np.min(banner_coords_2d[:, 0])).astype(int)
warped_right = np.round(np.max(banner_coords_2d[:, 0])).astype(int)
warped_top = np.round(np.min(banner_coords_2d[:, 1])).astype(int)
warped_bottom = np.round(np.max(banner_coords_2d[:, 1])).astype(int)
warped_width = int(warped_right - warped_left)
warped_height = int(warped_bottom - warped_top)
dst_banner_points = banner_coords_2d.astype(np.float32)
dst_banner_points[:, 0] -= warped_left
dst_banner_points[:, 1] -= warped_top
tform = cv2.getPerspectiveTransform(src_banner_points, dst_banner_points)
warped_banner = cv2.warpPerspective(banner, tform, (warped_width, warped_height))
# cv2.imshow("warped_banner", warped_banner)
image_with_banner = image.copy()
image_with_banner[warped_top: warped_bottom, warped_left: warped_right][warped_banner != 0] = warped_banner[
warped_banner != 0]
# cv2.imshow("image_with_banner", image_with_banner)
return image_with_banner
可能,这可以做得更整洁,我愿意编辑。
关注
我正在寻找一种方法来将纹理映射到目标图像中的一个小区域,该区域由 4 个角定义为 (x, y) 像素坐标。该区域不一定是矩形的。它是一些矩形在图像平面上的透视投影。
我想将一些(矩形)纹理映射到由这些角定义的蒙版中。
直接通过 forward-mapping 纹理 will not work properly 映射,因为源像素将映射到目标中的 non-integer 个位置。
这个问题一般是inverse-warping从目的到源,然后根据某种插值着色
Opencv 的 warpPerspective
在这里不起作用,因为它不能带掩码。
Inverse-warping 整个目的地然后掩码是不可接受的,因为大部分计算都是多余的。
- 是否有 built-in opencv(或其他)函数可以满足上述要求?
- 如果不是,有什么好方法可以从由角定义的 ROI 中获取像素列表,以便将其传递给
projectPoints
?
示例背景图片:
我想用其他纹理填充红线勾勒出的区域(由其角定义),比如这个
它们之间的映射可以通过使用 cv2.getPerspectiveTransform
对于后代,这里是如何仅在扭曲角点的 bbox 内前后扭曲像素,正如@Micka 所建议的那样。
这里banner
是草图,banner_coords_2d
是image
上红色区域的角,就是表情包
def transform_banner(banner_coords_2d, banner, image):
# show_points_on_image("banner corners", image, banner_coords_2d)
banner_height, banner_width, _ = banner.shape
src_banner_points = np.float32([
[0, 0],
[banner_width - 1, 0],
[0, banner_height - 1],
[banner_width - 1, banner_height - 1],
])
# only warp to size of bbox of warped corners, not all of the image
warped_left = np.round(np.min(banner_coords_2d[:, 0])).astype(int)
warped_right = np.round(np.max(banner_coords_2d[:, 0])).astype(int)
warped_top = np.round(np.min(banner_coords_2d[:, 1])).astype(int)
warped_bottom = np.round(np.max(banner_coords_2d[:, 1])).astype(int)
warped_width = int(warped_right - warped_left)
warped_height = int(warped_bottom - warped_top)
dst_banner_points = banner_coords_2d.astype(np.float32)
dst_banner_points[:, 0] -= warped_left
dst_banner_points[:, 1] -= warped_top
tform = cv2.getPerspectiveTransform(src_banner_points, dst_banner_points)
warped_banner = cv2.warpPerspective(banner, tform, (warped_width, warped_height))
# cv2.imshow("warped_banner", warped_banner)
image_with_banner = image.copy()
image_with_banner[warped_top: warped_bottom, warped_left: warped_right][warped_banner != 0] = warped_banner[
warped_banner != 0]
# cv2.imshow("image_with_banner", image_with_banner)
return image_with_banner
可能,这可以做得更整洁,我愿意编辑。