Python OpenCV:按键时刷新图像

0 投票
2 回答
9494 浏览
提问于 2025-04-18 01:18

我用 Python 的 opencv2 模块开发了一个程序。

这个程序会在按下某个键的时候上传一张图片。

下面是伪代码:

 import cv2
    from msvcrt import getch


    while True:

    k = getch()

    if k == 'w':

          img = cv2.imread(filedir + orange.jpg)
          cv2.namedWindow
          cv2.imshow(img)
          waitkey()
          destroyAllWindows

    elif k == 'a'

          img = cv2.imread(filedir + banana.jpg)
          cv2.namedWindow
          cv2.imshow(img)
          waitkey()
          destroyAllWindows

这段代码很简单明了,我的意思是当按下 'w' 键时,程序会尝试上传一个名为 'orange.jpg' 的文件。

我真正想问的是:如何设计这个程序,让用户只需要按一次键就能完成操作?现在的设计是,按一次键关闭图片,再按一次键打开图片。我希望用户只需按一次键就能完成处理。比如,如果用户按下 'w',而 'orange.jpg' 已经上传了,程序应该刷新这个文件,而不是关闭它。再比如,当用户按下 'a',如果 'orange.jpg' 正在打开,程序应该自动关闭 'orange.jpg',然后打开 'banana.jpg',这一切都应该只需要一次操作。目前,我需要按两次键才能完成这个任务。

我已经实现了代码,所以即使有人建议我去用 pygtk 通过按键上传图片,我也没问题。我的唯一目标是让上传的图片在用户干预很少的情况下被关闭,也就是说,处理过程应该看起来是自动的。

正如 beark 所说,使用 getch() 的话,程序的焦点总是在控制台上。我对此不太满意,因为我只想通过按键上传图片,但控制台却妨碍了这个操作。

谢谢。

2 个回答

1

我已经解决了这个问题:

import sys
import cv2
import os

def main():

    File_Lst =[]

    plat = sys.platform
    #print plat

    if plat == 'win32': #for windows operating system

        File_dir = "C:\\Users\\user\\Desktop\\fruit\\"


    elif plat == 'linux2': # for linux

        File_dir = "/host/Users/user/Desktop/fruit/"

    for file in os.listdir(File_dir):

        File_Lst.append(file)

    print File_Lst


    welcome_index = File_Lst.index('welcome.jpg')           
    welcome_str = File_Lst[welcome_index]

    orange_index = File_Lst.index('orange.jpg')         
    orange_str = File_Lst[orange_index]


    apple_index = File_Lst.index('apple.jpg')           
    apple_str = File_Lst[apple_index]

    banana_index = File_Lst.index('banana.jpg')         
    banana_str = File_Lst[banana_index]

    doughnuts_index = File_Lst.index('doughnuts.jpg')           
    doughnuts_str = File_Lst[doughnuts_index]

    img = cv2.imread(File_dir + welcome_str )
    cv2.destroyAllWindows()         
    cv2.imshow("Press KEYS to know which food is good or bad", img)

    while True:

        k = cv2.waitKey(0)

        if k == ord('w'): # wait for 'w' key to upload orange nutrition information

            img = cv2.imread(File_dir + orange_str) 
            newx,newy = img.shape[1]/2,img.shape[0]/2 #new size (w,h)
            img = cv2.resize(img,(newx,newy))
            cv2.destroyAllWindows()     
            cv2.imshow("Orange Nutritional Information", img)

        elif k == ord('a'): # wait for 'w' key to upload apple nutrition information

            img = cv2.imread(File_dir + apple_str)  
            newx,newy = img.shape[1]/2,img.shape[0]/2 #new size (w,h)
            img = cv2.resize(img,(newx,newy))
            cv2.destroyAllWindows()     
            cv2.imshow("Apple Nutritional Information", img)

        elif k == ord('s'): # wait for 'w' key to upload apple nutrition information

            img = cv2.imread(File_dir + banana_str) 
            newx,newy = img.shape[1]/2,img.shape[0]/2 #new size (w,h)
            img = cv2.resize(img,(newx,newy))
            cv2.destroyAllWindows()     
            cv2.imshow("Banana Nutritional Information", img)


        elif k == 32:

            break
            cv2.destroyAllWindows()

        else:

            img = cv2.imread(File_dir + doughnuts_str)
            cv2.destroyAllWindows()
            cv2.imshow("Bad, Have good eating habits CHUMP", img)
            continue    







main()

我每次显示图片的时候都会销毁窗口,这样可以确保每次按键都对应到最新上传的图片。

6

首先,去掉 getch() 这个函数。因为它只在控制台窗口有焦点的时候才能工作,这样的做法不太灵活。

可以用 waitKey() 来代替:

import cv2 

cv2.namedWindow("lala")
img = cv2.imread(filedir + orange.jpg) # load initial image

while True:
    cv2.imshow("lala", img)

    # The function waitKey waits for a key event infinitely (when delay<=0)
    k = chr(cv2.waitKey(100)) 
    if k == 'w':                       # toggle current image
        img = cv2.imread(filedir + orange.jpg)
    elif k == 'a':
        img = cv2.imread(filedir + banana.jpg)
    elif k == 27:  #escape key 
        break


cv2.destroyAllWindows()

撰写回答