对图像执行积分的有效方法 [英] efficient way of performing integral on an image

查看:169
本文介绍了对图像执行积分的有效方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个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, jcumdata[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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆