Python動態調節參數-滑動條-pygame和cv2

Python動態調節參數-滑動條-pygame和cv2

前言:

最近在整動態調參,然後每次修改參數,重啓啓動程序過於複雜,因此,結合網上資源,造了一個輪子,剛開始找到的是cv2的滑動條,然後發現,滑動條過於呆板,初始值設定,滑動條位置,以及最小值設定都不能調整。
就感覺很蠢,不適合我需要的從-90,90這樣的調節範圍。
因此想着thinkter能不能做,然後沒發現,最後找pygame這種做遊戲的,發現做的還可以。

由於時間不夠,簡單放一下代碼就好了, 大家隨便看看吧,不明白的debug一下就好了。

OpenCV的垃圾實現:

import cv2
import numpy as np
#定義回調函數,參數x爲函數cv2.createTrackbar()傳遞的滑塊位置對應的值
# 每次滑動, 都會調用這個函數, 但是我們用不上
def img_intensity_change_x(x):            
    pass
def img_intensity_change_y(y):            
    pass

img=np.zeros((512,512),dtype='uint8')
#新建一個窗口
cv2.namedWindow('img')
# 第一個參數是滑動杆名稱,第二個是對應的圖片,第三個是默認值,第四個是最大值,第五個是回調函數
cv2.createTrackbar('joint 1', 'img', 0, 40, img_intensity_change_x)
cv2.createTrackbar('joint 3', 'img', 0, 40, img_intensity_change_y)

while(1):
    img=np.zeros((512,512),dtype='uint8')
    # 拿到對應滑動杆的值
    x = cv2.getTrackbarPos('joint 1', 'img')
    y = cv2.getTrackbarPos('joint 3', 'img')
    # 對值進行需要的處理
    joint_1 = x - 20
    joint_3 = y - 20
    # print("x:", x)
    # print("y:", y)
    # 將數值寫到圖片當中。
    cv2.putText(img, 'joint 1:'+str(joint_1), (20, 20), fontFace=2, fontScale=1, color=(200, 0, 100), thickness=3 )
    cv2.putText(img, 'joint 3:'+str(joint_3), (20, 60), fontFace=2, fontScale=1, color=(200, 0, 100), thickness=3 )
    cv2.imshow('img',img)    
    # 每1毫秒刷新一次,當輸入q鍵的時候,結束整個主程序
    if cv2.waitKey(1)==ord('q'):
        break
    
cv2.destroyAllWindows()

在這裏插入圖片描述

pygame 動態調參:

import pygame
from pygame.locals import *
from sys import exit
import numpy as np
import cv2
import imutils

def create_scales(height, joints_num=3):
    #用於創建指定大小的圖像對象實例,分別表示紅,綠,藍三塊區域,主動實例化三個Surface對象
    # 參考的原代碼是紅綠藍三色,但是我需要的是七個滑動杆,所以加了一個參數
    surface_list = []
    for _ in range(joints_num):
        surface=pygame.surface.Surface((SCREEN_WIDTH,height))#與窗口Surface等寬,高度自行調整,下同
        surface_list.append(surface)
    
    for x in range(SCREEN_WIDTH):
        # 這裏面的函數是給滑動欄,加上顏色漸變,紅綠藍輪着來
        c=int((x/SCREEN_WIDTH)*255)
        # 每個x軸部分佔RGB顏色的多少,等同x*(255/640)
        red=(c,0,0)
        green=(0,c,0)
        blue=(0,0,c)
        color_list = [red, green, blue]
        line_rect=Rect(x,0,1,height)
        for i in range(joints_num):
            pygame.draw.rect(surface_list[i], color_list[i%len(color_list)], line_rect)
        
    return surface_list

def drawText(screen,text,posx,posy,textHeight=15,fontColor=(0,0,0),backgroudColor=(255,255,255)):
    fontObj = pygame.font.Font('freesansbold.ttf', textHeight)  # 通過字體文件獲得字體對象
    textSurfaceObj = fontObj.render(text, True,fontColor,backgroudColor)  # 配置要顯示的文字
    textRectObj = textSurfaceObj.get_rect()  # 獲得要顯示的對象的rect
    textRectObj.center = (posx, posy)  # 設置顯示對象的座標
    screen.blit(textSurfaceObj, textRectObj)  # 繪製字

def main():
    pygame.init()
    # 獲取筆記本攝像頭的視頻流
    cap = cv2.VideoCapture(0)    
    forucc = cv2.VideoWriter_fourcc(*'XVID')
    # 初始化pygame以及相關模塊
    screen=pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT), 0, 32)#返回一個窗口Surface對象
    surface_list = create_scales(rect_height, joints_num=joints_num)
    color=[127]*joints_num
    # joint_list可以換成你需要的參數列表,這裏設定的是默認值
    joint_list = [0]*joints_num
    # 初始化爲灰色
    while True:
        for event in pygame.event.get():
            if event.type==QUIT:
                pygame.quit()
                exit()                
        screen.fill((0,0,0))
        for i, surface in enumerate(surface_list):
            screen.blit(surface,(0, rect_height*i))
        # 獲取鼠標在窗口中的位置,這一步是交互的關鍵
        # 主程序必須要刷新的非常快,儘量在10毫秒之內完成纔行。要不然明顯卡頓
        x, y=pygame.mouse.get_pos()
        
        # 獲取鼠標按鈕狀態,get_pressed()[0]爲左鍵是否爲按下狀態,修改按下的數值
        if pygame.mouse.get_pressed()[0]:            
            for component in range(joints_num):
                #判斷是在哪個Surface對象(red_scale,green_scale,blue_scale)上移動鼠標
                if y > component*rect_height and y < (component+1)*rect_height:
                    #操作color列表,component爲索引值
                    color[component] = int((x/(SCREEN_WIDTH-1))*255)            
        # 先根據位置畫圓, 再在圓內標上數值
        for component in range(joints_num):
            pos = ( int((color[component]/255)*(SCREEN_WIDTH-1)), component*rect_height+rect_height//2 )
            pygame.draw.circle(screen, (255, 255, 255), pos[:3], rect_height//2)#繪製白色圓點.pos圓心座標,20爲圓半徑大小            
            joint_list[component] = np.round(180 * (pos[0] - SCREEN_WIDTH//2)/SCREEN_WIDTH, 1)
            drawText(screen, str(joint_list[component]), pos[0], pos[1])
 
        #在窗口標題上顯示參數元組
        pygame.display.set_caption("PyGame Joint Control - "+str(tuple(joint_list)))
        # get robot img stream from pc camera
        ret,robot_image = cap.read()
        if ret:
            # cv2.imshow("origin", robot_image)
            # cv2.waitKey(1)
            # 圖片可能需要旋轉,不需要的話就註釋掉
            robot_image = imutils.rotate(robot_image, 90, )
            robot_image=cv2.resize(robot_image, (SCREEN_HEIGHT-joints_num*rect_height, SCREEN_WIDTH))            
            
            my_surface = pygame.pixelcopy.make_surface(robot_image)
            screen.blit(my_surface,(0, rect_height*joints_num))
        my_surface = pygame.pixelcopy.make_surface(robot_image)
        screen.blit(my_surface,(0, rect_height*joints_num))
        pygame.display.update()
    cv2.destroyAllWindows()
    
if __name__=="__main__":
    #設置非全屏模式下窗口分辨率
    SCREEN_WIDTH = 720
    SCREEN_HEIGHT = 540
    rect_height = 30
    joints_num = 7
    main()
    

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章