Python: 显示图像直到点击鼠标按钮

Python: show image until mouse button is clicked

我正在使用 Python 3.8 编写代码,要求用户在图像出现后立即按下按钮。然后图像会以 1 到 4 秒的随机间隔替换为白色屏幕,直到出现新图像。我使用 cv2.waitKey() 直到按下 space 栏:没问题,工作正常。见下文:

    import sys, cv2, random

    im = cv2.imread('image.tiff')                    
    imBlank = cv2.imread('imageBlank.tiff')            
    cv2.namedWindow('win', cv2.WINDOW_NORMAL) 

    for i in range(5):           # create a loop that runs 5 times
        cv2.imshow('win', im)    # show the image
        k = cv2.waitKey(0)       # wait until key press           
        if k == 32:              # when space bar is pressed
            cv2.imshow('win', imBlank)  # show a blank screen
            SI = random.randint(1,4)    # random interval between 1 and 4 seconds
            cv2.waitKey(SI*1000)        # wait for random interval until loop starts again

现在的问题是我想做的正是这个,但我希望用户按下鼠标按钮而不是 space 栏。据我所知,cv2.waitKey() 函数不适用于鼠标,因此我编写了以下代码:

    def showBlank(event, x, y, flags, param):
        if event == cv2.EVENT_LBUTTONDOWN:
            cv2.imshow('win', imBlank)
        elif event == cv2.EVENT_RBUTTONDOWN:
            cv2.imshow('win', imBlank)              
            
    # repeat the loop 5 times
    for i in range(5):
        cv2.imshow('win', im)                       # show the image
        cv2.setMouseCallback('win', showBlank)      # go to function showBlank()
        """ wait here until mouse button is clicked"""
        SI = random.randint(1,4)                    # random interval between 1 and 4 seconds
        cv2.waitKey(SI*1000)                        # wait for random interval until loop starts again

同样,这段代码基本上可以工作,但如果用户不按下鼠标按钮,循环仍然保持 运行。我希望循环等待随机间隔开始,直到单击鼠标。

谢谢!我希望有人能在这里帮助我

我使用 Python 3.8.0.

开发了这个在我的电脑上运行的解决方案
import sys, cv2, random

def swapImages():
    cv2.imshow('win', imBlank)
    SI = random.randint(1,4)
    cv2.waitKey(SI*1000)
    cv2.imshow('win', im)    

def showBlank(event, x, y, flags, param):
    #param is the array i from below
    if event == cv2.EVENT_LBUTTONDOWN:
        print("showBlank: i[0]: ", param)
        swapImages()
        param[0] = param[0] + 1
    elif event == cv2.EVENT_RBUTTONDOWN:
        print("showBlank: i[0]: ", param)
        swapImages()
        param[0] = param[0] + 1
                    
im = cv2.imread('image.tiff')                    
imBlank = cv2.imread('imageBlank.tiff')            
cv2.namedWindow('win', cv2.WINDOW_NORMAL) 

i = [0]
# the mousecallback only needs to be set once
cv2.setMouseCallback('win', showBlank, i )
        
# show the initial image for the first time.
cv2.imshow('win', im)

while i[0] < 5:    
  cv2.waitKey(10)

根据this,不可能以同样的方式等待鼠标点击,可以等待键盘输入。因此,我需要稍微修改一下原始代码。上面代码的作用是 运行 一个 while 循环,直到变量 i[0] 达到值 5。每次 i[0] 增加,图像被点击。

对代码的一些解释:

数组

i = [0]

通过“param”参数传递给鼠标回调。

cv2.setMouseCallback('win', showBlank, i )

this所述,“i”需要是一个容器,因为

Python passes references to objects. Inside your function you have an object -- You're free to mutate that object (if possible). However, integers are immutable. One workaround is to pass the integer in a container which can be mutated

i[0] 在每次鼠标事件时发生变化

param[0] = param[0] + 1

当i[0]达到5时,while循环结束