我想知道是否有人可以帮助我将the smoothing example in the SciPy cookbook扩展到2D问题。
此脚本非常适合平滑1D功能,它们还为两个轴上的2D平滑提供代码(即模糊图像)。
但是,我想将此功能应用于2D数据集,但仅沿一个轴(x方向)。我可以循环执行此操作,方法是检查y中的每个切片,应用1D卷积,然后重建阵列。但这似乎是糟糕的编码技术。
因此,我想知道如何在2D中完成它?我想我需要制作一个2D内核,权重只沿一个方向变化,但我不知道如何做到这一点,或者使用哪个卷积函数(numpy.convolve
,scipy.signal.convolve
,{ {1}}等。)
答案 0 :(得分:4)
似乎你应该能够ny=1
执行2D图像的一维卷积,但这表明cookbook函数实际上使用了长度为2 * n + 1
的内核。这让我觉得您可以使用ny=0
,但这会在内核的定义中创建0/0
。所以,那里也没有运气。 :(基于此,我认为食谱不适合您的目的,所以我提供了另一种方法来做您所要求的。
要仅通过1维卷积来执行2D数组的平滑处理,您只需要创建一个沿着其中一个维度具有形状1的2D数组(内核),
import numpy as np
kern = np.ones((11, 1)) # This will smooth along columns
并将其标准化,使其总和为一,
kern /= kern.sum()
然后用信号对其进行卷积,
import scipy.signal as signal
X, Y = np.mgrid[-70:70, -70:70]
Z = np.cos((X**2+Y**2)/200.) + np.random.normal(size=X.shape)
Z_smooth = signal.convolve(Z, kern)
这应该给你这样的东西, man page for SCons
上面我使用了'boxcar'内核(常数值),许多人认为这种内核有些粗糙。人们通常更喜欢使用更清晰或更平滑的过滤器(例如,在烹饪书中使用'hanning'或'gaussian')。
kern_hanning = signal.hanning(11)[:, None]
kern_hanning /= kern_hanning.sum()
kern_gauss7 = signal.gaussian(11, 7)[:, None]
kern_gauss7 /= kern_gauss7.sum()
kern_gauss3 = signal.gaussian(11, 3)[:, None]
kern_gauss3 /= kern_gauss3.sum()
这些不同的窗口看起来像这样,
应用这些过滤器后,您将获得类似的内容,
请注意,'Gauss7'内核与boxcar几乎相同,因此它在输出中产生非常相似的结果。另一方面,hanning窗口更精细,因此它可以生成更清晰的数据过滤器(更不用说在环上涂抹)。
答案 1 :(得分:3)
也许最简单的选择是在scipy.ndimage.filters
中使用其中一个过滤器:
using System.Linq;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.OData;
using Microsoft.WindowsAzure.Mobile.Service;
using TempService.DataObjects;
using TempService.Models;
using System.Web.Http.OData.Query;
using System.Collections.Generic;
namespace TempService.Controllers
{
public class TodoItemController : TableController<TodoItem>
{
protected override void Initialize(HttpControllerContext controllerContext)
{
base.Initialize(controllerContext);
// Create a new Azure Storage domain manager using the stored
// connection string and the name of the table exposed by the controller.
string connectionStringName = "StorageConnectionString";
var tableName = controllerContext.ControllerDescriptor.ControllerName.ToLowerInvariant();
DomainManager = new StorageDomainManager<TodoItem>(connectionStringName,
tableName, Request, Services);
}
public Task<IEnumerable<TodoItem>> GetAllTodoItems(ODataQueryOptions options)
{
// Call QueryAsync, passing the supplied query options.
return DomainManager.QueryAsync(options);
}
// GET tables/TodoItem/1777
public SingleResult<TodoItem> GetTodoItem(string id)
{
return Lookup(id);
}
// PATCH tables/TodoItem/1456
public Task<TodoItem> PatchTodoItem(string id, Delta<TodoItem> patch)
{
return UpdateAsync(id, patch);
}
// POST tables/TodoItem
public async Task<IHttpActionResult> PostTodoItem(TodoItem item)
{
TodoItem current = await InsertAsync(item);
return CreatedAtRoute("Tables", new { id = current.Id }, current);
}
// DELETE tables/TodoItem/1234
public Task DeleteTodoItem(string id)
{
return DeleteAsync(id);
}
}
你也可以像这样使用过滤器的非1D版本:from scipy import ndimage
from scipy.misc import lena
img = lena()
# a uniform (boxcar) filter with a width of 50
boxcar = ndimage.uniform_filter1d(img, 50, 1)
# a Gaussian filter with a standard deviation of 10
gauss = ndimage.gaussian_filter1d(img, 10, 1)
(即为你不想平滑的轴设置过滤器宽度为0)。
要使任意内核平滑,您可以使用scipy.ndimage.convolve1d
:
ndimage.gaussian_filter(img, (0, 10))
这是各种输出的样子:
import numpy as np
kern = np.hanning(50) # a Hanning window with width 50
kern /= kern.sum() # normalize the kernel weights to sum to 1
hanning = ndimage.convolve1d(img, kern, 1)