關於ndarray的變量賦值與深淺copy,網上資料很多。
主要三點:
1、賦值
a = numpy.zeros((1, 1, 1), numpy.uint8)
b = a # 他兩個是一回事,修改a的內容, b會跟着變.
2、深copy
b=numpy.copy(a) # b和a初始值一樣,但沒有其他關係了, 修改a的內容,b不變
3、淺copy
b = numpy.view(a) # 據說這是淺copy, 不過我還沒測試真假
但是我的需求這三個都滿足不了。
我在用opencv做畫圖工具時,做拖動畫矩形的功能, 拖動狀態爲了體驗好,實時繪製矩形, 但是如果不消除預覽的矩形, 就會繪製出很多個矩形。
所以需要保存最初的 ndarray對象, 及時復原該對象, 避免繪製很多矩形。
這裏需要用的是逐項copy:
b[:] = a[:]
嘿嘿。
完整繪製代碼如下:
import numpy as np
import cv2 as cv
drawing = False # 如果 True 是鼠標按下
mode = True # 如果 True,畫矩形,按下‘m’切換到曲線
ix, iy = -1, -1
# 鼠標回調函數
def draw_circle(event, x, y, flags, param):
global ix, iy, drawing, mode, img, img2
if event == cv.EVENT_LBUTTONDOWN:
drawing = True
ix, iy = x, y
#img2 = img[:]
elif event == cv.EVENT_MOUSEMOVE:
if drawing == True:
img[:] = img2[:]
if mode == True:
cv.rectangle(img, (ix, iy), (x, y), (0, 255, 0), 1)
else:
cv.circle(img, (x, y), 5, (0, 0, 255), -1)
elif event == cv.EVENT_LBUTTONUP:
drawing = False
img[:] = img2[:]
if mode == True:
cv.rectangle(img, (ix, iy), (x, y), (0, 255, 0), 1)
else:
cv.circle(img, (x, y), 5, (0, 0, 255), -1)
img2[:] = img[:]
# 創建一個黑色圖像,一個窗口,然後和回調綁定
img = np.zeros((512, 512, 3), np.uint8)
img2 = np.copy(img)
cv.namedWindow('image')
cv.setMouseCallback('image', draw_circle)
while(1):
cv.imshow('image', img)
k = cv.waitKey(1) & 0xFF
if k == ord('m'):
mode = not mode
elif k == 27:
break
cv.destroyAllWindows()