2017-02-19 104 views
2

我有一个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.从NumPy数组中删除值对

如何删除这样的值对?

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。我想忽略文字选择的偏离“噪音”。假设我不能进一步降噪。

+1

请创建一个[Minimal,Complete,and Verifiable](http://stackoverflow.com/help/mcve)示例。这使我们更容易帮助你。 –

回答

2

似乎轮廓形状是(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]) 

代替。

+0

感谢您的解决方案和解释。像现在的魅力:) – MrVocabulary

+0

我会允许我自己一个简短的后续问题:如果我想为每个轴设置不同的阈值,该怎么办?据我所知,所有()需要一个迭代。 – MrVocabulary

+1

我编辑这个案例的帖子。 –