Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 需要使用轮廓检测图像的第二个极值点_Python_Image_Opencv_Image Processing - Fatal编程技术网

Python 需要使用轮廓检测图像的第二个极值点

Python 需要使用轮廓检测图像的第二个极值点,python,image,opencv,image-processing,Python,Image,Opencv,Image Processing,我正在尝试使用轮廓检测图像的第二个极值点 我试着做下面的事情 我正在寻找图像的所有轮廓 对等高线NumPy数组进行排序 删除NUMPY数组中的最后一个元素以去除外部轮廓,以免在极值点检测中考虑。李> 选择极值点 代码如下: import imutils import cv2 import numpy as np image = cv2.imread(r"SimpleBoxTest.png") gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) gray

我正在尝试使用轮廓检测图像的第二个极值点

我试着做下面的事情

  • 我正在寻找图像的所有轮廓
  • 对等高线NumPy数组进行排序
  • 删除NUMPY数组中的最后一个元素以去除外部轮廓,以免在极值点检测中考虑。李>
  • 选择极值点
  • 代码如下:

    import imutils
    import cv2
    import numpy as np
    
    image = cv2.imread(r"SimpleBoxTest.png")
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (5, 5), 0)
    
    thresh = cv2.threshold(gray, 45, 255, cv2.THRESH_BINARY)[1]
    thresh = cv2.erode(thresh, None, iterations=2)
    thresh = cv2.dilate(thresh, None, iterations=2)
    
    cnts = cv2.findContours(thresh.copy(), cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    cnts = imutils.grab_contours(cnts)
    
    c=sorted(cnts, key=cv2.contourArea)
    c = np.delete(c, (-1), axis=0) 
    
    extLeft = tuple(c[c[:, :, 0].argmin()][0])
    extRight = tuple(c[c[:, :, 0].argmax()][0])
    extTop = tuple(c[c[:, :, 1].argmin()][0])
    extBot = tuple(c[c[:, :, 1].argmax()][0])
    
    下面是错误

    Traceback (most recent call last):
      File "C:/TestCode/DocumentLayoutDetection/extreamPoints.py", line 41, in <module>
        extLeft = tuple(c[c[:, :, 0].argmin()][0])
    IndexError: too many indices for array
    
    回溯(最近一次呼叫最后一次):
    文件“C:/TestCode/DocumentLayoutDetection/extreamPoints.py”,第41行,在
    extLeft=tuple(c[c[:,:,0].argmin()][0])
    索引器:数组的索引太多
    
    下面的图片只是一个参考图片,我会尝试其他图片也

    图2

    变量c是数组的列表,因此添加for循环以对其进行迭代。 这解决了错误:

    for d in c:
        extLeft = tuple(d[d[:, :, 0].argmin()][0])
        extRight = tuple(d[d[:, :, 0].argmax()][0])
        extTop = tuple(d[d[:, :, 1].argmin()][0])
        extBot = tuple(d[d[:, :, 1].argmax()][0])
    

    您不需要删除最后一个元素,您可以从末尾获取第二个元素

    • c=sorted(cnts,key=cv2.contourArea)的结果
      不是一个NumPy数组,而是一个列表
      您可以使用
      type(c)
      检查类型,结果是

      您可以使用
      del
      delc[-1]
      删除最后一个元素,但不必这样做
    • 使用:
      c=c[-2]
      提取列表的最后一个元素。
      现在
      类型(c)
    • 使用
      extLeft=c[:,:,0].min()和
      extRight=c[:,:,0].max()查找最小值和最大值
      
    代码如下:

    import imutils
    import cv2
    import numpy as np
    
    image = cv2.imread(r"SimpleBoxTest.png")
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (5, 5), 0)
    
    thresh = cv2.threshold(gray, 45, 255, cv2.THRESH_BINARY)[1]
    thresh = cv2.erode(thresh, None, iterations=2)
    thresh = cv2.dilate(thresh, None, iterations=2)
    
    cnts = cv2.findContours(thresh.copy(), cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    cnts = imutils.grab_contours(cnts)
    
    c=sorted(cnts, key=cv2.contourArea)
    
    #c = np.delete(c, (-1), axis=0) 
    
    # c is a list, and not a numpy array, so use del instead of np.delete
    # But why?
    # del c[-1]
    
    # Get one element before the last element in the list
    c = c[-2] # Now c is a numpy.ndarray
    
    extLeft = c[:, :, 0].min()
    extRight = c[:, :, 0].max()
    extTop = c[:, :, 1].min()
    extBot = c[:, :, 1].max()
    
    # Draw rectangle for testing
    cv2.rectangle(image, (extLeft, extTop), (extRight, extBot), (0, 255, 0))
    
    cv2.imshow("image", image)
    cv2.waitKey()
    cv2.destroyAllWindows();
    

    更新: 如果需要找到所有等高线中的第二个极值点,可以在
    c
    中迭代等高线:

    # Mark all contours with red:
    cv2.drawContours(image, cnts, -1, (0, 0, 255), thickness=5)
    
    # Delete last element of the list
    del c[-1]
    
    # Initialize:
    extLeft, extRight, extTop, extBot = 1e9, -1e9, 1e9, -1e9
    
    # Iterate list and find the extreme points
    for cc in c:
        extLeft = min(cc[:, :, 0].min(), extLeft)
        extRight = max(cc[:, :, 0].max(), extRight)
        extTop = min(cc[:, :, 1].min(), extTop)
        extBot = max(cc[:, :, 1].max(), extBot)
    
    # Draw rectangle for testing
    cv2.rectangle(image, (extLeft, extTop), (extRight, extBot), (0, 255, 0), thickness=5)
    

    不使用for循环的解决方案:

    • 您可以使用
      np.vstack(c)
      连接列表中的NumPy数组。
      然后找到连接数组中的极值点
    代码:

    # Delete last element of the list.
    del c[-1]
    
    # Concatenate arrays along vertical axis.
    c = np.vstack(c)
    
    # Find extreme points:
    extLeft = c[:, :, 0].min()
    extRight = c[:, :, 0].max()
    extTop = c[:, :, 1].min()
    extBot = c[:, :, 1].max()
    

    结果:

    谢谢你的回答。我在其他图像上尝试了相同的代码,当有一个充满文本的页面时,获取极值点是主要目的。这段代码在这种情况下没有帮助。我将为同一个问题添加一个参考图像。是啊!我今天把它理解为列表。您可以绘制所有轮廓:
    cv2。绘制轮廓(图像,CNT,-1,(0,0,255),厚度=5)
    。结果看起来像。绿色框位于第二大轮廓周围。“图像的第二个极端点”是什么?我更新了我的帖子。我希望这就是你的意思。我喜欢你用优化代码解决问题的方式。事实上,我在当天晚些时候以一种非常复杂的方式解决了这个问题。但这是最好的解决办法。是的!这是一个列表,但是,当我们喜欢上面的代码时,我们将无法找到极值点,因为它将有最后一个列表的极值点。