我想在2D图像上计算一种方向场,就像从这个photoshop模型中说的那样(很差)。注意:当您在微分方程中学习时,这不是矢量场。相反,这是根据人们在计算图像的水平集时会看到的线条。
是否有已知方法可以获得图像的这种方向场(红线)?看起来它几乎像渐变的法线一样,但这也不是完全正确的,因为有些地方渐变为零,我也喜欢这些位置的方向场。 / p>
答案 0 :(得分:2)
我能够找到一篇关于如何为指纹处理执行此操作的论文,其中详细说明了其结果是可重复的。不幸的是,它背后是付费专区,但是这里有任何感兴趣并且能够访问全文的人:
Systematic methods for the computation of the directional fields and singular points of fingerprints
编辑:根据要求,这里有一个快速而简洁的摘要(在Python中),它是如何在上面的论文中实现的。
一种天真的方法是在目标像素周围的小方块邻域中平均梯度,非常类似于问题中图像上的叠加网格,然后计算法线。但是,如果您只是平均梯度,那么该区域中的相反梯度可能会相互抵消(例如,当计算沿脊的方向时)。因此,通常以平方梯度计算,因为然后将指向相反方向的梯度对齐。基于原始梯度的平方渐变有一个聪明的公式。我不会给出推导,但这里是公式:
现在,取区域上的平方梯度之和(以角度方式工作的一些分段定义的补偿为模)。最后,通过一些反正切的魔法,你将得到方向场。
如果在平滑灰度位图图像上运行以下代码并选择适当的网格尺寸,然后在原始图像旁边绘制方向字段O,您将看到方向字段如何或多或少地给出角度我在原来的问题中问过。
from scipy import misc
import numpy as np
import math
# Import the grayscale image
bmp = misc.imread('path/filename.bmp')
# Compute the gradient - VERY important to convert to floats!
grad = np.gradient(bmp.astype(float))
# Set the block size (superimposed grid on the sample image in the question)
blockRadius=5
# Compute the orientation field. Result will be a matrix of angles in [0, \pi), one for each pixel in the original (grayscale) image.
O = np.zeros(bmp.shape)
for x in range(0,bmp.shape[0]):
for y in range(0,bmp.shape[1]):
numerator = 0.
denominator = 0.
for i in range(max(0,x-blockRadius),min(bmp.shape[0],x+blockRadius)):
for j in range(max(0,y-blockRadius),min(bmp.shape[0],y+blockRadius)):
numerator = numerator + 2.*grad[0][i,j]*grad[1][i,j]
denominator = denominator + (math.pow(grad[0][i,j],2.) - math.pow(grad[1][i,j],2.))
if denominator==0:
O[x,y] = 0
elif denominator > 0:
O[x,y] = (1./2.)*math.atan(numerator/denominator)
elif numerator >= 0:
O[x,y] = (1./2.)*(math.atan(numerator/denominator)+math.pi)
elif numerator < 0:
O[x,y] = (1./2.)*(math.atan(numerator/denominator)-math.pi)
for x in range(0,bmp.shape[0]):
for y in range(0,bmp.shape[1]):
if O[x,y] <= 0:
O[x,y] = O[x,y] + math.pi
else:
O[x,y] = O[x,y]
干杯!