【问题标题】:updated:IndexError: index 0 is out of bounds for axis 0 with size 0?更新:IndexError:索引 0 超出轴 0 的范围,大小为 0?
【发布时间】:2020-04-24 06:21:27
【问题描述】:

我对以下代码有疑问: 我想在这个函数中返回 2 个值,一个是 orig_image 很好,另一个是 cx,cx 是最大轮廓中心的 x 坐标,它是一定范围内的区域。终端说“ValueError:解压的值太多(预期为 2)”。(已解决) 下一个问题弹出:“IndexError: index 0 is out of bounds for axis 0 with size 0?” 可以知道原因和解决方法吗?非常感谢!

def findContours(image):
    orig_image = image.copy()
    image2 = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    ret, image2 = cv2.threshold(image2, 127, 255, 1)
    image2 = cv2.Canny(image2,30,200)
    # Find contours 
    contours, hierarchy = cv2.findContours(image2.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    max_area = 200000000000000
    min_area = 100
    areaList=[]
    cxList=[]
    if contours is not None:
        for c in contours:    

            area = cv2.contourArea(c)
            if min_area < area < max_area:
                areaList.append(area)
                approx = cv2.approxPolyDP(c, 0.03*cv2.arcLength(c,True),False)

                cv2.drawContours(orig_image, [c], 0,(0,255,0), -1)
                # cv2.drawContours(orig_image, [c], 0,(225,0,0), -1)
                x,y,w,h = cv2.boundingRect(c)
                # cv2.rectangle(orig_image3,(x,y),(x+w,y+h),(0,0,255),2)
                cx=x+int(w/2)
                cxList.append(cx)
                cy=y+int(h/2)
                cv2.circle(orig_image, (cx,cy), 5, (0,0,255), -1) 
        if areaList:    
            maxArea=max(areaList)
            index=np.where(areaList==maxArea)
            targetCx= cxList[index[0][0]]
            return targetCx #this is where the problem occur

    return orig_image #this is where the problem occur

def main():
       targetCx , original_image = findContours(original_image) #this is where 
       the problem occur

终端:

targetCx , original_image = findContours(original_image)
ValueError: too many values to unpack (expected 2)

如果我将最后一部分更改为:

if areaList:    
        maxArea=max(areaList)
        index=np.where(areaList==maxArea)
        targetCx= cxList[index[0][0]]
        return targetCx
else:
        return None
return orig_image 

终端节目:

targetCx , original_image = findContours(original_image)
TypeError: cannot unpack non-iterable NoneType object

更新

def findContours(image):
    orig_image = image
    image2 = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    ret, image2 = cv2.threshold(image2, 127, 255, 1)
    image2 = cv2.Canny(image2,30,200)
    # Find contours 
    contours, hierarchy = cv2.findContours(image2.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    max_area = 200000000000000
    min_area = 100
    areaList=[]
    cxList=[]
    targetCx =None
    if contours is not None:
        for c in contours:    

            area = cv2.contourArea(c)
            if min_area < area < max_area:
                areaList.append(area)
                approx = cv2.approxPolyDP(c, 0.03*cv2.arcLength(c,True),False)

                cv2.drawContours(orig_image, [c], 0,(0,255,0), -1)
                # cv2.drawContours(orig_image, [c], 0,(225,0,0), -1)
                x,y,w,h = cv2.boundingRect(c)
                # cv2.rectangle(orig_image3,(x,y),(x+w,y+h),(0,0,255),2)
                cx=x+int(w/2)
                cxList.append(cx)
                cy=y+int(h/2)
                cv2.circle(orig_image, (cx,cy), 5, (0,0,255), -1) 

    if areaList:
        maxArea=max(areaList)
        index=np.where(areaList==maxArea)
        targetCx = cxList[index[0][0]]

    return targetCx,orig_image

终端:

targetCx = cxList[index[0][0]]
IndexError: index 0 is out of bounds for axis 0 with size 0

【问题讨论】:

  • 你能分享错误来自哪一行吗?
  • 好的,我已经添加了,请看一下thx!
  • 根据 OpenCV 版本,findContours 具有不同的返回签名。在 OpenCV 3.4.X 中它返回 3 个项目,而 OpenCV 4.1.X 返回 2 个项目。查看this post了解更多信息
  • where 可能没有找到任何真实值。单独看index。
  • 测试shoulds 的唯一方法是debug 或打印一些中间值。我不信任 shoulds,我的或其他任何人的。

标签: python numpy opencv matplotlib image-processing


【解决方案1】:

根据documentation,cv2.findContours() 函数返回3个值(图像、轮廓、层次结构)。

但您只尝试解包轮廓和层次结构,这会出错。
要解决此问题,请将您的代码更改为 image, contours, hierarchy = cv2.findContours()。
或者只是做_, contours, hierarchy = cv2.findContours() 不使用返回的图像。

更新
写第一个答案时更改了原始问题。
错误消息显示I(Python) expected function call will returns exactly two values, but actually more than two are returned。

findContours 函数的返回值可以是多种形式:None、targetCx、orig_image。
在您的函数调用端,您假设 findContours 函数准确返回两个返回值,tagetCx 和 original_image。

如果返回None,python 无法将其分发给您的变量(targetCx,original_image),因为None 不可迭代。 我不知道targetCx返回值是什么,可能targetCx的长度大于2。

建议
我想你想同时获得 targetCx 和 original_image。
为此,您应该像这样更改代码:

# ... code ...
targetCx = None  # Add this line
if contours is not None:
  # ... code ...
  # Remove all return statements inside function body
return targetCx, orig_image  # Change return orig_image to this

我希望这会有所帮助。

【讨论】:

  • 谢谢,不过好像我改成_, contours, hierarchy = cv2.findContours()好像没问题,终端显示ValueError: not enough values to unpack (expected 3, got 2)
  • 谢谢你我试过了,但还是有问题,targetCx = cxList[index[0][0]] IndexError: index 0 is out of bounds for axis 0 with size 0,但是我们正在取得进展,我已经更新了问题,请看一下。
【解决方案2】:

从技术上讲,您的函数一次只返回一项。当一个返回被击中时,该函数退出。所以这是一个很好的例子,有双重回报,并在每个部分留下一个 None。 IE。 -

...
    if areaList:    
        maxArea=max(areaList)
        index=np.where(areaList==maxArea)
        targetCx= cxList[index[0][0]]
        return (None, targetCx) #x-coord is second

return (orig_image, None) #orig_image is first

然后进行检查以确定您使用哪个分支。这样你就可以解压两个值(一个是None),返回不是问题。

original_image, targetCx = findContours(original_image)
if original_image is not None: 
    # do stuff with original_image
else:
    # do stuff with targetCx

如果有帮助,请告诉我!

【讨论】:

  • 谢谢 试过了还是有问题,targetCx = cxList[index[0][0]] IndexError: index 0 is out of bounds for axis 0 with size 0,已经搜索过了,还是不知道怎么解决。
  • 您是否曾将cxList 设置为除cxList=[] 以外的任何值?因为如果不是,那是一个关键问题,并解释了您遇到的问题。如果您从未将其设置为等于其他任何内容,或者通过cxList.append(&lt;thing&gt;) 添加任何内容,那么cxList[index[0][0]] 将永远不会有任何内容。另外值得注意的是index在[0]没有任何东西或index[0]在[0]没有任何东西的选项。
  • 是的,我首先使用if areaList:来确保cxList里面有东西,因为cxList只是我找到的轮廓的x坐标,cxList的长度应该和areaList一样,所以如果areaList不是 None 那么 cxList 也不应该是 None 。我想找到最大的controur(最大面积)并将其x坐标设置为targetCx。
  • 好的,我错过了嵌套 if 中的追加行。可能还有另外几个问题。如果contours 什么都不是,那就完蛋了。更复杂的是,即使contours 为无,您设置了areaList=[],所以它不再是None。您是否尝试在使用这些物品之前将它们打印出来?阿拉:python if areaList: print(areaList) maxArea=max(areaList) print(maxArea) index=np.where(areaList==maxArea) print(index[0][0]) targetCx= cxList[index[0][0]] return targetCx,orig_image
猜你喜欢
  • 1970-01-01
  • 2022-01-13
  • 2019-04-01
  • 2017-02-16
  • 2021-11-03
  • 2016-07-29
  • 2021-07-17
  • 2021-05-24
  • 2018-07-23
相关资源
最近更新 更多