【问题标题】:Remove pairs of values from NumPy array从 NumPy 数组中删除值对
【发布时间】:2017-02-19 15:28:02
【问题描述】:

我有一个 NumPy 数组 contours,我从 cv2.findContours 获得并使用 contours = np.concatenate(contours, axis = 0) 进行展平。它存储图像中对象轮廓的坐标。但是,我想删除 X 或 Y 小于 100 或大于 1000 的坐标。我首先尝试使用 contours = np.delete(contours, 0)contours = np.delete(contours[0], 0) 删除任何项目,但我一直收到此错误: IndexError: invalid index to scalar variable.

如何删除这样的值对?

print(type(contours))
→ <class 'numpy.ndarray'>
print(contours[0])
→ [[2834 4562]]
print(type(contours[0]))
→ <class 'numpy.ndarray'>
print(contours[0][0])
→ [2834 4562]
print(type(contours[0][0]))
<class 'numpy.ndarray'>

另外,我不想进一步连接/展平列表,因为它正是我需要发送到cv2.convexHull(contours) 的形式。

这是我的代码的最小工作示例:

import cv2          # library for processing images
import numpy as np  # numerical calculcations for Python

img = cv2.imread("img.png")
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
_, img_thr = cv2.threshold(img_gray,0,255,cv2.THRESH_OTSU)
img_rev = cv2.bitwise_not(img_thr)
img_cnt, contours, hierarchy = cv2.findContours(img_rev, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours = np.concatenate(contours, axis = 0)

hull = cv2.convexHull(contours)
rect = cv2.minAreaRect(np.int0(hull))
box = cv2.boxPoints(rect)
box = np.int0(box)

img_cnt = cv2.drawContours(img, contours, -1, (0,255,0), 3)
img_cnt = cv2.drawContours(img, [box], -1, (0,0,255), 5)

cv2.imwrite("img_out.png", img_cnt)

这是一个示例input image,这是我的output image。我想忽略文本选择的外围“噪音”。假设我不能使用进一步的降噪。

【问题讨论】:

标签: python arrays opencv numpy


【解决方案1】:

似乎 contours.shape 是 (N,1,2) 。在这种情况下,

contours[((contours>100)&(contours<1000)).all(axis=(1,2))]

会起作用的。

举例:

In [106]: contours=randint(0,1100,(10,1,2))
[[[ 803  772]]
 [[ 210  490]]
 [[ 433   76]]
 [[ 347   88]]
 [[ 763  747]]
 [[ 678  200]]
 [[ 816  444]]
 [[ 528  817]]
 [[ 140  440]]
 [[1019  654]]]

In [108]: valid = ((contours>100)&(contours<1000)).all(axis=(1,2))
Out[108]: array([ True,  True, False, False,  True,  True,  
                  True,  True,  True, False], dtype=bool)

In [111]: contours[valid]
Out[111]: 
array([[[803, 772]],
       [[210, 490]],
       [[763, 747]],
       [[678, 200]],
       [[816, 444]],
       [[528, 817]],
       [[140, 440]]])

如果你想在 X 和 Y 上使用不同的剪辑,那么你可以使用

(contours>[xmin,ymin])&(contours<[xmax,ymax])

改为。

【讨论】:

  • 感谢您的解决方案和解释。现在像魅力一样工作:)
  • 我将允许自己一个简短的后续问题:如果我想为每个轴设置不同的阈值怎么办?据我了解, all() 需要一个可迭代对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-19
  • 2022-12-15
  • 1970-01-01
  • 2020-08-28
  • 1970-01-01
  • 1970-01-01
  • 2018-01-13
相关资源
最近更新 更多