我试图创建一个程序来限制不同的颜色,在程序中我有一个返回到最后颜色范围的功能,但每次我尝试向列表添加新值时(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]
的值任何帮助都会得到满足并提前感谢:)
答案 0 :(得分: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
,或者更确切地说,标签“thing”引用的对象。而是将新对象分配给标签“thing”,这不会弄乱先前附加到该标签的对象。
当列表中放入的内容(或其他集合类型)是“可变”对象时,这种行为只是一个问题,例如, list
,dict
或Numpy数组。有关详细信息,请参阅this question
解决方案:制作放在列表中的对象的副本。在你的情况下:
minse[p].append(mins[p].copy())