小言_互联网的博客

基于Tkinter和百度Aip的人体关键点检测

403人阅读  评论(0)

个人博客:http://www.chenjianqu.com/

原文链接:http://www.chenjianqu.com/show-104.html

最近某些项目需要用到人体姿势识别。当前有很多著名的人体识别的开源项目,比如CMU的OpenPose,上交的AlphaPose,效果都很好。我昨天试着安装一下AlphaPose,配环境配了一天,终于可以运行Demo的时候,显存溢出。。。因此我换个思路,我的项目不要求实时性,使用API也是可以接受的。发现百度的人体识别这方面的API还不错,QPS限制为2,也能用,于是便有了这篇文章。

    本文通过调用百度开放的人体关键点检测API,实现关键点检测并将其在Python的轻量级GUI库Tkinter绘制出来。当然最直接的方法是直接用opencv显示出来,但是我们更多的时候需要进行交互,因此使用Tkinter。

 

一、百度API获取

    若想使用百度的API,需要在百度AI的官网上注册帐号,然后在人体识别功能下创建一个应用,即可得到

APP_ID、API_KEY、SECRET_KEY,这样就可以调用它的API了。调用方式可以参考其API文档https://ai.baidu.com/ai-doc/BODY/0k3cpyxme

    若想使用Python调用,首先要安装百度的API接口模块:

pip install baidu-aip

 

二、人体关键点获取和绘制

    可以通过下面的类调用百度API


  
  1. class BaiduAIP(object):
  2.      def __init__(self):
  3.          self.client = AipBodyAnalysis(cfg.APP_ID, cfg.API_KEY, cfg.SECRET_KEY)
  4.     
  5.      def bodyAnalysis(self,img_jpg):
  6.         etval, buffer = cv2.imencode( '.jpg', img_jpg)
  7.         result =  self.client.bodyAnalysis(buffer)  #内部把buffer转换为base64了
  8.          return result

    然后是绘制关键点和连线和方框的函数:


  
  1. def draw_line(img,dic,text):
  2.     color=( 0, 255, 0)
  3.     thickness= 2
  4.      if(text== 'warn'):
  5.         color=( 0, 0, 255)
  6.     
  7.      #nose ---> neck
  8.     cv2.line(img, ( int(dic[ 'nose'][ 'x']), int(dic[ 'nose'][ 'y'])),( int(dic[ 'neck'][ 'x']), int(dic[ 'neck'][ 'y'])), color, thickness)
  9.      #neck --> left_shoulder
  10.     cv2.line(img, ( int(dic[ 'neck'][ 'x']), int(dic[ 'neck'][ 'y'])),( int(dic[ 'left_shoulder'][ 'x']), int(dic[ 'left_shoulder'][ 'y'])), color, thickness)
  11.      #neck --> right_shoulder
  12.     cv2.line(img, ( int(dic[ 'neck'][ 'x']), int(dic[ 'neck'][ 'y'])),( int(dic[ 'right_shoulder'][ 'x']), int(dic[ 'right_shoulder'][ 'y'])), color, thickness)
  13.      #left_shoulder --> left_elbow
  14.     cv2.line(img, ( int(dic[ 'left_shoulder'][ 'x']), int(dic[ 'left_shoulder'][ 'y'])),( int(dic[ 'left_elbow'][ 'x']), int(dic[ 'left_elbow'][ 'y'])), color, thickness)
  15.      #left_elbow --> left_wrist
  16.     cv2.line(img, ( int(dic[ 'left_elbow'][ 'x']), int(dic[ 'left_elbow'][ 'y'])),( int(dic[ 'left_wrist'][ 'x']), int(dic[ 'left_wrist'][ 'y'])), color, thickness)
  17.      #right_shoulder --> right_elbow
  18.     cv2.line(img, ( int(dic[ 'right_shoulder'][ 'x']), int(dic[ 'right_shoulder'][ 'y'])),( int(dic[ 'right_elbow'][ 'x']), int(dic[ 'right_elbow'][ 'y'])), color, thickness)
  19.      #right_elbow --> right_wrist
  20.     cv2.line(img, ( int(dic[ 'right_elbow'][ 'x']), int(dic[ 'right_elbow'][ 'y'])),( int(dic[ 'right_wrist'][ 'x']), int(dic[ 'right_wrist'][ 'y'])), color, thickness)
  21.      #neck --> left_hip
  22.     cv2.line(img, ( int(dic[ 'neck'][ 'x']), int(dic[ 'neck'][ 'y'])),( int(dic[ 'left_hip'][ 'x']), int(dic[ 'left_hip'][ 'y'])), color, thickness)
  23.      #neck --> right_hip
  24.     cv2.line(img, ( int(dic[ 'neck'][ 'x']), int(dic[ 'neck'][ 'y'])),( int(dic[ 'right_hip'][ 'x']), int(dic[ 'right_hip'][ 'y'])), color, thickness)
  25.      #left_hip --> left_knee
  26.     cv2.line(img, ( int(dic[ 'left_hip'][ 'x']), int(dic[ 'left_hip'][ 'y'])),( int(dic[ 'left_knee'][ 'x']), int(dic[ 'left_knee'][ 'y'])), color, thickness)
  27.      #right_hip --> right_knee
  28.     cv2.line(img, ( int(dic[ 'right_hip'][ 'x']), int(dic[ 'right_hip'][ 'y'])),( int(dic[ 'right_knee'][ 'x']), int(dic[ 'right_knee'][ 'y'])), color, thickness)
  29.      #left_knee --> left_ankle
  30.     cv2.line(img, ( int(dic[ 'left_knee'][ 'x']), int(dic[ 'left_knee'][ 'y'])),( int(dic[ 'left_ankle'][ 'x']), int(dic[ 'left_ankle'][ 'y'])), color, thickness)
  31.      #right_knee --> right_ankle
  32.     cv2.line(img, ( int(dic[ 'right_knee'][ 'x']), int(dic[ 'right_knee'][ 'y'])),( int(dic[ 'right_ankle'][ 'x']), int(dic[ 'right_ankle'][ 'y'])), color, thickness)
  33. def draw_point(img,dic,text):
  34.     color=( 0, 255, 0)
  35.     thickness= 2
  36.      if(text== 'warn'):
  37.         color=( 0, 0, 255)
  38.      for i  in dic:
  39.         cv2.circle(img,( int(dic[i][ 'x']), int(dic[i][ 'y'])), 5,color,thickness)
  40. def draw_box(img,dic,text):
  41.     color=( 255, 0, 0)
  42.      if(text== 'warn'):
  43.         color=( 0, 0, 255)
  44.     
  45.     left_top=( int(dic[ 'left']), int(dic[ 'top']))
  46.     left_bottom=( int(dic[ 'left']), int(dic[ 'top']+dic[ 'height']))
  47.     right_bottom=( int(dic[ 'left']+dic[ 'width']), int(dic[ 'top']+dic[ 'height']))
  48.     right_top=( int(dic[ 'left']+dic[ 'width']), int(dic[ 'top']))
  49.     cv2.line(img, left_top,left_bottom, color,  2)
  50.     cv2.line(img, left_top,right_top, color,  2)
  51.     cv2.line(img, right_bottom,left_bottom,color,  2)
  52.     cv2.line(img, right_bottom,right_top,color,  2)
  53.     
  54.     cv2.putText(img, text, ( int(dic[ 'left']), int(dic[ 'top'])+ 20), cv2.FONT_HERSHEY_COMPLEX,  1,color,  1)

    测试一下:


  
  1. if __name__ ==  '__main__':
  2.     baiduapi = BaiduAIP()
  3.     img = cv2.imread( '/media/chen/chen/Photo/others/littleCookies.jpg')
  4.     d=baiduapi.bodyAnalysis(img)
  5.     print( "api time= "+str(t2-t1))
  6.     print(d[ "person_num"])
  7.     print(d[ "log_id"])
  8.     persion=d[ "person_info"]
  9.      for p  in persion:
  10.         draw_line(img,p[ 'body_parts'], 'ok')
  11.         draw_point(img,p[ 'body_parts'], 'ok')
  12.         draw_box(img,p[ 'location'], 'beauty')
  13.     cv2.imwrite( "image1.jpg",img)

    结果:

 

 

 

三、tkinter界面开发

    先定义窗口和组件:


  
  1. IMG_HEIGT= 352* 2
  2. IMG_WIDTH= 640* 2
  3. #根窗口
  4. window = tk.Tk()
  5. #显示变量
  6. num_people = StringVar()
  7. num_people. set( '当前人数:0')
  8. num_desertion = StringVar()
  9. num_desertion. set( '开小差:0')
  10. #UI绘制
  11. window.title( "智能课堂管理")
  12. sw = window.winfo_screenwidth() #获取屏幕宽
  13. sh = window.winfo_screenheight() #获取屏幕高
  14. #设置窗口大小和位置
  15. wx = IMG_WIDTH+ 100
  16. wh = IMG_HEIGT+ 100
  17. window.geometry( "%dx%d+%d+%d" %(wx,wh,(sw-wx)/ 2,(sh-wh)/ 2 -100)) #窗口至指定位置
  18. #顶部是信息栏
  19. fm1 = Frame(window)
  20. Label(fm1,  text= "总人数:20").pack(side= 'left')
  21. label_num = Label(fm1, textvariable=num_people).pack(side= 'left')
  22. label_num = Label(fm1, textvariable=num_desertion).pack(side= 'left')
  23. fm1.pack(side= 'top', padx=10)
  24. #左侧是操作栏
  25. fm2 = Frame(window)
  26. fm2.pack(side= 'left', padx=10)
  27. canvas1 = tk.Canvas(window,bg= "#c4c2c2",height=IMG_HEIGT,width=IMG_WIDTH) #绘制画布
  28. canvas1.pack(side= "left")
  29. job=ImgProcThread()
  30. bt_start = tk.Button(fm2, text= "启动",height= 2,width= 15,command=job.start).pack(side= "top")
  31. bt_pause = tk.Button(fm2, text= "暂停",height= 2,width= 15,command=job.pause).pack(side= "top")
  32. bt_resume = tk.Button(fm2, text= "恢复",height= 2,width= 15,command=job. resume).pack(side= "top")
  33. bt_stop = tk.Button(fm2, text= "结束线程",height= 2,width= 15,command=job. stop).pack(side= "top")
  34. bt_quit = tk.Button(fm2, text= "退出程序",height= 2,width= 15,command=window.quit).pack(side= "top")
  35. window.mainloop()

    ImgProcThread是什么?由于tkiner中没有提供直接播放视频的组件,因此我们使用cavas显示图片,并将关键点检测和图片检测放到另一个线程。但是由于Python自带的线程类功能功能不足,因此需要自己实现线程阻塞、结束等功能,如下:


  
  1. class ImgProcThread(threading.Thread):
  2.      def __init__(self, *args, **kwargs):
  3.          super(ImgProcThread,  self).__init_ _(*args, **kwargs)
  4.          self.__flag = threading.Event()      # 用于暂停线程的标识
  5.          self.__flag.set()        # 设置为True
  6.          self.__running = threading.Event()       # 用于停止线程的标识
  7.          self.__running.set()       # 将running设置为True
  8.         
  9.      def run(self):
  10.         capture = cv2.VideoCapture( '/media/chen/chen/Photo/others/1.mp4')
  11.          while  self.__running.isSet()  and capture.isOpened():
  12.              self.__flag.wait()       # 为True时立即返回, 为False时阻塞直到内部的标识位为True后返回
  13.             pass
  14.             
  15.      def pause(self):
  16.          self.__flag.clear()      # 设置为False, 让线程阻塞
  17.     
  18.      def resume(self):
  19.          self.__flag.set()     # 设置为True, 让线程停止阻塞
  20.     
  21.      def stop(self):
  22.          self.__flag.set()        # 将线程从暂停状态恢复, 如何已经暂停的话
  23.          self.__running.clear()         # 设置为Fals

 

四、总程序

    本程序是根据我自己的需求来写的,因此会有一些在别人看起来蜜汁操作的代码,大家可以略过。

    config.py


  
  1. APP_ID= "***"
  2. API_KEY= "***"
  3. SECRET_KEY= "***"

 

    aip_bodyanalysis.py


  
  1. from aip import AipBodyAnalysis
  2. import sys
  3. if( '/opt/ros/kinetic/lib/python2.7/dist-packages' in sys.path):
  4.     sys.path.remove( '/opt/ros/kinetic/lib/python2.7/dist-packages')
  5. import cv2
  6. import os
  7. import  config  as cfg
  8. import base64
  9. import  time
  10. def pose_analyse(img,dic):
  11.     nose=( int(dic[ 'nose'][ 'x']), int(dic[ 'nose'][ 'y']))
  12.     neck=( int(dic[ 'neck'][ 'x']), int(dic[ 'neck'][ 'y']))
  13.      if(neck[ 1]<=nose[ 1]):
  14.          return  'warn'
  15.      return  'ok'
  16. def draw_line(img,dic,text):
  17.     color=( 0, 255, 0)
  18.     thickness= 2
  19.      if(text== 'warn'):
  20.         color=( 0, 0, 255)
  21.     
  22.      #nose ---> neck
  23.     cv2.line(img, ( int(dic[ 'nose'][ 'x']), int(dic[ 'nose'][ 'y'])),( int(dic[ 'neck'][ 'x']), int(dic[ 'neck'][ 'y'])), color, thickness)
  24.      #neck --> left_shoulder
  25.     cv2.line(img, ( int(dic[ 'neck'][ 'x']), int(dic[ 'neck'][ 'y'])),( int(dic[ 'left_shoulder'][ 'x']), int(dic[ 'left_shoulder'][ 'y'])), color, thickness)
  26.      #neck --> right_shoulder
  27.     cv2.line(img, ( int(dic[ 'neck'][ 'x']), int(dic[ 'neck'][ 'y'])),( int(dic[ 'right_shoulder'][ 'x']), int(dic[ 'right_shoulder'][ 'y'])), color, thickness)
  28.      #left_shoulder --> left_elbow
  29.     cv2.line(img, ( int(dic[ 'left_shoulder'][ 'x']), int(dic[ 'left_shoulder'][ 'y'])),( int(dic[ 'left_elbow'][ 'x']), int(dic[ 'left_elbow'][ 'y'])), color, thickness)
  30.      #left_elbow --> left_wrist
  31.     cv2.line(img, ( int(dic[ 'left_elbow'][ 'x']), int(dic[ 'left_elbow'][ 'y'])),( int(dic[ 'left_wrist'][ 'x']), int(dic[ 'left_wrist'][ 'y'])), color, thickness)
  32.      #right_shoulder --> right_elbow
  33.     cv2.line(img, ( int(dic[ 'right_shoulder'][ 'x']), int(dic[ 'right_shoulder'][ 'y'])),( int(dic[ 'right_elbow'][ 'x']), int(dic[ 'right_elbow'][ 'y'])), color, thickness)
  34.      #right_elbow --> right_wrist
  35.     cv2.line(img, ( int(dic[ 'right_elbow'][ 'x']), int(dic[ 'right_elbow'][ 'y'])),( int(dic[ 'right_wrist'][ 'x']), int(dic[ 'right_wrist'][ 'y'])), color, thickness)
  36.      #neck --> left_hip
  37.     cv2.line(img, ( int(dic[ 'neck'][ 'x']), int(dic[ 'neck'][ 'y'])),( int(dic[ 'left_hip'][ 'x']), int(dic[ 'left_hip'][ 'y'])), color, thickness)
  38.      #neck --> right_hip
  39.     cv2.line(img, ( int(dic[ 'neck'][ 'x']), int(dic[ 'neck'][ 'y'])),( int(dic[ 'right_hip'][ 'x']), int(dic[ 'right_hip'][ 'y'])), color, thickness)
  40.      #left_hip --> left_knee
  41.     cv2.line(img, ( int(dic[ 'left_hip'][ 'x']), int(dic[ 'left_hip'][ 'y'])),( int(dic[ 'left_knee'][ 'x']), int(dic[ 'left_knee'][ 'y'])), color, thickness)
  42.      #right_hip --> right_knee
  43.     cv2.line(img, ( int(dic[ 'right_hip'][ 'x']), int(dic[ 'right_hip'][ 'y'])),( int(dic[ 'right_knee'][ 'x']), int(dic[ 'right_knee'][ 'y'])), color, thickness)
  44.      #left_knee --> left_ankle
  45.     cv2.line(img, ( int(dic[ 'left_knee'][ 'x']), int(dic[ 'left_knee'][ 'y'])),( int(dic[ 'left_ankle'][ 'x']), int(dic[ 'left_ankle'][ 'y'])), color, thickness)
  46.      #right_knee --> right_ankle
  47.     cv2.line(img, ( int(dic[ 'right_knee'][ 'x']), int(dic[ 'right_knee'][ 'y'])),( int(dic[ 'right_ankle'][ 'x']), int(dic[ 'right_ankle'][ 'y'])), color, thickness)
  48. def draw_point(img,dic,text):
  49.     color=( 0, 255, 0)
  50.     thickness= 2
  51.      if(text== 'warn'):
  52.         color=( 0, 0, 255)
  53.      for i in dic:
  54.         cv2.circle(img,( int(dic[i][ 'x']), int(dic[i][ 'y'])), 5,color,thickness)
  55. def draw_box(img,dic,text):
  56.     color=( 255, 0, 0)
  57.      if(text== 'warn'):
  58.         color=( 0, 0, 255)
  59.     
  60.     left_top=( int(dic[ 'left']), int(dic[ 'top']))
  61.     left_bottom=( int(dic[ 'left']), int(dic[ 'top']+dic[ 'height']))
  62.     right_bottom=( int(dic[ 'left']+dic[ 'width']), int(dic[ 'top']+dic[ 'height']))
  63.     right_top=( int(dic[ 'left']+dic[ 'width']), int(dic[ 'top']))
  64.     cv2.line(img, left_top,left_bottom, color,  2)
  65.     cv2.line(img, left_top,right_top, color,  2)
  66.     cv2.line(img, right_bottom,left_bottom,color,  2)
  67.     cv2.line(img, right_bottom,right_top,color,  2)
  68.     
  69.     cv2.putText(img, text, ( int(dic[ 'left']), int(dic[ 'top'])+ 20), cv2.FONT_HERSHEY_COMPLEX,  1,color,  1)
  70.     
  71. class BaiduAIP(object):
  72.     def __init_ _(self):
  73.         self.client = AipBodyAnalysis(cfg.APP_ID, cfg.API_KEY, cfg.SECRET_KEY)
  74.     
  75.     def bodyAnalysis(self,img_jpg):
  76.         etval, buffer = cv2.imencode( '.jpg', img_jpg)
  77.         result = self.client.bodyAnalysis(buffer)  #内部把buffer转换为base64了
  78.          return result
  79.         
  80. if __name_ _ ==  '__main__':
  81.     baiduapi = BaiduAIP()
  82.     img = cv2.imread( '/media/chen/chen/Photo/others/littleCookies.jpg')
  83.     t1=time.time()
  84.     d=baiduapi.bodyAnalysis(img)
  85.     t2=time.time()
  86.      print( "api time= "+str(t2-t1))
  87.      print(d[ "person_num"])
  88.      print(d[ "log_id"])
  89.     persion=d[ "person_info"]
  90.      for p in persion:
  91.         draw_line(img,p[ 'body_parts'], 'ok')
  92.         draw_point(img,p[ 'body_parts'], 'ok')
  93.         draw_box(img,p[ 'location'], 'beauty')
  94.     t3=time.time()
  95.      print( "draw time= "+str(t3-t2))
  96.     cv2.imwrite( "image1.jpg",img)

 

    tkinter_body.py


  
  1. import sys
  2. if( '/opt/ros/kinetic/lib/python2.7/dist-packages'  in sys.path):
  3.     sys.path.remove( '/opt/ros/kinetic/lib/python2.7/dist-packages')
  4. import cv2
  5. import tkinter as tk
  6. from tkinter import * #文件控件
  7. from PIL import Image, ImageTk #图像控件
  8. import threading #多线程
  9. from aip_bodyanalysis import *
  10. import time
  11. IMG_HEIGT= 352* 2
  12. IMG_WIDTH= 640* 2
  13. aip=BaiduAIP()
  14. is_run=True
  15. #申请线程锁
  16. lock=threading.Lock()
  17. #根窗口
  18. window = tk.Tk()
  19. #显示变量
  20. num_people = StringVar()
  21. num_people.set( '当前人数:0')
  22. num_desertion = StringVar()
  23. num_desertion.set( '不正常:0')
  24. #UI绘制
  25. window.title( "测试")
  26. sw = window.winfo_screenwidth() #获取屏幕宽
  27. sh = window.winfo_screenheight() #获取屏幕高
  28. #设置窗口大小和位置
  29. wx = IMG_WIDTH+ 100
  30. wh = IMG_HEIGT+ 100
  31. window.geometry( "%dx%d+%d+%d"  %(wx,wh,(sw-wx)/ 2,(sh-wh)/ 2- 100)) #窗口至指定位置
  32. #顶部是信息栏
  33. fm1 = Frame(window)
  34. Label(fm1, text= "总人数:20").pack(side= 'left')
  35. label_num = Label(fm1, textvariable=num_people).pack(side= 'left')
  36. label_num = Label(fm1, textvariable=num_desertion).pack(side= 'left')
  37. fm1.pack(side= 'top', padx= 10)
  38. #左侧是操作栏
  39. fm2 = Frame(window)
  40. fm2.pack(side= 'left', padx= 10)
  41. canvas1 = tk.Canvas(window,bg= "#c4c2c2",height=IMG_HEIGT,width=IMG_WIDTH) #绘制画布
  42. canvas1.pack(side= "left")
  43. def getResult(img):
  44.     d=aip.bodyAnalysis(img)
  45.      if( "person_info"  not  in d):
  46.          return
  47.     persion=d[ "person_info"]
  48.      #获取人数
  49.     num=len(persion)
  50.     num_people.set(  "当前人数:"+str(num))
  51.      #绘制人体姿势
  52.      for p  in  persion:
  53.         status=pose_analyse(img,p[ 'body_parts'])
  54.         draw_line(img,p[ 'body_parts'],status)
  55.         draw_point(img,p[ 'body_parts'],status)
  56.         draw_box(img,p[ 'location'],status)
  57.         
  58. def cc():
  59.     capture = cv2.VideoCapture( '/media/chen/chen/Photo/others/1.mp4')
  60.      #capture = cv2.VideoCapture(0)
  61.      while capture.isOpened():
  62.         t 0=time.time()
  63.          _, frame = capture.read()
  64.          #清除缓存
  65.          for i  in range( 15):
  66.              _, frame = capture.read()
  67.         getResult(frame)
  68.         frame = cv2.flip(frame,  1) #翻转 0:上下颠倒 大于0水平颠倒
  69.         cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
  70.         img = Image.fromarray(cv2image)
  71.         image_file=ImageTk.PhotoImage(img)
  72.         canvas1.create_image( 0, 0,anchor= "nw",image=image_file)
  73.         print(time.time()-t 0)
  74.     print( "ending")
  75.     
  76.     
  77. class ImgProcThread(threading.Thread):
  78.      def __init__(self, *args, **kwargs):
  79.          super(ImgProcThread,  self).__init_ _(*args, **kwargs)
  80.          self.__flag = threading.Event()      # 用于暂停线程的标识
  81.          self.__flag.set()        # 设置为True
  82.          self.__running = threading.Event()       # 用于停止线程的标识
  83.          self.__running.set()       # 将running设置为True
  84.         
  85.      def run(self):
  86.         capture = cv2.VideoCapture( '/media/chen/chen/Photo/others/1.mp4')
  87.          while  self.__running.isSet()  and capture.isOpened():
  88.              self.__flag.wait()       # 为True时立即返回, 为False时阻塞直到内部的标识位为True后返回
  89.             t 0=time.time()
  90.              _, frame = capture.read()
  91.              for i  in range( 15):
  92.                  _, frame = capture.read()
  93.             frame = cv2.resize(frame,(IMG_WIDTH,IMG_HEIGT), interpolation=cv2.INTER_NEAREST)
  94.             getResult(frame)
  95.              #frame = cv2.flip(frame, 1)#翻转 0:上下颠倒 大于0水平颠倒
  96.             cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
  97.             img = Image.fromarray(cv2image)
  98.             image_file=ImageTk.PhotoImage(img)
  99.             canvas1.create_image( 0, 0,anchor= "nw",image=image_file)
  100.             print(time.time()-t 0)
  101.             
  102.      def pause(self):
  103.          self.__flag.clear()      # 设置为False, 让线程阻塞
  104.     
  105.      def resume(self):
  106.          self.__flag.set()     # 设置为True, 让线程停止阻塞
  107.     
  108.      def stop(self):
  109.          self.__flag.set()        # 将线程从暂停状态恢复, 如何已经暂停的话
  110.          self.__running.clear()         # 设置为Fals
  111. def video_demo():
  112.     t=threading.Thread(target=cc)
  113.     t.start()
  114.     
  115. job=ImgProcThread()
  116. bt_start = tk.Button(fm2,text= "启动",height= 2,width= 15,command=job.start).pack(side= "top")
  117. bt_pause = tk.Button(fm2,text= "暂停",height= 2,width= 15,command=job.pause).pack(side= "top")
  118. bt_resume = tk.Button(fm2,text= "恢复",height= 2,width= 15,command=job.resume).pack(side= "top")
  119. bt_stop = tk.Button(fm2,text= "结束线程",height= 2,width= 15,command=job.stop).pack(side= "top")
  120. bt_quit = tk.Button(fm2,text= "退出程序",height= 2,width= 15,command=window.quit).pack(side= "top")
  121. window.mainloop()

    

    代码执行结果:

 

 


转载:https://blog.csdn.net/qq_37394634/article/details/105494672
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场