My image is a ndarray(2048, 2048, 3). I'd like to modify it and keep a copy (around 5) of the former version so I can reverse any modification done via click event.
In the code bellow, I am drawing circle for every click on the image. However, I'd like to store more than one image and remove the last one (pop()
) for each right click.
click_pts = []
def click(event, x, y, flags, param):
global click_pts, image, image_ref
if event == cv2.EVENT_LBUTTONDOWN:
click_pts.append((x, y))
image_ref = np.ndarray.copy(image)
cv2.circle(image, (x, y), 5, (255, 0, 0), -1)
cv2.imshow("image", image)
print((x, y))
elif event == cv2.EVENT_RBUTTONDOWN:
click_pts.pop()
image = np.ndarray.copy(image_ref)
cv2.imshow("image", image)
image = cv2.imread('images/RT1_2th.png')
image_ref = np.ndarray.copy(image)
cv2.namedWindow("image")
cv2.setMouseCallback("image", click)
# Loop until 'q' is pressed
while True:
cv2.imshow("image", image)
key = cv2.waitKey(1) & 0xFF
if key == ord('q'):
break
cv2.destroyAllWindows()
I failed to find any reliable way to store multiple image in an array... doesn't matter what type of array it is, but having .pop()
function would be great.
Also, (side note), in the OpenCV example, image
is not passed into the function and a click results in (if I remove global image
from click
):
UnboundLocalError: local variable 'image' referenced before assignment
I don't really like global variable, I wonder, what is the alternative? Edit: Added two functions handle the shifting. The lshift shifts to left and replace last image with a new one:
def lshift(arr, new_arr):
result = np.empty_like(arr)
result[:-1] = arr[1:]
result[-1] = new_arr
return result
def rshift(arr):
result = np.empty_like(arr)
result[1:] = arr[:-1]
result[0] = arr[0]
return result
It works pretty well but don't forget to use np.array.copy()
to pass by value the image that is drawn upon. Otherwise, it is passed by reference and you end up with the same copy of everything!