失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > python手势识别控制幻灯片翻页系统_基于Emgu CV 的手势识别实现PPT的控制放映

python手势识别控制幻灯片翻页系统_基于Emgu CV 的手势识别实现PPT的控制放映

时间:2023-10-29 20:51:57

相关推荐

python手势识别控制幻灯片翻页系统_基于Emgu CV 的手势识别实现PPT的控制放映

Emgu CV 简介

众所周知,Emgu CV是.NET平台下对OpenCV图像处理库的封装,也就是.NET版的OpenCV。开发者可以很方便的通过C#,VB等语言调用OpenCV函数来实现相应的图像处理功能。

手势识别

在计算机科学中,手势识别是通过数学算法来识别人类手势的一个议题。手势识别可以来自人的身体各部位的运动,但一般是指脸部和手的运动。

腾讯有一个小工具,叫“QQ手势达人forPPT”,可以通过手势运动来控制PPT的放映,本文章亦是通过Emgu CV实现类似效果。

PPT控制类

控制的两个核心,一个是手势的检测,另一个就是如何使用C#控制PPT的播放、停止、上一页、下一页等操作。下面这个类即实现通过C#来控制PPT的加载,播放控制等。

1:// ***********************************************************************

2:// Assembly : HandTrackerTestWindow

3:// Author : pengdian

4:// Created : 08-29-

5://

6:// Last Modified By : pengdian

7:// Last Modified On : 08-29-

8:// ***********************************************************************

9://

10:// Copyright (c) . All rights reserved.

11://

12:// PPT操作

13:// ***********************************************************************

14:using System;

15:using System.IO;

16:

17:///

18:/// The HandTrackerTestWindow namespace.

19:///

20:namespace HandTrackerTestWindow

21:{

22: ///

23: /// PPT操作类.

24: ///

25: public class PowerPointOperate

26: {

27: ///

28: /// The object application

29: ///

30: private static Microsoft.Office.Interop.PowerPoint.Application objApp = null;

31:

32: ///

33: /// The object pres

34: ///

35: private static Microsoft.Office.Interop.PowerPoint.Presentation objPres = null;

36:

37: ///

38: /// The object ss ws

39: ///

40: private Microsoft.Office.Interop.PowerPoint.SlideShowWindows objSSWs;

41:

42: ///

43: /// The object SST

44: ///

45: private Microsoft.Office.Interop.PowerPoint.SlideShowTransition objSST;

46:

47: ///

48: /// The object SSS

49: ///

50: private static Microsoft.Office.Interop.PowerPoint.SlideShowSettings objSSS;

51:

52: ///

53: /// The object SLD RNG

54: ///

55: private Microsoft.Office.Interop.PowerPoint.SlideRange objSldRng;

56:

57: public bool IsStart

58: {

59: get

60: {

61: if (objPres == null || objPres.SlideShowWindow == null || objPres.SlideShowWindow.View == null)

62: {

63: return false;

64: }

65: return objPres.SlideShowWindow.View.State == Microsoft.Office.Interop.PowerPoint.PpSlideShowState.ppSlideShowRunning ? true : false;

66: }

67: }

68:

69: ///

70: /// Prevents a default instance of the class from being created.

71: ///

72: private PowerPointOperate()

73: {

74: }

75:

76: ///

77: /// 单例模式,获取ppt操作类实例.

78: ///

79: /// PowerPointOperate.

80: public static PowerPointOperate GetInstance()

81: {

82: return new PowerPointOperate();

83: }

84:

85: ///

86: /// 加载PPT文件.

87: ///

88: /// The PPT file.

89: /// 指定文件不存在

90: public void LoadFile(string pptFile)

91: {

92: if (string.IsNullOrWhiteSpace(pptFile) || !File.Exists(pptFile))

93: {

94: throw new Exception("指定文件不存在");

95: }

96:

97: 防止连续打开多个PPT程序.

98: if (objApp == null)

99: {

100: objApp = new Microsoft.Office.Interop.PowerPoint.Application() { Visible = Microsoft.Office.Core.MsoTriState.msoTrue };

101: }

102:

103: try

104: {

105: 以只读方式打开,方便操作结束后保存.

106: objPres = objApp.Presentations.Open(pptFile, Microsoft.Office.Core.MsoTriState.msoTrue, Microsoft.Office.Core.MsoTriState.msoFalse, Microsoft.Office.Core.MsoTriState.msoTrue);

107: //Prevent Office Assistant from displaying alert messages:

108: this.bAssistantOn = objApp.Assistant.On;

109: objApp.Assistant.On = false;

110: }

111: catch

112: {

113: objApp.Quit();

114: GC.Collect();

115: }

116: finally

117: {

118: objSSS = null;

119: }

120: }

121:

122: ///

123: /// 开始播放PPT

124: ///

125: public void PPTStart()

126: {

127: try

128: {

129: if (objApp != null && objPres != null)

130: {

131: objSSS = objPres.SlideShowSettings;

132: objSSS.Run();

133: }

134: }

135: catch

136: {

137: objApp.Quit();

138: GC.Collect();

139: }

140: }

141:

142: ///

143: /// 停止播放PPT

144: ///

145: public void PPTStop()

146: {

147: try

148: {

149: if (objApp != null && IsStart)

150: {

151: objPres.SlideShowWindow.View.Exit();

152: }

153: }

154: catch

155: {

156: objApp.Quit();

157: GC.Collect();

158: }

159: finally

160: {

161: objSSS = null;

162: }

163: }

164:

165: ///

166: /// 关闭PPT文档。

167: ///

168: public void PPTClose()

169: {

170: if (objApp != null)

171: {

172: objApp.Quit();

173: objApp = null;

174: }

175:

176: GC.Collect();

177: }

178:

179: ///

180: /// PPT下一页。

181: ///

182: public void NextSlide()

183: {

184: if (objApp != null && IsStart)

185: {

186: objPres.SlideShowWindow.View.Next();

187: }

188: }

189:

190: ///

191: /// PPT上一页。

192: ///

193: public void PreviousSlide()

194: {

195: if (objApp != null && IsStart)

196: {

197: objPres.SlideShowWindow.View.Previous();

198: }

199: }

200: }

201:}

手势识别与运动检测

这里唯一的难点就是手势模型的创建,所幸,这种麻烦东西我们可以从“QQ手势达人forPPT”中提取出来,剩下的就是识别和检测手势了。代码如下:

1:using Emgu.CV;

2:using Emgu.CV.Structure;

3:using Emgu.CV.Util;

4:using System;

5:using System.Collections.Generic;

6:using System.Drawing;

7:using System.IO;

8:using System.Linq;

9:using System.Text;

10:

11:namespace HandTrackerTestWindow

12:{

13: public class HandTracker : IDisposable

14: {

15: CascadeClassifier palmHaar = new CascadeClassifier(@"data\palm.dat");

16: CascadeClassifier fistHaar = new CascadeClassifier(@"data\fist.dat");

17:

18: public void Dispose()

19: {

20: if (palmHaar != null)

21: {

22: palmHaar.Dispose();

23: palmHaar = null;

24: }

25: if (fistHaar != null)

26: {

27: fistHaar.Dispose();

28: fistHaar = null;

29: }

30: }

31:

32: public Rectangle DetectPalm(string imagePath)

33: {

34: if (!File.Exists(imagePath))

35: {

36: return new Rectangle(0, 0, 0, 0);

37: }

38: Image img = new Image(imagePath);

39: Image grayImage = img.Copy().Convert();

40: Rectangle[] palmDetected = palmHaar.DetectMultiScale(grayImage, 1.4, 10, new Size(20, 20), Size.Empty);

41: //faces.AddRange(facesDetected);

42: if (palmDetected == null || palmDetected.Length == 0)

43: {

44: return new Rectangle(0, 0, 0, 0);

45: }

46:

47: return palmDetected[0];

48: }

49: public Rectangle DetectPalm(Bitmap bitmap)

50: {

51: if (bitmap == null)

52: {

53: return new Rectangle(0, 0, 0, 0);

54: }

55: Image img = new Image(bitmap);

56: Image grayImage = img.Copy().Convert();

57: Rectangle[] palmDetected = palmHaar.DetectMultiScale(grayImage, 1.4, 10, new Size(20, 20), Size.Empty);

58: //faces.AddRange(facesDetected);

59: if (palmDetected == null || palmDetected.Length == 0)

60: {

61: return new Rectangle(0, 0, 0, 0);

62: }

63:

64: return palmDetected[0];

65: }

66: public Rectangle DetectFist(string imagePath)

67: {

68: if (!File.Exists(imagePath))

69: {

70: return new Rectangle(0, 0, 0, 0);

71: }

72: Image img = new Image(imagePath);

73: Image grayImage = img.Copy().Convert();

74: Rectangle[] fistDetected = fistHaar.DetectMultiScale(grayImage, 1.4, 10, new Size(20, 20), Size.Empty);

75: if (fistDetected == null || fistDetected.Length == 0)

76: {

77: return new Rectangle(0, 0, 0, 0);

78: }

79:

80: return fistDetected[0];

81: }

82:

83: public Rectangle DetectFist(Bitmap bitmap)

84: {

85: if (bitmap == null)

86: {

87: return new Rectangle(0, 0, 0, 0);

88: }

89: Image img = new Image(bitmap);

90: Image grayImage = img.Copy().Convert();

91: Rectangle[] fistDetected = fistHaar.DetectMultiScale(grayImage, 1.4, 10, new Size(20, 20), Size.Empty);

92: if (fistDetected == null || fistDetected.Length == 0)

93: {

94: return new Rectangle(0, 0, 0, 0);

95: }

96:

97: return fistDetected[0];

98: }

99: }

100:}

解决了手势检测控制类和PPT放映控制类,剩下的就是创建一个界面来进行控制了。

1:private void test()

2: {

3: bool isPalm = false;

4: bool isFist = false;

5: int count = 0;

6: while (true)

7: {

8: if (count > 10)

9: {

10: isPalm = false;

11: isFist = false;

12: count = 0;

13: this.Invoke(showControllerDelegate, false);

14: }

15: if (!isPalm)

16: {

17: isFist = false;

18: Bitmap bitmap = videoPlayer.GetCurrentVideoFrame();

19: if (handTracker.DetectPalm(bitmap).Width > 0)

20: {

21: isPalm = true;

22: count = 0;

23: this.Invoke(showControllerDelegate, true);

24: }

25: Thread.Sleep(50);

26: }

27: else

28: {

29: if (!isFist)

30: {

31: Bitmap bitmap = videoPlayer.GetCurrentVideoFrame();

32: Rectangle rect = handTracker.DetectFist(bitmap);

33: if (rect.Width > 0)

34: {

35: firstRect = rect;

36: isFist = true;

37: count = 0;

38: this.Invoke(showButtonDelegate, true);

39: }

40: else

41: {

42: isFist = false;

43: if (handTracker.DetectPalm(bitmap).Width > 0)

44: {

45: isPalm = true;

46: count = 0;

47: this.Invoke(showButtonDelegate, false);

48: }

49: else

50: {

51: count++;

52: }

53:

54: }

55: Thread.Sleep(50);

56: }

57: else

58: {

59: Bitmap bitmap = videoPlayer.GetCurrentVideoFrame();

60: Rectangle rect = handTracker.DetectFist(bitmap);

61: if (rect.Width > 0)

62: {

63: if (firstRect.Left - rect.Left > 30)

64: {

65: this.Invoke(nextPPTDelegate);

66: PowerPointOperate.GetInstance().NextSlide();

67: isPalm = false;

68: isFist = false;

69: count = 0;

70: Thread.Sleep(500);

71: this.Invoke(showControllerDelegate, false);

72: }

73: else if (firstRect.Left - rect.Left < -30)

74: {

75: this.Invoke(prePPTDelegate);

76: PowerPointOperate.GetInstance().PreviousSlide();

77: isPalm = false;

78: isFist = false;

79: count = 0;

80: Thread.Sleep(500);

81: this.Invoke(showControllerDelegate, false);

82: }

83: else

84: {

85: isPalm = true;

86: isFist = true;

87: count = 0;

88: }

89: //this.Invoke(showButtonDelegate);

90: }

91: else

92: {

93: if (handTracker.DetectPalm(bitmap).Width > 0)

94: {

95: isPalm = true;

96: isFist = false;

97: count = 0;

98: this.Invoke(showButtonDelegate, false);

99: }

100: else

101: {

102: count++;

103: }

104: }

105: Thread.Sleep(50);

106: }

107:

108: }

109:

110:

111: //PowerPointOperate.GetInstance().PPTStop();

112: }

113: }

最后实现的效果图如下:

检测手掌:

检测拳头:

移动拳头控制PPT

由于只是写一个用于演示的Demo,因此代码没做优化,有兴趣的可以自行修改,目前只做了上一页和下一页,开始播放和停止播放,有兴趣的可以自行补上。

文章已迁移到:/forum.php

如果觉得《python手势识别控制幻灯片翻页系统_基于Emgu CV 的手势识别实现PPT的控制放映》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。