我是 OpenCV 新手。我想创建一个函数,该函数在图像中获取一些焦点,并随着您远离该焦点而逐渐变得更加模糊(例如,持续更加模糊,而不是选择要模糊和非模糊的区域)。我想让模糊尽可能连续地增加。有人对如何做到这一点有任何想法吗?
这是一种使用多种模糊强度的方法。
im = cv.imread(cv.samples.findFile("lena.jpg"))
(height, width) = im.shape[:2]
cx,cy = (width-1) / 2, (height-1) / 2
y,x = np.mgrid[0:height, 0:width]
distance = np.hypot(x-cx, y-cy)
sigma = distance ** 2 * 0.0002
logsigma = np.log2(sigma).astype(np.float32)
Run Code Online (Sandbox Code Playgroud)
def ntimes(n, fn, *a, **kw):
def sub(arg):
for i in range(n):
arg = fn(arg, *a, **kw)
return arg
return sub
nlayers = 8
blur_pyramid = [im]
for k in range(nlayers-1):
blur_pyramid.append(cv.pyrDown(blur_pyramid[k]))
blur_layers = np.array([
ntimes(k, cv.pyrUp)(blur_pyramid[k])
for k in range(nlayers)
])
# this is faster than calculating GaussianBlur on the full-size image
Run Code Online (Sandbox Code Playgroud)
# this stunt is needed because I can't figure out how to make numpy do the equivalent indexing
@nb.njit(parallel=True)
def sample_along_axis0(texture, levelmap):
N,H,W,C = texture.shape
out = np.empty((H,W,C), dtype=np.uint8)
levelmap = np.clip(levelmap, 0, N-1)
ilevelmap = np.clip(np.floor(levelmap).astype(np.int32), 0, N-2)
flevelmap = levelmap - ilevelmap
for y in nb.prange(H):
for x in range(W):
ilevel = ilevelmap[y,x]
flevel = flevelmap[y,x]
out[y,x] = np.clip(
(1-flevel) * texture[ilevel,y,x] + flevel * texture[ilevel+1,y,x],
0, 255)
return out
composite = sample_along_axis0(blur_layers, logsigma)
Run Code Online (Sandbox Code Playgroud)
此代码在西格玛级别计算中包含“相差一”错误。由于 中的低通,第二级[1]对应于 sigma=1 pyrDown,但是我将其视为代表log(sigma) == 1,这意味着 sigma=2。我认为这对于读者来说是一个很好的练习,可以找到合适的地方来解决这个问题。
以下是具有最近邻插值(沿着级别)并且每个级别具有不同色调的版本。您可以清楚地看到级别的交汇处。内环全部是“红色”,因为根本没有模糊,即它的级别为 0(并且源图像严重染成红色)。
模糊是低通的。如果考虑低通频谱图,它会在超过某个点后下降。
对于这种径向变化的模糊,您希望该截止点向左/向右移动(沿着频率轴)。
如果您只获取源图像和它的强烈模糊版本,然后在它们之间进行插值,这不会向左/向右移动点,它会向上/向下移动整个频率平台,即超出截止值的频率观点。
在极限情况下,如果模糊版本非常强烈,它就只是一种平面颜色。你基本上会得到一个小插图:
| 归档时间: |
|
| 查看次数: |
524 次 |
| 最近记录: |