如何创建光隧道变换图像
How to create light tunnel transformation image
我有一个练习,可以将图像转换为像这样具有光隧道效果的图像。
我的第一个想法是select在中间画一个区域圆,如果中心点、边界点和考虑的点是在同一行,但结果很差。
这是我的代码:
import numpy as np
import cv2
import math
import numpy as np
from google.colab.patches import cv2_imshow
from shapely.geometry import LineString
from shapely.geometry import Point
img = cv2.imread("./orig_img.png")
h,w,_ = img.shape
flex_x = np.zeros((h,w),np.float32)
flex_y = np.zeros((h,w),np.float32)
scale_y= 1
center_x, center_y = (w // 2, h // 2)
radius = 50
scale_x = 1
p = Point(center_x, center_y)
c = p.buffer(radius).boundary
for y in range(h):
delta_y = scale_y * (y - center_y)
for x in range(w):
delta_x = scale_x * (x - center_x)
distance = delta_x * delta_x + delta_y * delta_y
if distance <= (radius * radius):
flex_x[y, x] = x
flex_y[y, x] = y
else:
l = LineString([(center_x, center_y), (x,y)])
i = c.intersection(l)
new_x,new_y = round(i.coords[0][0]),round(i.coords[0][1])
flex_x[y,x] = flex_x[new_y,new_x]
flex_y[y,x] = flex_y[new_y,new_x]
dst = cv2.remap(img, flex_x, flex_y, cv2.INTER_LINEAR)
cv2_imshow(dst)
有没有人有更好的主意来做这个或者我的代码可以修复吗? , 请帮我!非常感谢!
这需要 cv.remap
和一些几何图形。
您遇到问题是因为您尝试画线。你甚至不需要为此重新映射。
im = cv.imread("d1LU6.png")
(h,w) = im.shape[:2]
# some definitions
center = np.array([w/2, h/2])
radius = h / 5
i,j = np.mgrid[0:h, 0:w]
xymap = np.dstack([j,i]).astype(np.float32) # "identity" map
# coordinates relative to center
coords = (xymap - center)
# distance to center
dist = np.linalg.norm(coords, axis=2)
# touch only what's outside of the circle
mask = (dist >= radius)
# project onto circle (calculate unit vectors, move onto circle, then back to top-left origin)
xymap[mask] = coords[mask] / dist[mask,None] * radius + center
out = cv.remap(im, map1=xymap, map2=None, interpolation=cv.INTER_LINEAR)
# imshow(out)
我有一个练习,可以将图像转换为像这样具有光隧道效果的图像。
我的第一个想法是select在中间画一个区域圆,如果中心点、边界点和考虑的点是在同一行,但结果很差。
这是我的代码:
import numpy as np
import cv2
import math
import numpy as np
from google.colab.patches import cv2_imshow
from shapely.geometry import LineString
from shapely.geometry import Point
img = cv2.imread("./orig_img.png")
h,w,_ = img.shape
flex_x = np.zeros((h,w),np.float32)
flex_y = np.zeros((h,w),np.float32)
scale_y= 1
center_x, center_y = (w // 2, h // 2)
radius = 50
scale_x = 1
p = Point(center_x, center_y)
c = p.buffer(radius).boundary
for y in range(h):
delta_y = scale_y * (y - center_y)
for x in range(w):
delta_x = scale_x * (x - center_x)
distance = delta_x * delta_x + delta_y * delta_y
if distance <= (radius * radius):
flex_x[y, x] = x
flex_y[y, x] = y
else:
l = LineString([(center_x, center_y), (x,y)])
i = c.intersection(l)
new_x,new_y = round(i.coords[0][0]),round(i.coords[0][1])
flex_x[y,x] = flex_x[new_y,new_x]
flex_y[y,x] = flex_y[new_y,new_x]
dst = cv2.remap(img, flex_x, flex_y, cv2.INTER_LINEAR)
cv2_imshow(dst)
有没有人有更好的主意来做这个或者我的代码可以修复吗? , 请帮我!非常感谢!
这需要 cv.remap
和一些几何图形。
您遇到问题是因为您尝试画线。你甚至不需要为此重新映射。
im = cv.imread("d1LU6.png")
(h,w) = im.shape[:2]
# some definitions
center = np.array([w/2, h/2])
radius = h / 5
i,j = np.mgrid[0:h, 0:w]
xymap = np.dstack([j,i]).astype(np.float32) # "identity" map
# coordinates relative to center
coords = (xymap - center)
# distance to center
dist = np.linalg.norm(coords, axis=2)
# touch only what's outside of the circle
mask = (dist >= radius)
# project onto circle (calculate unit vectors, move onto circle, then back to top-left origin)
xymap[mask] = coords[mask] / dist[mask,None] * radius + center
out = cv.remap(im, map1=xymap, map2=None, interpolation=cv.INTER_LINEAR)
# imshow(out)