-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
LP
authored and
LP
committed
Sep 15, 2022
1 parent
15e7be1
commit fff5160
Showing
6 changed files
with
155 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
// See https://aka.ms/new-console-template for more information | ||
using DlibDotNet; | ||
using OpenCvSharp; | ||
using System.Runtime.InteropServices; | ||
using Point = OpenCvSharp.Point; | ||
using System.Numerics; | ||
using System.Diagnostics; | ||
|
||
// define two constants, one for the eye aspect ratio to indicate | ||
// blink and then a second constant for the number of consecutive | ||
// frames the eye must be below the threshold | ||
var EYE_AR_THRESH = 0.2; | ||
var EYE_AR_CONSEC_FRAMES = 1; | ||
// initialize the frame counters and the total number of blinks | ||
var COUNTER = 0; | ||
var TOTAL = 0; | ||
|
||
VideoCapture cap = new(0); | ||
using (var detector = Dlib.GetFrontalFaceDetector()) | ||
// 加载人脸68特征点检测模型 | ||
using (var sp = ShapePredictor.Deserialize("Resource/shape_predictor_68_face_landmarks.dat")) | ||
while (cap.IsOpened()) | ||
{ | ||
using var frameMat = cap.RetrieveMat(); | ||
byte[] array = new byte[frameMat.Width * frameMat.Height * frameMat.ElemSize()]; | ||
Marshal.Copy(frameMat.Data, array, 0, array.Length); | ||
|
||
using var cimg = Dlib.LoadImageData<RgbPixel>(array, (uint)frameMat.Height, (uint)frameMat.Width, (uint)(frameMat.Width * frameMat.ElemSize())); | ||
var dets = detector.Operator(cimg); | ||
|
||
var shapes = new List<FullObjectDetection>(); | ||
foreach (var rect in dets) | ||
{ | ||
// 画出检测到的脸的矩形框 | ||
frameMat.Rectangle(new Rect(rect.Left, rect.Top, (int)rect.Width, (int)rect.Height), new Scalar(255, 0, 0)); | ||
var shape = sp.Detect(cimg, rect); | ||
var eye1 = new Vector2[6]; | ||
var eye2 = new Vector2[6]; | ||
for (uint i = 0; i < shape.Parts; i++) | ||
{ | ||
var point = shape.GetPart(i); | ||
// 获取第一只眼睛 | ||
if (i >= 36 && i < 42) | ||
{ | ||
eye1[i - 36] = new Vector2(point.X, point.Y); | ||
} | ||
// 获取第二只眼睛 | ||
if (i >= 42 && i < 48) | ||
{ | ||
eye2[i - 42] = new Vector2(point.X, point.Y); | ||
} | ||
|
||
// 画出检测到的脸的68特征点 | ||
frameMat.Circle(point.X, point.Y, 1, new Scalar(0, 255, 0)); | ||
// frameMat.PutText(i.ToString(), new Point(point.X, point.Y), HersheyFonts.HersheySimplex, 0.3, new Scalar(0, 255, 0)); | ||
} | ||
|
||
var EAR1 = eyeAspectRatio(eye1); | ||
var EAR2 = eyeAspectRatio(eye2); | ||
// average the eye aspect ratio together for both eyes | ||
var ear = (EAR1 + EAR2) / 2.0; | ||
frameMat.PutText(string.Format("EAR: {0:N2}", ear), new Point(300, 30), HersheyFonts.HersheySimplex, 0.7, new Scalar(0, 0, 255), 2); | ||
// check to see if the eye aspect ratio is below the blink | ||
// threshold, and if so, increment the blink frame counter | ||
if (ear < EYE_AR_THRESH) | ||
{ | ||
COUNTER += 1; | ||
Debug.WriteLine(ear); | ||
} | ||
// otherwise, the eye aspect ratio is not below the blink | ||
// threshold | ||
else | ||
{ | ||
//if the eyes were closed for a sufficient number of | ||
// then increment the total number of blinks | ||
if (COUNTER >= EYE_AR_CONSEC_FRAMES) | ||
TOTAL += 1; | ||
// reset the eye frame counter | ||
COUNTER = 0; | ||
} | ||
} | ||
|
||
frameMat.PutText(string.Format("Blinks: {0}", TOTAL), new Point(10, 30), HersheyFonts.HersheySimplex, 0.7, new Scalar(0, 0, 255), 2); | ||
|
||
Cv2.ImShow("img", frameMat); | ||
|
||
Cv2.WaitKey(50); | ||
} | ||
|
||
static double eyeAspectRatio(Vector2[] eye) | ||
{ | ||
// compute the euclidean distances between the two sets of | ||
// vertical eye landmarks (x, y)-coordinates | ||
var A = Vector2.Distance(eye[1], eye[5]); | ||
var B = Vector2.Distance(eye[2], eye[4]); | ||
// compute the euclidean distance between the horizontal | ||
// eye landmark (x, y)-coordinates | ||
var C = Vector2.Distance(eye[0], eye[3]); | ||
// compute the eye aspect ratio | ||
var ear = (A + B) / (2.0 * C); | ||
// return the eye aspect ratio | ||
return ear; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# 眨眼检测c#(.net6) | ||
* 利用 [眼睛纵横比(EAR)](http://vision.fe.uni-lj.si/cvww2016/proceedings/papers/05.pdf?spm=a2c6h.12873639.article-detail.9.7cba3329OtWn6S&file=05.pdf)来进行眨眼算法 | ||
* 使用 [dlib](https://github.com/davisking/dlib) 进行人脸以及68特征点检测 |
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net6.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="DlibDotNet" Version="19.21.0.20220724" /> | ||
<PackageReference Include="OpenCvSharp4.Windows" Version="4.6.0.20220608" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<None Update="Resource\shape_predictor_68_face_landmarks.dat"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="shape_predictor_68_face_landmarks.dat.bz2"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 17 | ||
VisualStudioVersion = 17.3.32825.248 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "blink", "blink.csproj", "{2D57E00A-0052-4A83-BE0C-92118E0A393D}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{2D57E00A-0052-4A83-BE0C-92118E0A393D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{2D57E00A-0052-4A83-BE0C-92118E0A393D}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{2D57E00A-0052-4A83-BE0C-92118E0A393D}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{2D57E00A-0052-4A83-BE0C-92118E0A393D}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {5E7E598B-396F-4A6C-8C6B-6CB5FD4FBDAC} | ||
EndGlobalSection | ||
EndGlobal |