【问题标题】:Crop out partial image using NumPy (or SciPy)使用 NumPy(或 SciPy)裁剪部分图像
【发布时间】:2014-02-07 06:52:15
【问题描述】:

使用numpyscipy(我没有使用OpenCV)我正在尝试从图像中裁剪出一个区域。

例如,我有这个:

我想得到这个:

是否有类似cropPolygon(image, vertices=[(1,2),(3,4)...])numpySciPy 的东西?

【问题讨论】:

  • 只是为了绘图目的吗?还是您只想实际处理一部分数据,即图像中有趣的部分?
  • 我只想处理图像的那个区域
  • 不用于绘图目的
  • 我所做的是创建一个一维数组,其中包含一个区域内的所有点值(通过地理坐标确定该区域,在我的情况下相当复杂),而不是另一个数组,其中放置这些像素的行/列索引,然后像这样进一步处理它,但取决于最终应用程序,这可能是一个好或坏的策略

标签: python numpy scipy


【解决方案1】:

你在使用 matplotlib 吗?

我之前采用的一种方法是使用matplotlib.path.Path.contains_points() 方法来构造一个布尔掩码,然后可以使用它来索引图像数组。

例如:

import numpy as np
from matplotlib.path import Path
from scipy.misc import lena

img = lena()

# vertices of the cropping polygon
xc = np.array([219.5, 284.8, 340.8, 363.5, 342.2, 308.8, 236.8, 214.2])
yc = np.array([284.8, 220.8, 203.5, 252.8, 328.8, 386.2, 382.2, 328.8])
xycrop = np.vstack((xc, yc)).T

# xy coordinates for each pixel in the image
nr, nc = img.shape
ygrid, xgrid = np.mgrid[:nr, :nc]
xypix = np.vstack((xgrid.ravel(), ygrid.ravel())).T

# construct a Path from the vertices
pth = Path(xycrop, closed=False)

# test which pixels fall within the path
mask = pth.contains_points(xypix)

# reshape to the same size as the image
mask = mask.reshape(img.shape)

# create a masked array
masked = np.ma.masked_array(img, ~mask)

# if you want to get rid of the blank space above and below the cropped
# region, use the min and max x, y values of the cropping polygon:

xmin, xmax = int(xc.min()), int(np.ceil(xc.max()))
ymin, ymax = int(yc.min()), int(np.ceil(yc.max()))
trimmed = masked[ymin:ymax, xmin:xmax]

绘图:

from matplotlib import pyplot as plt

fig, ax = plt.subplots(2, 2)

ax[0,0].imshow(img, cmap=plt.cm.gray)
ax[0,0].set_title('original')
ax[0,1].imshow(mask, cmap=plt.cm.gray)
ax[0,1].set_title('mask')
ax[1,0].imshow(masked, cmap=plt.cm.gray)
ax[1,0].set_title('masked original')
ax[1,1].imshow(trimmed, cmap=plt.cm.gray)
ax[1,1].set_title('trimmed original')

plt.show()

【讨论】:

  • 此方法是否仍包含有关原始图像的数据?这很奇怪,因为当我对图像执行scikit-image 分析时,我裁剪掉的区域仍在分析中。
  • maskednp.ma.masked_array。是否分析屏蔽区域将取决于所讨论的特定功能的行为。大多数基本的 numpy 操作(np.sumnp.max 等)将忽略掩码值。您可以通过许多其他方式使用布尔掩码 - 例如,您可以使用img[mask] 获得一个仅包含裁剪区域中的像素值的一维数组,或者您可以使用img[~mask] = np.nan 将该区域之外的值设置为 NaN。跨度>
  • 嗯有没有办法将掩码数组转换为普通数组?
  • 阅读我发布的链接 - 掩码数组由原始值数组和掩码组成。您可以通过.data 属性访问原始值,并通过.mask 属性访问掩码。 “转换”到底是什么意思?您希望遮罩区域之外的值发生什么变化?
  • 我实际上找到了解决这个问题的方法。我改用了 matplotlib 的路径模块!
猜你喜欢
  • 2017-01-15
  • 1970-01-01
  • 2014-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-17
相关资源
最近更新 更多