ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Project_AF] 자동초점 현미경 개발기 (5) - GUI
    Ort Lab 2020. 3. 6. 00:24

    저번 글(4)까지 해서 자동초점을 위한 준비는 끝이 났습니다. 이제 이를 이용해서 본격적으로 프로그램을 제작해야죠!

    그런의미로 오늘은 GUI를 제작할 예정입니다.

     

    일단 GUI에 기본적으로 들어가야할 기능을 선정해봅시다.

     

    기본적인 기능은 초점을 잡는것이니, 초점을 잡는 기능은 있어야겠고.. 필요할 경우 제물대의 높이를 버튼으로 조종할 수 있도록 해야겠군요. 그리고 접안렌즈쪽은 카메라가 있으니, gui 자체에서 카메라 화면을 크게 보여주는 것도 중요하겠군요. 또한 연구용으로 쓰려면 촬영이 중요하니.. 프로그램 자체에 현재 카메라화면을 스크린샷해서 원하는 이름으로 저장해주는 기능도 있어야겠군요. 

     

    대충 GUI를 디자인해보자면..

    gui모식도

    네 이렇습니다. 붉은색으로 숫자를 써놓았으니.. 하나하나 짚어보면

     

    1. 이 큼직한 장소에 카메라의 이미지가 뜰겁니다. 즉 현미경으로 보는 화면이겠죠?

    2. 버튼입니다. 제물대를 위로 올리는 버튼입니다.

    3. 이게 중요한데.. 버튼 1번에 올리거나, 내릴정도를 입력하는 칸입니다. 0~100까지 입력가능합니다.

    4. 제물대를 아래로 내리는 버튼입니다.

    5. 이 버튼이 자동초점 버튼인데.. 이걸 누르면 자동으로 장치를 작동시켜 초점을 맞춥니다.

    6. 초기화 버튼입니다. 현재 제물대의 높이를 최대높이로 지정해주는겁니다.

    7. 좌측에는 저장할 파일의 이름을 써넣습니다. 우측 버튼을 누르면 그 이름으로 저장됩니다.

     

    위와 같습니다. 

    이걸 이제 코드화 시키자면..

    import PIL
    from PIL import Image,ImageTk
    import cv2
    from tkinter import *
    from tkinter import ttk
    import numpy as np
    
    cap = cv2.VideoCapture(1)
    
    cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
    
    window = Tk()
    window.title("AutoFocus Microscope")
    window.geometry("640x585")
    window.bind('<Escape>', lambda e: window.quit())
    GUI = Label(window)
    GUI.pack()
    
    graph = np.zeros((105,640, 3), np.uint8)
    cv2.rectangle(graph,(0, 0),(640, 105),(255,255,255),-1)
    cv2.rectangle(graph,(5, 5),(60, 100),(200,200,200),1)
    cv2.rectangle(graph,(353, 5),(633, 100),(200,200,200),1)
    
    
    
    move_step = ttk.Entry(window, width=5)
    move_step.place(x=12,y=522)
    
    save_name = ttk.Entry(window, width=15)
    save_name.place(x=360,y=552)
    num_sample = 100
    
    
    def Save_data():
        print('Save_data')
    
    
    def AF():
        print('AF')
    
    
    
    def settop():
        print('top')
    
    def up_step():
        print('up')
    
    def down_step():
        print('down')
    
    def show_frame():
    
        global graph
    
        ret, frame = cap.read()
        data = np.vstack((frame, graph))
    
        if ret:
    
            output_image = cv2.cvtColor(data, cv2.COLOR_BGR2RGBA)
            img = PIL.Image.fromarray(output_image)
            imgtk = ImageTk.PhotoImage(image=img)
            GUI.imgtk = imgtk
            GUI.configure(image=imgtk)
            GUI.after(10, show_frame)
    
    AF_button = ttk.Button(window, text="Auto Focuse", width=37, command=AF)
    AF_button.place(x=360,y=490)
    settop_button = ttk.Button(window, text="Set Top", width=37, command=settop)
    settop_button.place(x=360,y=520)
    save_button = ttk.Button(window, text="SAVE as", width=20, command=Save_data)
    save_button.place(x=480,y=550)
    up_button = ttk.Button(window, text="▲", width=5,command=up_step)
    up_button.place(x=10,y=490)
    down_button = ttk.Button(window, text="▼", width=5,command=down_step)
    down_button.place(x=10,y=550)
    
    show_frame()
    window.mainloop()

    아하하ㅏ하하하하하하하하하핳핳<퍽 

    일단 편한대로 tkinter를 이용해서 구현하였고요.. 

    GUI tkinter는 event-driven인데요, event-driven은 특정이벤트(버튼이 눌리거나)가 발생할때까지 기다렸다 이벤트가 발생할 경우 실행되는방식입니다.

    아 이거 설명해야되나요 ㅋㅋㅋㅋㅋㅋ 떠올리기 싫은 기억인데 ㅋㅋㅋㅋㅋㅋㅋ

    그냥 대충만.. 하자면

     

    AF_button = ttk.Button(window, text="Auto Focuse", width=37, command=AF)

    밑에서부터 13번째 줄에 AF_button은 Auto Focus라고 적힌 길이 37짜리 버튼을 만드는겁니다. gui모식도에서 5번입니다. 이 버튼을 누를경우, AF함수를 실행시키는데 이를 위해서 위쪽에서 먼저 AF() 함수를 정의해두었습니다. 버튼은 이런식으로 제작하였습니다.

     

    move_step = ttk.Entry(window, width=5)

    입력창은 27번째 줄에서 move_step인데.. 이게 위에 gui모식도에서 3번입니다. 입력창은 Entry라는것을 사용하는데요, 이 Entry의 이름을 이용하여 나중에 move_step이라는 이름의 Entry에 적힌 문자열을 불러올수 있습니다.

     

    그리고 맨 아래에 show_frame()이란 함수가 웹캠의 데이터를 실시간으로 gui모식도의 1번에 띄워주는 역할을 합니다.

     

    이걸 실행시켜보면~

    요런 gui가 생성됩니다 와! (게임 스트리머들이 한다는 손캠 한번 해보았습니다)

    그리고 버튼을 누를때마다.. 터미널에서 보이듯이 해당 함수가 호출되어 print가 실행됩니다.

     

    이제 GUI는 끝났으니.. 다음부터는 각 버튼에 함수를 본격적으로 제작해보도록 하죠!

    댓글

Designed by Tistory.