(1) Use cv2.copyMakeBorder
to enlarge the image, to avoid the warpped points going out of range of the original image size.
cv2.copyMakeBorder(...)
copyMakeBorder(src, top, bottom, left, right, borderType[, dst[, value]]) -> dst
. @brief Forms a border around an image.
.
. The function copies the source image into the middle of the destination image. The areas to the
. left, to the right, above and below the copied source image will be filled with extrapolated
. pixels. This is not what filtering functions based on it do (they extrapolate pixels on-fly), but
. what other more complex functions, including your own, may do to simplify image boundary handling.
useage:
img = cv2.copyMakeBorder(img, dh, dh, dw, dw, borderType=cv2.BORDER_CONSTANT, value=(0,0,0))
Set dw=nw//2, dh=nh//2
maybe ok, adjust if necessary. The nh, nw
is the height and width of the source image.
(2) Create perturbed mesh grid using the method from the paper
xs, ys = create_grid() # the result is like np.meshgrid
Notice make sure the type and the size.
# xs = xs.reshape(nh, nw).astype(np.float32)
# nh, nw is the height and width of the coppied image
(3) Use cv2.remap
to remap:
cv2.remap(...)
remap(src, map1, map2, interpolation[, dst[, borderMode[, borderValue]]]) -> dst
. @brief Applies a generic geometrical transformation to an image.
.
. The function remap transforms the source image using the specified map:
. f[exttt{dst} (x,y) = exttt{src} (map_x(x,y),map_y(x,y))f]
usage:
dst= cv2.remap(img, xs, ys, cv2.INTER_CUBIC)
This is a demo result:
(4) Crop the nonzero region and resize if necessary:
Related:
Converting opencv remap code from c++ to python
Split text lines in scanned document