我想创建扭曲效果,如螺旋,拉伸,鱼眼,楔形和其他效果,如水下和雪地,像这个website使用cv2库在python中。
发布于 2017-03-11 16:31:54
我算出了鱼眼的失真。
在OpenCV 3.0版及更高版本中,可以使用cv2.fisheye.undistortImage()执行此操作。如果你需要,我有python的代码。
这是我从下面的输入图像中得到的:
输入图像:

失真图像:

该函数接受一个矩阵,该矩阵在修改时会产生不同的图像失真。
更新
为了添加降雪效果,您可以添加一些噪声,如泊松噪声。
发布于 2020-04-17 23:14:43
这里有一半的答案。pixel函数使用map从源中为目标中的每个像素选择一个像素。alkasm对此的回答是:How do I use OpenCV's remap function?在定义过程方面做得很好,但掩盖了这些映射的有用性。如果你能在地图上有创意,你就可以做出任何你想要的效果。这是我想出来的。
该程序首先加载图像并调整其大小。对于较小的屏幕,这是一种便利。然后创建空地图。
贴图需要与正在处理的图像的尺寸相同,但深度为1。如果调整大小的原始图像为633 x 400 x 3,则两个贴图都需要为633 x 400。
重新映射完成后,cv2.remap将使用映射中每个坐标处的值来确定在目标中使用原始像素中的哪个像素。对于目的地中的每个x,y,map2x x,y=src[ destx,y,destx,y]。
最简单的映射是如果对于每个(x,y),map1(x,y)=x和map2(x,y)=y。这将创建一个一对一的映射,并且目标将与源匹配。在此示例中,为每个值添加了一个小偏移量。偏移量中的余弦函数会产生正负位移,在最终图像中产生波动。
请注意,创建映射的速度很慢,但cv2.remap很快。一旦创建了映射,cv2.remap就足够快,可以应用于视频帧。
import numpy as np #create waves
import cv2
import math
# read in image and resize down to width of 400
# load your image file here
image = cv2.imread("20191114_154534.jpg")
r = 400.0 / image.shape[1]
dim = (400, int(image.shape[0] * r))
# Perform the resizing of the image
resized = cv2.resize(image, dim, interpolation = cv2.INTER_AREA)
# Grab the dimensions of the image and calculate the center
# of the image (center not needed at this time)
(h, w, c) = resized.shape
center = (w // 2, h // 2)
# set up the x and y maps as float32
flex_x = np.zeros((h,w),np.float32)
flex_y = np.zeros((h,w),np.float32)
# create simple maps with a modified assignment
# the math modifier creates ripples. increase the divisor for less waves,
# increase the multiplier for greater movement
# this is where the magic is assembled
for y in range(h):
for x in range(w):
flex_x[y,x] = x + math.cos(x/15) * 15
flex_y[y,x] = y + math.cos(y/30) * 25
# do the remap this is where the magic happens
dst = cv2.remap(resized,flex_x,flex_y,cv2.INTER_LINEAR)
#show the results and wait for a key
cv2.imshow("Resized",resized)
cv2.imshow("Flexed",dst)
cv2.waitKey(0)
cv2.destroyAllWindows()发布于 2020-04-18 01:11:04
这是一个替换块,用来在图像中间绘制出一个鱼眼。请在其他地方查看有关数学的详细信息。用它代替前面代码中的2个for循环。
正如我在答案的前半部分所述(参见前面的答案),此块的目的是创建两个共同工作的映射,以将源映像重新映射到目标映像。
为了创建这两个映射,此块使用图像的尺寸遍历2个for循环。将为X和Y贴图(flex_x和flex_y)计算值。它首先将每个元素分配给简单的x和y,以实现1对1的替换映射。然后,如果半径(r)在0和1之间,将应用鱼眼切线滑动的贴图,并映射新的flex_x和flex_y值。
有关更多详细信息,请参阅我的另一个答案。
# create simple maps with a modified assignment
# outside the bulge is normal, inside is modified
# this is where the magic is assembled
for y in range(h):
ny = ((2*y-250)/(h-250))-1 #play with the 250's to move the y
ny2 = ny*ny
for x in range(w):
nx = ((2*x-50)/(w-50))-1 #play with the 50's to move the x
nx2 = nx*nx
r = math.sqrt(nx2+ny2)
flex_x[y,x] = x
flex_y[y,x] = y
if r>0 and r<1:
nr1 = 1 - r**2
nr2 = math.sqrt(nr1)
nr = (r + (1.0-nr2)) / 2.0
theta = math.atan2(ny,nx)
nxn = nr*math.cos(theta)
nyn = nr*math.sin(theta)
flex_x[y,x] = (((nxn+1)*w)/2.0)
flex_y[y,x] = (((nyn+1)*h)/2.0)https://stackoverflow.com/questions/42732873
复制相似问题