【问题标题】:max, min value of list of lists at 1st column第一列列表列表的最大值、最小值
【发布时间】:2016-09-04 04:59:12
【问题描述】:

假设我有一个列表列表。例如,

([[[362, 239]], [[362, 367]], [[386, 367]], [[386, 239]]])

如何分别获取第 1 列和第 2 列的最大值?

这个例子的答案应该是:

col1_max = 386, col2_max = 367

我已经试过了:

col1_max = max(cnts.iteritems(), key=operator.itemgetter(1))[0]
print col1_max

但在这里我得到了只是

errorcode: "AttributeError: 'list' object has no attribute 'iteritems'"

更新:

我会用不同的方式重新表述我的问题 现在我想写一个代码来

  • 检测对象

  • 这些的中心

目前的代码是:

import imutils
import cv2
import os, os.path

DIR = 'pics/'
numberOfPictures = len([name for name in os.listdir(DIR) if os.path.isfile(os.path.join(DIR, name))])

for i in range(0, numberOfPictures):
    image = cv2.imread('pics/' + str(i) + '.png', 0)
    thresh = cv2.threshold(image, 60, 255, cv2.THRESH_BINARY)[1]
    
    cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if imutils.is_cv2() else cnts[1]
    
    j = 1
    
    for c in cnts:
        M = cv2.moments(c)
        
        if M["m00"] != 0:
            cX = int(M["m10"] / M["m00"])
            cY = int(M["m01"] / M["m00"])
            
        else:
            continue
        
        print cnts
          
        j = j + 1
    
        cv2.drawContours(image, [c], -1, (0, 255, 0), 2)
        cv2.circle(image, (cX, cY), 7, (255, 255, 255), -1)
        cv2.putText(image, "center", (cX - 20, cY - 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)
    
        cv2.imshow("Image", image)
        cv2.waitKey(0)
        cv2.destroyAllWindows()

仅此一项效果很好,但现在我想从 cnts 中获取最大值和最小值。

我使用 cv2.findContours 来创建我的 cnts

cnts = [array([[[362, 239]], [[362, 367]], [[386, 367]], [[386, 239]]])]

如何提取第一列的最大值和第二列的最大值?

【问题讨论】:

  • 这实际上是一个列表列表..这是故意的吗?

标签: python opencv contour


【解决方案1】:

如果您的输入是列表列表(与示例中的不同),这应该可以:

li = [[362, 239], [362, 367], [386, 367], [386, 239]]

def get_max_by_col(li, col):
    # col - 1 is used to 'hide' the fact lists' indexes are zero-based from the caller
    return max(li, key=lambda x: x[col - 1])[col - 1]

print(get_max_by_col(li, 1))
>> 386

print(get_max_by_col(li, 2))
>> 367

更新如果您确实有列表列表,请更改行
return max(li, key=lambda x: x[col - 1])[col - 1]
在上面的代码中
return max(li, key=lambda x: x[0][col - 1])[0][col - 1].

【讨论】:

  • 好的,我会试试的,但是如果我有一个列表,你是什么意思?不是这个吗?
  • @M.Wittig,不,[[[362, 239]], [[362, 367]], [[386, 367]], [[386, 239]]] 是列表的列表
  • 啊,我明白了,这种情况下可能的解决方案是什么?对不起,我是 python 的新手 ^^
  • 我使用了你的代码,但我得到的一切都是 >>"return max(cnts, key=lambda x: x[0][col - 1])[0][col - 1] IndexError:索引 1 超出轴 0 的范围,大小为 1"
  • @M.Wittig cnts 是什么?此代码适用于[[[362, 239]], [[362, 367]], [[386, 367]], [[386, 239]]]
【解决方案2】:

我知道这是一个老问题,但是 您还可以使用 numpy 的超快速内置函数之一: np.argmax(data, axis=0), 这将返回所有列中的第一个最大出现次数,请参阅numpy documentation

【讨论】:

    【解决方案3】:

    我自己做的

    但我还是想给出可能的答案

    import imutils
    import cv2
    import os, os.path
    
    
    DIR = 'pics/'
    numberOfPictures = len([name for name in os.listdir(DIR) if os.path.isfile(os.path.join(DIR, name))])
    
    for i in range(0, numberOfPictures):
    
        image = cv2.imread('pics/' + str(i) + '.png', 0)
        thresh = cv2.threshold(image, 60, 255, cv2.THRESH_BINARY)[1]
        
        cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        cnts = cnts[0] if imutils.is_cv2() else cnts[1]
        
        j = 1
        
        for c in cnts:
            M = cv2.moments(c)
            
            if M["m00"] != 0:
                cX = int(M["m10"] / M["m00"])
                cY = int(M["m01"] / M["m00"])
                
            else:
                continue
    
            def get_max_by_col(c, col):
                return max(c, key=lambda x: x[0][col - 1])[0][col - 1]
    
            print(get_max_by_col(c, 1))
            print(get_max_by_col(c, 2))
            
            j = j + 1
        
            cv2.drawContours(image, [c], -1, (0, 255, 0), 2)
            cv2.circle(image, (cX, cY), 7, (255, 255, 255), -1)
            cv2.putText(image, "center", (cX - 20, cY - 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)
        
            cv2.imshow("Image", image)
            cv2.waitKey(0)
            cv2.destroyAllWindows()
    

    我得到 386 和 367 作为最大值

    c = [[[362 239]], [[362 367]], [[386 367]], [[386 239]]]

    【讨论】:

      猜你喜欢
      • 2013-12-27
      • 2018-03-05
      • 2023-03-29
      • 1970-01-01
      • 2013-04-08
      • 1970-01-01
      • 2017-10-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多