1

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!

mooder
  • 341
  • 2
  • 8

1 Answers1

1

Create a NumPy array of zeros.

arr = np.zeros((5,2048,2048,3), dtype=np.uint8)

Now you can easily add your images to and get anyone you want. Suppose you want the last one then arr[4] should suffice.

Vardan Agarwal
  • 2,023
  • 2
  • 15
  • 27
  • How would you shift the [1:] arrays to [:-1], i.e. get rid of the first one and add a new one at the end? – mooder Jun 05 '20 at 18:02
  • Edited the post with working code. I was inspired by this: https://stackoverflow.com/questions/30399534/shift-elements-in-a-numpy-array – mooder Jun 05 '20 at 18:36