Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Image processing 有计算图像方向场的标准方法吗?_Image Processing - Fatal编程技术网

Image processing 有计算图像方向场的标准方法吗?

Image processing 有计算图像方向场的标准方法吗?,image-processing,Image Processing,我想在2D图像上计算一种方向场,就像这个photoshop模型(很差)所示。注意:这不是一个向量场,正如您在微分方程中了解的那样。相反,这是一种沿着线条绘制的东西,如果他们计算图像的水平集,就会看到这些线条 是否有已知的方法获取图像的这种方向场(红线)?看起来它的行为几乎像梯度的法线,但这也不完全是它,因为有些地方的梯度为零,我也希望在这些地方有方向场。我找到了一篇关于如何为指纹处理做到这一点的论文,这篇论文非常详细,结果是可以重复的。不幸的是,它隐藏在付费墙后面,但这里是为任何有兴趣并且能够

我想在2D图像上计算一种方向场,就像这个photoshop模型(很差)所示。注意:这不是一个向量场,正如您在微分方程中了解的那样。相反,这是一种沿着线条绘制的东西,如果他们计算图像的水平集,就会看到这些线条


是否有已知的方法获取图像的这种方向场(红线)?看起来它的行为几乎像梯度的法线,但这也不完全是它,因为有些地方的梯度为零,我也希望在这些地方有方向场。

我找到了一篇关于如何为指纹处理做到这一点的论文,这篇论文非常详细,结果是可以重复的。不幸的是,它隐藏在付费墙后面,但这里是为任何有兴趣并且能够访问全文的人准备的:


编辑:根据要求,下面是一个简短的摘要(用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]
来自scipy导入杂项
将numpy作为np导入
输入数学
#导入灰度图像
bmp=misc.imread('path/filename.bmp')
#计算梯度-转换为浮点数非常重要!
梯度=np.梯度(bmp.aType(浮点))
#设置块大小(问题中样本图像上的重叠网格)
块半径=5
#计算方向场。结果将是一个以[0、\pi]表示的角度矩阵,原始(灰度)图像中的每个像素对应一个角度矩阵。
O=np.zero(bmp.shape)
对于范围(0,bmp.shape[0])内的x:
对于范围(0,bmp.shape[1])中的y:
分子=0。
分母=0。
对于范围内的i(最大值(0,x-blockRadius),最小值(bmp.shape[0],x+blockRadius)):
对于范围内的j(最大值(0,y-块半径),最小值(bmp.shape[0],y+块半径)):
分子=分子+2.*梯度[0][i,j]*梯度[1][i,j]
分母=分母+(数学功率(grad[0][i,j],2.)-数学功率(grad[1][i,j],2.))
如果分母==0:
O[x,y]=0
elif分母>0:
O[x,y]=(1./2.)*数学atan(分子/分母)
elif分子>=0:
O[x,y]=(1./2.)*(数学atan(分子/分母)+数学pi)
elif分子<0:
O[x,y]=(1./2.)*(数学atan(分子/分母)-数学pi)
对于范围(0,bmp.shape[0])内的x:
对于范围(0,bmp.shape[1])中的y:

如果O[x,y]@rayryeng-你没有抓住重点。我不是问如何像微分方程那样画向量场,我是问如何计算图像的方向或方向场。这是完全不同的。我怎么能把我的问题标记为不是重复的,因为这是误导性的?如果是,我倾向于去掉重复的标志你在答案后面加了更多的细节。让我们读一篇大多数人都看不到的文章并不是一个有用的答案。哈哈,我很乐意这样做!但似乎大家对这个问题没有太大兴趣,所以我只是发布了一个快速回复。让我提供更多的细节肯定比把它标记为副本要好e、 我会写一篇更详细的文章。Touche。我确实认为副本是相关的,这就是我标记它的原因。现在我可以看到它是不相关的,我想看看这是怎么做的。我现在将删除副本。请继续编辑你的答案:)。此外,图像处理标签中没有那么多:)我只是两个金牌中的一个獾和我现在看到了这个问题。不管怎样,期待着答案!自由地将你的方程式渲染成一幅图像。干杯,谢谢你的编辑!