对图像执行积分的有效方法 [英] efficient way of performing integral on an image
问题描述
我有一个2D数组(通常大小约为400x100),如图所示(它看起来像是梯形,因为右下角的元素是nan).对于数组中的每个元素,我想沿着列对几个元素(〜10个元素的数量级)执行数值积分.用物理学的语言将颜色视为力的大小,我想通过计算Fdz的积分来找到完成的工作.我可以使用双for循环并使用trap
来完成这项工作,但是在Matlab或python中还有其他更有效的方法(可能使用数组和向量化)吗?我的最终目标是找到评估积分最大的点.因此,从黄色代表较大值的图像中,我们期望积分在虚线右侧的某个地方最大.
I have a 2D array (typical size about 400x100) as shown (it looks like a trapezium because elements in the lower right are nan). For each element in the array, I want to perform a numerical integral along the column for several elements (of the order of ~10 elements). In physics language think of the colour as the magnitude of the force, and I want to find the work done by calculating th integral of Fdz. I can use a double for-loop and use trap
to do the job, but are there other more efficient ways (probably mkaing use of arrays and vectorization) to do it in Matlab or python? My ultimate goal is to find the point where the evaluated integral is the largest. So from the image in which yellow represents large value, we expect the integral to be the largest somewhere on the right side above the dotted line.
此外,如果我想要积分的点数是整数,这相对容易,但是如果我想要积分7.5分呢?我正在考虑使用fit
插入点,但是我不确定这是否会使任务过于复杂.
Also, it is relatively easy if the number of points I want to integrate is an integer, but what if I want to integrate, say, 7.5 points? I am thinking of using fit
to interpolate the points, but I'm not sure if that's over-complicating the task.
推荐答案
您可以使用cumsum
加快trap
的速度.计算累积和(@Benjamin提出的一维积分图像)
You can use cumsum
to speedup trap
. Calculating the cummulative sum (1-dimensional integral images proposed by @Benjamin)
>>> import numpy as np
>>> csdata = np.cumsum(data, axis=1)
以离散长度集成
>>> npoints = 6
>>> result = np.zeros_like(data)
>>> result[:-npoints, :] = csdata[npoints:, :] - csdata[:-npoints, :]
result
是图像中每个i, j
的cumdata[i+npoints, j] - cumdata[i, j]
向量化.它将在最后npoints
行中填充零.如果要防止这种情况,可以使用np.pad
reflect
边界.
The result
is a vectorization of cumdata[i+npoints, j] - cumdata[i, j]
for every i, j
in the image. It will fill with zeros last npoints
rows. You can reflect
the boundary with np.pad
if you want to prevent this.
对于非离散间隔,可以使用插值:
For non-discrete intervals, you can work with interpolations:
>>> from scipy.interpolate import interp2d
>>> C = 0.5 # to interpolate every npoints+C pixels
>>> y, x = np.mgrid[:data.shape[0], :data.shape[1]]
>>> ynew, xnew = np.mgrid[C:data.shape[0]+C, :data.shape[1]]
>>> f = interp2d(x, y, csdata)
>>> csnew = f(xnew, ynew)
上面的方法在y
方向上移动了规则网格C
像素,并在这些点上对累积数据csdata
进行插值(实际上,它对每个像素进行插值矢量化).
The above shifts a regular grid C
pixels in y
direction, and interpolates the cummulative data csdata
at those points (in practice, it vectorices interpolation for every pixel).
则npoints+C
长度的积分可以通过以下方式获得
Then the integral of npoints+C
length can be obtained as
>>> npoints = 6
>>> result = np.zeros_like(data)
>>> result[:-npoints, :] = csnew[npoints:, :] - csdata[:-npoints, :]
请注意,现在上限为csnew
(实际上移位6得到6.5元素),从而实际上将其每6.5点积分一次.
Note that the upper bound is now csnew
(a shift of 6 actually gets the 6.5 element), making it integrate every 6.5 points in practice.
然后您可以找到最大点为
You can then find the maximum point as
>>> idx = np.argmax(result.ravel()) # ravel to get the 1D maximum point
>>> maxy, maxx = np.unravel_index(idx, data.shape) # get 2D coordinates of idx
这篇关于对图像执行积分的有效方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!