【问题标题】:The values of a list in python change without me trying to change thempython中列表的值会发生变化,而我没有尝试更改它们
【发布时间】:2014-11-27 04:26:24
【问题描述】:

我正在尝试创建一个程序来阈值不同的颜色,并且在程序中我有一个返回上一个颜色范围的函数,但每次我尝试向列表中添加新值(minse,maxse)时保留这些旧值,然后列表中该特定颜色的所有列表都将转到新的附加列表。

import cv2
import numpy as np
import cPickle as pickle
from matplotlib import pyplot as plt

def nothing(x):
    pass

cap = cv2.VideoCapture(0)
cv2.namedWindow('image')
#last values
minse = [[],[],[]]
maxse = [[],[],[]]
p = 0
try:
    mins, maxs= pickle.load(open("varvid.p", "rb"))
except:
    mins = np.array([[255,255,255],[255,255,255],[255,255,255]])
    maxs = np.array([[0,0,0],[0,0,0],[0,0,0]])


cv2.createTrackbar('brush_size','image',1,10, nothing)
cv2.createTrackbar('vahe','image',0,50, nothing)


# mouse callback function
def choose_color(event,x,y,flags,param):
    global mins, maxs, minse, maxse, p, brush_size, vahe

    if event == cv2.EVENT_LBUTTONDOWN:
        nx = brush_size
        ny = brush_size
        pixs = hsv[y-ny:y+ny,x-nx:x+nx,:] 
        print minse[p]
        print mins[p]
        minse[p].append(mins[p])
        print minse[p]
        maxse[p].append(maxs[p])
        mins[p]=np.minimum(mins[p], pixs.min(0).min(0) - vahe).clip(0, 255).astype('uint8')
        print mins[p]
        maxs[p]=np.maximum(maxs[p], pixs.max(0).max(0) + vahe).clip(0, 255).astype('uint8')

#deletes lasts maxs and mins
def eelmised_varvid():
    global maxs, maxse, mins, minse, p
    try:    

        maxs[p] = maxse[p].pop()
        mins[p] = minse[p].pop()

    except:
        mins[p] = np.array([255,255,255])
        maxs[p] = np.array([0,0,0])

cv2.namedWindow('tava')
cv2.setMouseCallback('tava', choose_color)

print("For exiting press 'q', to save the values 's', ball colors - 'p', yellow - 'y' and blue -  'b', default is  the ball")

while(True):
    # Capture frame-by-frame
    ret, frame = cap.read()

    hsv = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV) 
    brush_size =cv2.getTrackbarPos('brush_size','image')
    vahe = cv2.getTrackbarPos('brush_size','image')

    # Display the resulting frame
    median = cv2.medianBlur(hsv,5)
    mask = cv2.inRange(hsv, mins[p], maxs[p])


    cv2.imshow('tava', median)
    cv2.imshow('mask', mask)
    k = cv2.waitKey(1) & 0xFF

    if k == ord('q'):
        break
    elif k == ord('p'):
        p = 0
    elif k == ord('y'):
        p = 1
    elif k == ord('b'):
        p = 2
    elif k == ord('s'):
        pickle.dump([mins,maxs], open("varvid.p", "wb"))
    elif k == ord('e'):
        eelmised_varvid()
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()

问题应该出在这部分代码上:

def choose_color(event,x,y,flags,param):
    global mins, maxs, minse, maxse, p, brush_size, vahe

    if event == cv2.EVENT_LBUTTONDOWN:
        nx = brush_size
        ny = brush_size
        pixs = hsv[y-ny:y+ny,x-nx:x+nx,:]
        print"The value that should be appended to the old value list:",mins[p]
        print"The old value list before appending:", minse[p]
        minse[p].append(mins[p])
        print"The old value list after appending:",minse[p]
        maxse[p].append(maxs[p])
        mins[p]=np.minimum(mins[p], pixs.min(0).min(0) - vahe).clip(0, 255).astype('uint8')
        maxs[p]=np.maximum(maxs[p], pixs.max(0).max(0) + vahe).clip(0, 255).astype('uint8')

还有一个例子:首先点击: 应附加到旧值列表的值:[255 255 255] 附加前的旧值列表:[] 附加后的旧值列表:[array([255, 255, 255])] 第二次点击: 应该附加到旧值列表的值:[84 33 237] 附加前的旧值列表:[array([ 84, 33, 237])] 追加后的旧值列表:[array([ 84, 33, 237]), array([ 84, 33, 237])]

编辑: 好吧,我尝试对其进行更多调试,发现这不是 .append() 函数的问题,而是出于某种原因,这行代码:

mins[p]=np.minimum(mins[p], pixs.min(0).min(0) - vahe).clip(0, 255).astype('uint8')

改变minse[p]的值

如有任何帮助,我们将不胜感激,并在此先感谢 :)

【问题讨论】:

  • 您应该尝试将代码缩小到相关区域,并尝试举一个例子(带有实际值)这将有助于我们理解您的问题。
  • 问题是什么?根据示例,附加工作正常,因为它正在附加。你预计会发生什么?
  • 问题在于它不仅会追加,而且还会将列表中的列表更改为我要追加到列表的列表,或者以某种方式更改旧值列表的值,但我没有不知道怎么做

标签: python list numpy append repeat


【解决方案1】:

问题是,Python 列表并不真正存储“数据”,它只是存储对其他对象的引用。您的问题可以减少:

list_ = []
thing = [0, 0]
list_.append(thing)
print list_
# [[0, 0]]

thing[0] = 1
list_.append(thing)
print list_
# [[1, 0], [1, 0]]

因此,当您执行上述操作时,您最终会得到一个类似[thing, thing] 的列表。 thing 的瞬时内容决定了 list_ 的内容显示的内容。

另外,请注意,当您现在这样做时:

thing = [2, 2]
list_.append(thing)
print list_
# [[1, 0], [1, 0], [2, 2]]

列表的旧内容没有改变,因为你没有改变 thing,或者更确切地说,标签“事物”所引用的对象。相反,您将 新对象 分配给标签“事物”,这不会与之前附加到该标签的对象混淆。

仅当放入列表(或其他集合类型)的内容是“可变”对象时,此行为才值得关注,例如listdict 或 Numpy 数组。有关更多信息,请参见例如this question.

解决方案:复制您放在列表中的对象。在你的情况下:

minse[p].append(mins[p].copy())

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-20
    • 2017-05-18
    • 2017-11-26
    • 1970-01-01
    • 2021-01-16
    • 2021-05-14
    • 1970-01-01
    • 2023-03-16
    相关资源
    最近更新 更多