C# 人脸识别库 0.1
<p><em><span style="font-size: 13px"></span></em></p><h1><span><strong style="font-size: 18pt">.NET 人脸识别库 ViewFaceCore</strong></span></h1>
<p>这是基于 SeetaFace6 人脸识别开发的 .NET 平台下的人脸识别库<br>这是一个使用超简单的人脸识别库<br>这是一个基于 .NET Standard 2.0 开发的库<br>这个库已经发布到 NuGet ,你可以一键集成到你的项目<br>此项目可以免费商业使用</p>
<h2>⭐、开源</h2>
<p>开源协议:Apache-2.0<br>GitHub地址: ViewFaceCore<br><em><strong>十分感谢您的小星星</strong></em></p>
<h2>一、示例</h2>
<p>示例项目地址:WinForm 摄像头人脸检测<br>示例项目效果:</p>
<p><img src="https://img2020.cnblogs.com/blog/1188429/202006/1188429-20200624091353655-1553363960.png"></p>
<p> </p>
<h2>二、使用</h2>
<p>一分钟在你的项目里集成人脸识别</p>
<p><strong>1. 创建你的 .NET 应用</strong></p>
<p>.NET Standard >= 2.0<br>.NET Core >= 2.0<br>.NET Framework >= 4.6.1^2</p>
<p><br><strong>2. 使用 Nuget 安装 ViewFaceCore</strong></p>
<ul>
<li>Author : View</li>
<li>Version >= 0.1.1</li>
</ul>
<p><em>此 Nuget 包会自动添加依赖的 C++ 库,以及最精简的识别模型。</em><br><em>如果需要其它场景的识别模型,请下载 SeetaFace6 模型文件。</em></p>
<p><strong>3. 在项目中编写你的代码</strong></p>
<ul>
<li>按照 说明 自己编写</li>
<li>或者参考以下代码</li>
</ul>
<p>简单的调用示例</p>
<div class="cnblogs_code"><img id="code_img_closed_1e32d281-1a0a-40a7-b9f8-d8a5e65b470a" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_1e32d281-1a0a-40a7-b9f8-d8a5e65b470a" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_1e32d281-1a0a-40a7-b9f8-d8a5e65b470a" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> Main()
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> ViewFace viewFace = <span style="color: rgba(0, 0, 255, 1)">new</span> ViewFace((str) => { Debug.WriteLine(str); }); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 初始化人脸识别类,并设置 日志回调函数</span>
<span style="color: rgba(0, 128, 128, 1)"> 4</span> viewFace.DetectorSetting = <span style="color: rgba(0, 0, 255, 1)">new</span> DetectorSetting() { FaceSize = <span style="color: rgba(128, 0, 128, 1)">20</span>, MaxWidth = <span style="color: rgba(128, 0, 128, 1)">2000</span>, MaxHeight = <span style="color: rgba(128, 0, 128, 1)">2000</span>, Threshold = <span style="color: rgba(128, 0, 128, 1)">0.5</span><span style="color: rgba(0, 0, 0, 1)"> };
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span>
<span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 系统默认使用的轻量级识别模型。如果对精度有要求,请切换到 Normal 模式;并下载需要模型文件 放入生成目录的 model 文件夹中</span>
<span style="color: rgba(0, 128, 128, 1)"> 7</span> viewFace.FaceType =<span style="color: rgba(0, 0, 0, 1)"> FaceType.Normal;
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 系统默认使用5个人脸关键点。</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">不建议改动,除非是使用口罩模型。</span>
<span style="color: rgba(0, 128, 128, 1)"> 9</span> viewFace.MarkType =<span style="color: rgba(0, 0, 0, 1)"> MarkType.Light;
</span><span style="color: rgba(0, 128, 128, 1)">10</span>
<span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 255, 1)">#region</span> 识别老照片
<span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 255, 1)">float</span><span style="color: rgba(0, 0, 0, 1)">[] oldEigenValues;
</span><span style="color: rgba(0, 128, 128, 1)">13</span> Bitmap oldImg = (Bitmap)Image.FromFile(<span style="color: rgba(128, 0, 0, 1)">@"</span><span style="color: rgba(128, 0, 0, 1)">C:\Users\yangw\OneDrive\图片\Camera Roll\IMG_20181103_142707.jpg</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">老图片路径</span><span style="color: rgba(0, 128, 0, 1)">*/</span>); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 从文件中加载照片 </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 或者视频帧等</span>
<span style="color: rgba(0, 128, 128, 1)">14</span> <span style="color: rgba(0, 0, 255, 1)">var</span> oldFaces = viewFace.FaceDetector(oldImg); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 检测图片中包含的人脸信息。(置信度、位置、大小)</span>
<span style="color: rgba(0, 128, 128, 1)">15</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (oldFaces.Length > <span style="color: rgba(128, 0, 128, 1)">0</span>) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">识别到人脸</span>
<span style="color: rgba(0, 128, 128, 1)">16</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">17</span> { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 打印人脸信息</span>
<span style="color: rgba(0, 128, 128, 1)">18</span> Console.WriteLine($<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">识别到的人脸数量:{oldFaces.Length} 。人脸信息:\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">19</span> Console.WriteLine($<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">序号\t人脸置信度\t位置X\t位置Y\t宽度\t高度</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">20</span> <span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = <span style="color: rgba(128, 0, 128, 1)">0</span>; i < oldFaces.Length; i++<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">21</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">22</span> Console.WriteLine($<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">{i + 1}\t{oldFaces.Score}\t{oldFaces.Location.X}\t{oldFaces.Location.Y}\t{oldFaces.Location.Width}\t{oldFaces.Location.Height}</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">23</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">24</span> <span style="color: rgba(0, 0, 0, 1)"> Console.WriteLine();
</span><span style="color: rgba(0, 128, 128, 1)">25</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">26</span> <span style="color: rgba(0, 0, 255, 1)">var</span> oldPoints = viewFace.FaceMark(oldImg, oldFaces[<span style="color: rgba(128, 0, 128, 1)">0</span>]); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 获取 第一个人脸 的识别关键点。(人脸识别的关键点数据)</span>
<span style="color: rgba(0, 128, 128, 1)">27</span> oldEigenValues = viewFace.Extract(oldImg, oldPoints); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 获取 指定的关键点 的特征值。</span>
<span style="color: rgba(0, 128, 128, 1)">28</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">29</span> <span style="color: rgba(0, 0, 255, 1)">else</span> { oldEigenValues = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">float</span>[<span style="color: rgba(128, 0, 128, 1)">0</span>]; <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">未识别到人脸</span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">30</span> <span style="color: rgba(0, 0, 255, 1)">#endregion</span>
<span style="color: rgba(0, 128, 128, 1)">31</span>
<span style="color: rgba(0, 128, 128, 1)">32</span> <span style="color: rgba(0, 0, 255, 1)">#region</span> 识别新照片
<span style="color: rgba(0, 128, 128, 1)">33</span> <span style="color: rgba(0, 0, 255, 1)">float</span><span style="color: rgba(0, 0, 0, 1)">[] newEigenValues;
</span><span style="color: rgba(0, 128, 128, 1)">34</span> Bitmap newImg = (Bitmap)Image.FromFile(<span style="color: rgba(128, 0, 0, 1)">@"</span><span style="color: rgba(128, 0, 0, 1)">C:\Users\yangw\OneDrive\图片\Camera Roll\IMG_20181129_224339.jpg</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">新图片路径</span><span style="color: rgba(0, 128, 0, 1)">*/</span>); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 从文件中加载照片 </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 或者视频帧等</span>
<span style="color: rgba(0, 128, 128, 1)">35</span> <span style="color: rgba(0, 0, 255, 1)">var</span> newFaces = viewFace.FaceDetector(newImg); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 检测图片中包含的人脸信息。(置信度、位置、大小)</span>
<span style="color: rgba(0, 128, 128, 1)">36</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (newFaces.Length > <span style="color: rgba(128, 0, 128, 1)">0</span>) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">识别到人脸</span>
<span style="color: rgba(0, 128, 128, 1)">37</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">38</span> { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 打印人脸信息</span>
<span style="color: rgba(0, 128, 128, 1)">39</span> Console.WriteLine($<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">识别到的人脸数量:{newFaces.Length} 。人脸信息:\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">40</span> Console.WriteLine($<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">序号\t人脸置信度\t位置X\t位置Y\t宽度\t高度</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">41</span> <span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = <span style="color: rgba(128, 0, 128, 1)">0</span>; i < newFaces.Length; i++<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">42</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">43</span> Console.WriteLine($<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">{i + 1}\t{newFaces.Score}\t{newFaces.Location.X}\t{newFaces.Location.Y}\t{newFaces.Location.Width}\t{newFaces.Location.Height}</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">44</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">45</span> <span style="color: rgba(0, 0, 0, 1)"> Console.WriteLine();
</span><span style="color: rgba(0, 128, 128, 1)">46</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">47</span> <span style="color: rgba(0, 0, 255, 1)">var</span> newPoints = viewFace.FaceMark(newImg, newFaces[<span style="color: rgba(128, 0, 128, 1)">0</span>]); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 获取 第一个人脸 的识别关键点。(人脸识别的关键点数据)</span>
<span style="color: rgba(0, 128, 128, 1)">48</span> newEigenValues = viewFace.Extract(newImg, newPoints); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 获取 指定的关键点 的特征值。</span>
<span style="color: rgba(0, 128, 128, 1)">49</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">50</span> <span style="color: rgba(0, 0, 255, 1)">else</span> { newEigenValues = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">float</span>[<span style="color: rgba(128, 0, 128, 1)">0</span>]; <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">未识别到人脸</span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">51</span> <span style="color: rgba(0, 0, 255, 1)">#endregion</span>
<span style="color: rgba(0, 128, 128, 1)">52</span>
<span style="color: rgba(0, 128, 128, 1)">53</span> <span style="color: rgba(0, 0, 255, 1)">try</span>
<span style="color: rgba(0, 128, 128, 1)">54</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">55</span> <span style="color: rgba(0, 0, 255, 1)">float</span> similarity = viewFace.Similarity(oldEigenValues, newEigenValues); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 对比两张照片上的数据,确认是否是同一个人。</span>
<span style="color: rgba(0, 128, 128, 1)">56</span> Console.WriteLine($<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">阈值 = {Face.Threshold}\t相似度 = {similarity}</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">57</span> Console.WriteLine($<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">是否是同一个人:{viewFace.IsSelf(similarity)}</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">58</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">59</span> <span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e)
</span><span style="color: rgba(0, 128, 128, 1)">60</span> <span style="color: rgba(0, 0, 0, 1)"> { Console.WriteLine(e); }
</span><span style="color: rgba(0, 128, 128, 1)">61</span>
<span style="color: rgba(0, 128, 128, 1)">62</span> <span style="color: rgba(0, 0, 0, 1)"> Console.ReadKey();
</span><span style="color: rgba(0, 128, 128, 1)">63</span> }</pre>
</div>
<span class="cnblogs_code_collapse">ViewFaceCore 使用示例</span></div>
<p> </p>
<h2><strong>三、说明</strong></h2>
<p>命名空间:ViewFaceCore.Sharp : 人脸识别类所在的命名空间</p>
<ul>
<li>属性说明:</li>
<li>方法说明:</li>
</ul>
<table style="height: 124px; float: left; width: 866px" border="1" align="center"><caption> </caption>
<tbody>
<tr>
<td><span style="font-size: 16px"><strong>属性名称</strong></span></td>
<td><span style="font-size: 16px"><strong>类型</strong></span></td>
<td><span style="font-size: 16px"><strong>说明</strong></span></td>
<td><span style="font-size: 16px"><strong>默认值</strong></span></td>
</tr>
<tr>
<td>ModelPath</td>
<td>string</td>
<td>获取或设置模型路径 [ 如非必要,请勿修改 ]</td>
<td>./model/</td>
</tr>
<tr>
<td>FaceType</td>
<td>FaceType</td>
<td>获取或设置人脸类型</td>
<td>FaceType.Light</td>
</tr>
<tr>
<td>MarkType</td>
<td>MarkType</td>
<td>获取或设置人脸关键点类型</td>
<td>MarkType.Light</td>
</tr>
<tr>
<td>DetectorSetting</td>
<td>DetectorSetting</td>
<td>获取或设置人脸检测器设置</td>
<td>new DetectorSetting()</td>
</tr>
</tbody>
</table>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Drawing;
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> ViewFaceCore.Sharp;
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> ViewFaceCore.Sharp.Model;
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span>
<span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 识别 bitmap 中的人脸,并返回人脸的信息。</span>
<span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 0, 1)">FaceInfo[] FaceDetector(Bitmap);
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span>
<span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 识别 bitmap 中指定的人脸信息 info 的关键点坐标。</span>
<span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 0, 1)">FaceMarkPoint[] FaceMark(Bitmap, FaceInfo);
</span><span style="color: rgba(0, 128, 128, 1)">10</span>
<span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 提取人脸特征值。</span>
<span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 255, 1)">float</span><span style="color: rgba(0, 0, 0, 1)">[] Extract(Bitmap, FaceMarkPoint[]);
</span><span style="color: rgba(0, 128, 128, 1)">13</span>
<span style="color: rgba(0, 128, 128, 1)">14</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 计算特征值相似度。</span>
<span style="color: rgba(0, 128, 128, 1)">15</span> <span style="color: rgba(0, 0, 255, 1)">float</span> Similarity(<span style="color: rgba(0, 0, 255, 1)">float</span>[], <span style="color: rgba(0, 0, 255, 1)">float</span><span style="color: rgba(0, 0, 0, 1)">[]);
</span><span style="color: rgba(0, 128, 128, 1)">16</span>
<span style="color: rgba(0, 128, 128, 1)">17</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 判断相似度是否为同一个人。</span>
<span style="color: rgba(0, 128, 128, 1)">18</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> IsSelf(<span style="color: rgba(0, 0, 255, 1)">float</span>);</pre>
</div>
<h2><strong>四、实现</strong></h2>
<p><strong>此项目受到了 SeetaFaceEngine.NET 项目的启发</strong></p>
<p>这个项目本质上来说还是调用了 SeetaFace 的 C++ 类库来实现的人脸识别功能。针对本人遇到过的相关的类库的使用都不太方便,而且使用的 SeetaFace 的版本较老,故萌生了自己重新开发的想法。</p>
<p>本项目在开发完成之后为了方便调用,采用了 Nuget 包的形式,将所有需要的依赖以及最小识别模型一起打包。<strong>在使用时非常简单,只需要 nuget 安装,编写代码,运行即可,不需要多余的操作。</strong></p>
<p>首先查看 SeetaFace ,已经更新到了v3(v6即v3)(上面前辈的项目是基于v1开发的),最新版本暂时没有开源,但是可以免费商用。然后是根据以前的经验和 SeetaFace6 文档的指导,以及前辈的项目,做了以下操作。</p>
<p>1.对SeetaFace6 的接口进行了 C++ 形式的封装。</p>
<p>目前主要实现了 人脸检测,关键点提取,特征值提取,特征值对比几个人脸识别中的基础接口。有了这几个接口,可以完整的实现一套人脸识别和验证的流程。</p>
<ul>
<li>c++封装的接口代码如下:</li>
</ul>
<div class="cnblogs_code"><img id="code_img_closed_eaf465ba-5fd4-43ed-b2b4-e2b1097b3220" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_eaf465ba-5fd4-43ed-b2b4-e2b1097b3220" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_eaf465ba-5fd4-43ed-b2b4-e2b1097b3220" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> #include <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">seeta/FaceDetector.h</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(0, 128, 128, 1)">2</span> #include <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">seeta/FaceLandmarker.h</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(0, 128, 128, 1)">3</span> #include <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">seeta/FaceRecognizer.h</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(0, 128, 128, 1)">4</span>
<span style="color: rgba(0, 128, 128, 1)">5</span> #include <time.h>
<span style="color: rgba(0, 128, 128, 1)">6</span>
<span style="color: rgba(0, 128, 128, 1)">7</span> <span style="color: rgba(0, 0, 255, 1)">#define</span> View_Api extern "C" __declspec(dllexport)
<span style="color: rgba(0, 128, 128, 1)">8</span>
<span style="color: rgba(0, 128, 128, 1)">9</span> <span style="color: rgba(0, 0, 255, 1)">using</span> <span style="color: rgba(0, 0, 255, 1)">namespace</span><span style="color: rgba(0, 0, 0, 1)"> std;
</span><span style="color: rgba(0, 128, 128, 1)"> 10</span>
<span style="color: rgba(0, 128, 128, 1)"> 11</span> typedef <span style="color: rgba(0, 0, 255, 1)">void</span>(_stdcall* LogCallBack)(<span style="color: rgba(0, 0, 255, 1)">const</span> <span style="color: rgba(0, 0, 255, 1)">char</span>*<span style="color: rgba(0, 0, 0, 1)"> logText);
</span><span style="color: rgba(0, 128, 128, 1)"> 12</span>
<span style="color: rgba(0, 128, 128, 1)"> 13</span> <span style="color: rgba(0, 0, 255, 1)">string</span> modelPath = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">./model/</span><span style="color: rgba(128, 0, 0, 1)">"</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 模型所在路径</span>
<span style="color: rgba(0, 128, 128, 1)"> 14</span> LogCallBack logger = NULL; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 日志回调函数
</span><span style="color: rgba(0, 128, 128, 1)"> 15</span>
<span style="color: rgba(0, 128, 128, 1)"> 16</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 打印日志</span>
<span style="color: rgba(0, 128, 128, 1)"> 17</span> <span style="color: rgba(0, 0, 255, 1)">void</span> WriteLog(<span style="color: rgba(0, 0, 255, 1)">string</span> str) { <span style="color: rgba(0, 0, 255, 1)">if</span> (logger !=<span style="color: rgba(0, 0, 0, 1)"> NULL) { logger(str.c_str()); } }
</span><span style="color: rgba(0, 128, 128, 1)"> 18</span>
<span style="color: rgba(0, 128, 128, 1)"> 19</span> <span style="color: rgba(0, 0, 255, 1)">void</span> WriteMessage(<span style="color: rgba(0, 0, 255, 1)">string</span> fanctionName, <span style="color: rgba(0, 0, 255, 1)">string</span> message) { WriteLog(fanctionName + <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">\t Message:</span><span style="color: rgba(128, 0, 0, 1)">"</span> +<span style="color: rgba(0, 0, 0, 1)"> message); }
</span><span style="color: rgba(0, 128, 128, 1)"> 20</span> <span style="color: rgba(0, 0, 255, 1)">void</span> WriteModelName(<span style="color: rgba(0, 0, 255, 1)">string</span> fanctionName, <span style="color: rgba(0, 0, 255, 1)">string</span> modelName) { WriteLog(fanctionName + <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">\t Model.Name:</span><span style="color: rgba(128, 0, 0, 1)">"</span> +<span style="color: rgba(0, 0, 0, 1)"> modelName); }
</span><span style="color: rgba(0, 128, 128, 1)"> 21</span> <span style="color: rgba(0, 0, 255, 1)">void</span> WriteRunTime(<span style="color: rgba(0, 0, 255, 1)">string</span> fanctionName, <span style="color: rgba(0, 0, 255, 1)">int</span> start) { WriteLog(fanctionName + <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">\t Run.Time:</span><span style="color: rgba(128, 0, 0, 1)">"</span> + to_string(clock() - start) + <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)"> ms</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">); }
</span><span style="color: rgba(0, 128, 128, 1)"> 22</span> <span style="color: rgba(0, 0, 255, 1)">void</span> WriteError(<span style="color: rgba(0, 0, 255, 1)">string</span> fanctionName, <span style="color: rgba(0, 0, 255, 1)">const</span> std::exception& e) { WriteLog(fanctionName + <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">\t Error:</span><span style="color: rgba(128, 0, 0, 1)">"</span> +<span style="color: rgba(0, 0, 0, 1)"> e.what()); }
</span><span style="color: rgba(0, 128, 128, 1)"> 23</span>
<span style="color: rgba(0, 128, 128, 1)"> 24</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 注册日志回调函数</span>
<span style="color: rgba(0, 128, 128, 1)"> 25</span> View_Api <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> V_SetLogFunction(LogCallBack writeLog)
</span><span style="color: rgba(0, 128, 128, 1)"> 26</span> <span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)"> 27</span> logger =<span style="color: rgba(0, 0, 0, 1)"> writeLog;
</span><span style="color: rgba(0, 128, 128, 1)"> 28</span> WriteMessage(__FUNCDNAME__, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Successed.</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)"> 29</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)"> 30</span>
<span style="color: rgba(0, 128, 128, 1)"> 31</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 设置人脸模型目录</span>
<span style="color: rgba(0, 128, 128, 1)"> 32</span> View_Api <span style="color: rgba(0, 0, 255, 1)">void</span> V_SetModelPath(<span style="color: rgba(0, 0, 255, 1)">const</span> <span style="color: rgba(0, 0, 255, 1)">char</span>*<span style="color: rgba(0, 0, 0, 1)"> path)
</span><span style="color: rgba(0, 128, 128, 1)"> 33</span> <span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)"> 34</span> modelPath =<span style="color: rgba(0, 0, 0, 1)"> path;
</span><span style="color: rgba(0, 128, 128, 1)"> 35</span> WriteMessage(__FUNCDNAME__, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Model.Path:</span><span style="color: rgba(128, 0, 0, 1)">"</span> +<span style="color: rgba(0, 0, 0, 1)"> modelPath);
</span><span style="color: rgba(0, 128, 128, 1)"> 36</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)"> 37</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 获取人脸模型目录</span>
<span style="color: rgba(0, 128, 128, 1)"> 38</span> View_Api <span style="color: rgba(0, 0, 255, 1)">bool</span> V_GetModelPath(<span style="color: rgba(0, 0, 255, 1)">char</span>**<span style="color: rgba(0, 0, 0, 1)"> path)
</span><span style="color: rgba(0, 128, 128, 1)"> 39</span> <span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)"> 40</span> <span style="color: rgba(0, 0, 255, 1)">try</span>
<span style="color: rgba(0, 128, 128, 1)"> 41</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 42</span> <span style="color: rgba(0, 0, 255, 1)">#pragma</span> warning(disable:4996)
<span style="color: rgba(0, 128, 128, 1)"> 43</span> strcpy(*<span style="color: rgba(0, 0, 0, 1)">path, modelPath.c_str());
</span><span style="color: rgba(0, 128, 128, 1)"> 44</span>
<span style="color: rgba(0, 128, 128, 1)"> 45</span> <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 46</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)"> 47</span> <span style="color: rgba(0, 0, 255, 1)">catch</span> (<span style="color: rgba(0, 0, 255, 1)">const</span> std::exception&<span style="color: rgba(0, 0, 0, 1)"> e)
</span><span style="color: rgba(0, 128, 128, 1)"> 48</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 49</span> <span style="color: rgba(0, 0, 0, 1)"> WriteError(__FUNCDNAME__, e);
</span><span style="color: rgba(0, 128, 128, 1)"> 50</span> <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 51</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)"> 52</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)"> 53</span>
<span style="color: rgba(0, 128, 128, 1)"> 54</span> seeta::FaceDetector* v_faceDetector =<span style="color: rgba(0, 0, 0, 1)"> NULL;
</span><span style="color: rgba(0, 128, 128, 1)"> 55</span>
<span style="color: rgba(0, 128, 128, 1)"> 56</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 人脸检测结果</span>
<span style="color: rgba(0, 128, 128, 1)"> 57</span> <span style="color: rgba(0, 0, 255, 1)">static</span><span style="color: rgba(0, 0, 0, 1)"> SeetaFaceInfoArray detectorInfos;
</span><span style="color: rgba(0, 128, 128, 1)"> 58</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 人脸数量检测器</span>
<span style="color: rgba(0, 128, 128, 1)"> 59</span> View_Api <span style="color: rgba(0, 0, 255, 1)">int</span> V_DetectorSize(unsigned <span style="color: rgba(0, 0, 255, 1)">char</span>* imgData, <span style="color: rgba(0, 0, 255, 1)">int</span> width, <span style="color: rgba(0, 0, 255, 1)">int</span> height, <span style="color: rgba(0, 0, 255, 1)">int</span> channels, <span style="color: rgba(0, 0, 255, 1)">double</span> faceSize = <span style="color: rgba(128, 0, 128, 1)">20</span>, <span style="color: rgba(0, 0, 255, 1)">double</span> threshold = <span style="color: rgba(128, 0, 128, 1)">0.9</span>, <span style="color: rgba(0, 0, 255, 1)">double</span> maxWidth = <span style="color: rgba(128, 0, 128, 1)">2000</span>, <span style="color: rgba(0, 0, 255, 1)">double</span> maxHeight = <span style="color: rgba(128, 0, 128, 1)">2000</span>, <span style="color: rgba(0, 0, 255, 1)">int</span> type = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)"> 60</span> <span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)"> 61</span> <span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 62</span> clock_t start =<span style="color: rgba(0, 0, 0, 1)"> clock();
</span><span style="color: rgba(0, 128, 128, 1)"> 63</span>
<span style="color: rgba(0, 128, 128, 1)"> 64</span> SeetaImageData img =<span style="color: rgba(0, 0, 0, 1)"> { width, height, channels, imgData };
</span><span style="color: rgba(0, 128, 128, 1)"> 65</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (v_faceDetector ==<span style="color: rgba(0, 0, 0, 1)"> NULL) {
</span><span style="color: rgba(0, 128, 128, 1)"> 66</span> <span style="color: rgba(0, 0, 0, 1)"> seeta::ModelSetting setting;
</span><span style="color: rgba(0, 128, 128, 1)"> 67</span> <span style="color: rgba(0, 0, 0, 1)"> setting.set_device(SEETA_DEVICE_CPU);
</span><span style="color: rgba(0, 128, 128, 1)"> 68</span> <span style="color: rgba(0, 0, 255, 1)">string</span> modelName = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">face_detector.csta</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 69</span> <span style="color: rgba(0, 0, 255, 1)">switch</span><span style="color: rgba(0, 0, 0, 1)"> (type)
</span><span style="color: rgba(0, 128, 128, 1)"> 70</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 71</span> <span style="color: rgba(0, 0, 255, 1)">case</span> <span style="color: rgba(128, 0, 128, 1)">1</span>: modelName = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">mask_detector.csta</span><span style="color: rgba(128, 0, 0, 1)">"</span>; <span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 72</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)"> 73</span> setting.append(modelPath +<span style="color: rgba(0, 0, 0, 1)"> modelName);
</span><span style="color: rgba(0, 128, 128, 1)"> 74</span> <span style="color: rgba(0, 0, 0, 1)"> WriteModelName(__FUNCDNAME__, modelName);
</span><span style="color: rgba(0, 128, 128, 1)"> 75</span> v_faceDetector = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> seeta::FaceDetector(setting);
</span><span style="color: rgba(0, 128, 128, 1)"> 76</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)"> 77</span>
<span style="color: rgba(0, 128, 128, 1)"> 78</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (faceSize != <span style="color: rgba(128, 0, 128, 1)">20</span>) { v_faceDetector-><span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">(seeta::FaceDetector::Property::PROPERTY_MIN_FACE_SIZE, faceSize); }
</span><span style="color: rgba(0, 128, 128, 1)"> 79</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (threshold != <span style="color: rgba(128, 0, 128, 1)">0.9</span>) { v_faceDetector-><span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">(seeta::FaceDetector::Property::PROPERTY_THRESHOLD, threshold); }
</span><span style="color: rgba(0, 128, 128, 1)"> 80</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (maxWidth != <span style="color: rgba(128, 0, 128, 1)">2000</span>) { v_faceDetector-><span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">(seeta::FaceDetector::Property::PROPERTY_MAX_IMAGE_WIDTH, maxWidth); }
</span><span style="color: rgba(0, 128, 128, 1)"> 81</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (maxHeight != <span style="color: rgba(128, 0, 128, 1)">2000</span>) { v_faceDetector-><span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">(seeta::FaceDetector::Property::PROPERTY_MAX_IMAGE_HEIGHT, maxHeight); }
</span><span style="color: rgba(0, 128, 128, 1)"> 82</span>
<span style="color: rgba(0, 128, 128, 1)"> 83</span> auto infos = v_faceDetector-><span style="color: rgba(0, 0, 0, 1)">detect(img);
</span><span style="color: rgba(0, 128, 128, 1)"> 84</span> detectorInfos =<span style="color: rgba(0, 0, 0, 1)"> infos;
</span><span style="color: rgba(0, 128, 128, 1)"> 85</span>
<span style="color: rgba(0, 128, 128, 1)"> 86</span> WriteRunTime(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">V_Detector</span><span style="color: rgba(128, 0, 0, 1)">"</span>, start); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 此方法已经是人脸检测的全过程,故计时器显示为 人脸识别方法</span>
<span style="color: rgba(0, 128, 128, 1)"> 87</span> <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> infos.size;
</span><span style="color: rgba(0, 128, 128, 1)"> 88</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)"> 89</span> <span style="color: rgba(0, 0, 255, 1)">catch</span> (<span style="color: rgba(0, 0, 255, 1)">const</span> std::exception&<span style="color: rgba(0, 0, 0, 1)"> e)
</span><span style="color: rgba(0, 128, 128, 1)"> 90</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 91</span> <span style="color: rgba(0, 0, 0, 1)"> WriteError(__FUNCDNAME__, e);
</span><span style="color: rgba(0, 128, 128, 1)"> 92</span> <span style="color: rgba(0, 0, 255, 1)">return</span> -<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 93</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)"> 94</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)"> 95</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 人脸检测器</span>
<span style="color: rgba(0, 128, 128, 1)"> 96</span> View_Api <span style="color: rgba(0, 0, 255, 1)">bool</span> V_Detector(<span style="color: rgba(0, 0, 255, 1)">float</span>* score, <span style="color: rgba(0, 0, 255, 1)">int</span>* x, <span style="color: rgba(0, 0, 255, 1)">int</span>* y, <span style="color: rgba(0, 0, 255, 1)">int</span>* width, <span style="color: rgba(0, 0, 255, 1)">int</span>*<span style="color: rgba(0, 0, 0, 1)"> height)
</span><span style="color: rgba(0, 128, 128, 1)"> 97</span> <span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)"> 98</span> <span style="color: rgba(0, 0, 255, 1)">try</span>
<span style="color: rgba(0, 128, 128, 1)"> 99</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">100</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">clock_t start = clock();</span>
<span style="color: rgba(0, 128, 128, 1)">101</span>
<span style="color: rgba(0, 128, 128, 1)">102</span> <span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = <span style="color: rgba(128, 0, 128, 1)">0</span>; i < detectorInfos.size; i++, detectorInfos.data++<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">103</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">104</span> *score = detectorInfos.data-><span style="color: rgba(0, 0, 0, 1)">score;
</span><span style="color: rgba(0, 128, 128, 1)">105</span> *x = detectorInfos.data-><span style="color: rgba(0, 0, 0, 1)">pos.x;
</span><span style="color: rgba(0, 128, 128, 1)">106</span> *y = detectorInfos.data-><span style="color: rgba(0, 0, 0, 1)">pos.y;
</span><span style="color: rgba(0, 128, 128, 1)">107</span> *width = detectorInfos.data-><span style="color: rgba(0, 0, 0, 1)">pos.width;
</span><span style="color: rgba(0, 128, 128, 1)">108</span> *height = detectorInfos.data-><span style="color: rgba(0, 0, 0, 1)">pos.height;
</span><span style="color: rgba(0, 128, 128, 1)">109</span> score++, x++, y++, width++, height++<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">110</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">111</span> detectorInfos.data =<span style="color: rgba(0, 0, 0, 1)"> NULL;
</span><span style="color: rgba(0, 128, 128, 1)">112</span> detectorInfos.size =<span style="color: rgba(0, 0, 0, 1)"> NULL;
</span><span style="color: rgba(0, 128, 128, 1)">113</span>
<span style="color: rgba(0, 128, 128, 1)">114</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">WriteRunTime(__FUNCDNAME__, start); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 此方法只是将 人脸数量检测器 获取到的数据赋值传递,并不耗时。故不显示此方法的调用时间</span>
<span style="color: rgba(0, 128, 128, 1)">115</span> <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">116</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">117</span> <span style="color: rgba(0, 0, 255, 1)">catch</span> (<span style="color: rgba(0, 0, 255, 1)">const</span> std::exception&<span style="color: rgba(0, 0, 0, 1)"> e)
</span><span style="color: rgba(0, 128, 128, 1)">118</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">119</span> <span style="color: rgba(0, 0, 0, 1)"> WriteError(__FUNCDNAME__, e);
</span><span style="color: rgba(0, 128, 128, 1)">120</span> <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">121</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">122</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">123</span>
<span style="color: rgba(0, 128, 128, 1)">124</span>
<span style="color: rgba(0, 128, 128, 1)">125</span> seeta::FaceLandmarker* v_faceLandmarker =<span style="color: rgba(0, 0, 0, 1)"> NULL;
</span><span style="color: rgba(0, 128, 128, 1)">126</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 人脸关键点数量</span>
<span style="color: rgba(0, 128, 128, 1)">127</span> View_Api <span style="color: rgba(0, 0, 255, 1)">int</span> V_FaceMarkSize(<span style="color: rgba(0, 0, 255, 1)">int</span> type = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">128</span> <span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">129</span> <span style="color: rgba(0, 0, 255, 1)">try</span>
<span style="color: rgba(0, 128, 128, 1)">130</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">131</span> clock_t start =<span style="color: rgba(0, 0, 0, 1)"> clock();
</span><span style="color: rgba(0, 128, 128, 1)">132</span>
<span style="color: rgba(0, 128, 128, 1)">133</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (v_faceLandmarker ==<span style="color: rgba(0, 0, 0, 1)"> NULL) {
</span><span style="color: rgba(0, 128, 128, 1)">134</span> <span style="color: rgba(0, 0, 0, 1)"> seeta::ModelSetting setting;
</span><span style="color: rgba(0, 128, 128, 1)">135</span> <span style="color: rgba(0, 0, 0, 1)"> setting.set_device(SEETA_DEVICE_CPU);
</span><span style="color: rgba(0, 128, 128, 1)">136</span> <span style="color: rgba(0, 0, 255, 1)">string</span> modelName = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">face_landmarker_pts68.csta</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">137</span> <span style="color: rgba(0, 0, 255, 1)">switch</span><span style="color: rgba(0, 0, 0, 1)"> (type)
</span><span style="color: rgba(0, 128, 128, 1)">138</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">139</span> <span style="color: rgba(0, 0, 255, 1)">case</span> <span style="color: rgba(128, 0, 128, 1)">1</span>: modelName = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">face_landmarker_mask_pts5.csta</span><span style="color: rgba(128, 0, 0, 1)">"</span>; <span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">140</span> <span style="color: rgba(0, 0, 255, 1)">case</span> <span style="color: rgba(128, 0, 128, 1)">2</span>: modelName = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">face_landmarker_pts5.csta</span><span style="color: rgba(128, 0, 0, 1)">"</span>; <span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">141</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">142</span> setting.append(modelPath +<span style="color: rgba(0, 0, 0, 1)"> modelName);
</span><span style="color: rgba(0, 128, 128, 1)">143</span> <span style="color: rgba(0, 0, 0, 1)"> WriteModelName(__FUNCDNAME__, modelName);
</span><span style="color: rgba(0, 128, 128, 1)">144</span> v_faceLandmarker = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> seeta::FaceLandmarker(setting);
</span><span style="color: rgba(0, 128, 128, 1)">145</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">146</span> <span style="color: rgba(0, 0, 255, 1)">int</span> size = v_faceLandmarker-><span style="color: rgba(0, 0, 0, 1)">number();
</span><span style="color: rgba(0, 128, 128, 1)">147</span>
<span style="color: rgba(0, 128, 128, 1)">148</span> <span style="color: rgba(0, 0, 0, 1)"> WriteRunTime(__FUNCDNAME__, start);
</span><span style="color: rgba(0, 128, 128, 1)">149</span> <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> size;
</span><span style="color: rgba(0, 128, 128, 1)">150</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">151</span> <span style="color: rgba(0, 0, 255, 1)">catch</span> (<span style="color: rgba(0, 0, 255, 1)">const</span> std::exception&<span style="color: rgba(0, 0, 0, 1)"> e)
</span><span style="color: rgba(0, 128, 128, 1)">152</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">153</span> <span style="color: rgba(0, 0, 0, 1)"> WriteError(__FUNCDNAME__, e);
</span><span style="color: rgba(0, 128, 128, 1)">154</span> <span style="color: rgba(0, 0, 255, 1)">return</span> -<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">155</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">156</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">157</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 人脸关键点</span>
<span style="color: rgba(0, 128, 128, 1)">158</span> View_Api <span style="color: rgba(0, 0, 255, 1)">bool</span> V_FaceMark(unsigned <span style="color: rgba(0, 0, 255, 1)">char</span>* imgData, <span style="color: rgba(0, 0, 255, 1)">int</span> width, <span style="color: rgba(0, 0, 255, 1)">int</span> height, <span style="color: rgba(0, 0, 255, 1)">int</span> channels, <span style="color: rgba(0, 0, 255, 1)">int</span> x, <span style="color: rgba(0, 0, 255, 1)">int</span> y, <span style="color: rgba(0, 0, 255, 1)">int</span> fWidth, <span style="color: rgba(0, 0, 255, 1)">int</span> fHeight, <span style="color: rgba(0, 0, 255, 1)">double</span>* pointX, <span style="color: rgba(0, 0, 255, 1)">double</span>* pointY, <span style="color: rgba(0, 0, 255, 1)">int</span> type = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">159</span> <span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">160</span> <span style="color: rgba(0, 0, 255, 1)">try</span>
<span style="color: rgba(0, 128, 128, 1)">161</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">162</span> clock_t start =<span style="color: rgba(0, 0, 0, 1)"> clock();
</span><span style="color: rgba(0, 128, 128, 1)">163</span>
<span style="color: rgba(0, 128, 128, 1)">164</span> SeetaImageData img =<span style="color: rgba(0, 0, 0, 1)"> { width, height, channels, imgData };
</span><span style="color: rgba(0, 128, 128, 1)">165</span> SeetaRect face =<span style="color: rgba(0, 0, 0, 1)"> { x, y, fWidth, fHeight };
</span><span style="color: rgba(0, 128, 128, 1)">166</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (v_faceLandmarker ==<span style="color: rgba(0, 0, 0, 1)"> NULL) {
</span><span style="color: rgba(0, 128, 128, 1)">167</span> <span style="color: rgba(0, 0, 0, 1)"> seeta::ModelSetting setting;
</span><span style="color: rgba(0, 128, 128, 1)">168</span> <span style="color: rgba(0, 0, 0, 1)"> setting.set_device(SEETA_DEVICE_CPU);
</span><span style="color: rgba(0, 128, 128, 1)">169</span> <span style="color: rgba(0, 0, 255, 1)">string</span> modelName = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">face_landmarker_pts68.csta</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">170</span> <span style="color: rgba(0, 0, 255, 1)">switch</span><span style="color: rgba(0, 0, 0, 1)"> (type)
</span><span style="color: rgba(0, 128, 128, 1)">171</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">172</span> <span style="color: rgba(0, 0, 255, 1)">case</span> <span style="color: rgba(128, 0, 128, 1)">1</span>: modelName = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">face_landmarker_mask_pts5.csta</span><span style="color: rgba(128, 0, 0, 1)">"</span>; <span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">173</span> <span style="color: rgba(0, 0, 255, 1)">case</span> <span style="color: rgba(128, 0, 128, 1)">2</span>: modelName = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">face_landmarker_pts5.csta</span><span style="color: rgba(128, 0, 0, 1)">"</span>; <span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">174</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">175</span> setting.append(modelPath +<span style="color: rgba(0, 0, 0, 1)"> modelName);
</span><span style="color: rgba(0, 128, 128, 1)">176</span> <span style="color: rgba(0, 0, 0, 1)"> WriteModelName(__FUNCDNAME__, modelName);
</span><span style="color: rgba(0, 128, 128, 1)">177</span> v_faceLandmarker = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> seeta::FaceLandmarker(setting);
</span><span style="color: rgba(0, 128, 128, 1)">178</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">179</span> std::vector<SeetaPointF> _points = v_faceLandmarker-><span style="color: rgba(0, 0, 0, 1)">mark(img, face);
</span><span style="color: rgba(0, 128, 128, 1)">180</span>
<span style="color: rgba(0, 128, 128, 1)">181</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">_points.empty()) {
</span><span style="color: rgba(0, 128, 128, 1)">182</span> <span style="color: rgba(0, 0, 255, 1)">for</span> (auto iter = _points.begin(); iter != _points.end(); iter++<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">183</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">184</span> *pointX = (*<span style="color: rgba(0, 0, 0, 1)">iter).x;
</span><span style="color: rgba(0, 128, 128, 1)">185</span> *pointY = (*<span style="color: rgba(0, 0, 0, 1)">iter).y;
</span><span style="color: rgba(0, 128, 128, 1)">186</span> pointX++<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">187</span> pointY++<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">188</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">189</span>
<span style="color: rgba(0, 128, 128, 1)">190</span> <span style="color: rgba(0, 0, 0, 1)"> WriteRunTime(__FUNCDNAME__, start);
</span><span style="color: rgba(0, 128, 128, 1)">191</span> <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">192</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">193</span> <span style="color: rgba(0, 0, 255, 1)">else</span> { <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">; }
</span><span style="color: rgba(0, 128, 128, 1)">194</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">195</span> <span style="color: rgba(0, 0, 255, 1)">catch</span> (<span style="color: rgba(0, 0, 255, 1)">const</span> std::exception&<span style="color: rgba(0, 0, 0, 1)"> e)
</span><span style="color: rgba(0, 128, 128, 1)">196</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">197</span> <span style="color: rgba(0, 0, 0, 1)"> WriteError(__FUNCDNAME__, e);
</span><span style="color: rgba(0, 128, 128, 1)">198</span> <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">199</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">200</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">201</span>
<span style="color: rgba(0, 128, 128, 1)">202</span> seeta::FaceRecognizer* v_faceRecognizer =<span style="color: rgba(0, 0, 0, 1)"> NULL;
</span><span style="color: rgba(0, 128, 128, 1)">203</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 获取人脸特征值长度</span>
<span style="color: rgba(0, 128, 128, 1)">204</span> View_Api <span style="color: rgba(0, 0, 255, 1)">int</span> V_ExtractSize(<span style="color: rgba(0, 0, 255, 1)">int</span> type = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">205</span> <span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">206</span> <span style="color: rgba(0, 0, 255, 1)">try</span>
<span style="color: rgba(0, 128, 128, 1)">207</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">208</span> clock_t start =<span style="color: rgba(0, 0, 0, 1)"> clock();
</span><span style="color: rgba(0, 128, 128, 1)">209</span>
<span style="color: rgba(0, 128, 128, 1)">210</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (v_faceRecognizer ==<span style="color: rgba(0, 0, 0, 1)"> NULL) {
</span><span style="color: rgba(0, 128, 128, 1)">211</span> <span style="color: rgba(0, 0, 0, 1)"> seeta::ModelSetting setting;
</span><span style="color: rgba(0, 128, 128, 1)">212</span> setting.set_id(<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">213</span> <span style="color: rgba(0, 0, 0, 1)"> setting.set_device(SEETA_DEVICE_CPU);
</span><span style="color: rgba(0, 128, 128, 1)">214</span> <span style="color: rgba(0, 0, 255, 1)">string</span> modelName = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">face_recognizer.csta</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">215</span> <span style="color: rgba(0, 0, 255, 1)">switch</span><span style="color: rgba(0, 0, 0, 1)"> (type)
</span><span style="color: rgba(0, 128, 128, 1)">216</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">217</span> <span style="color: rgba(0, 0, 255, 1)">case</span> <span style="color: rgba(128, 0, 128, 1)">1</span>: modelName = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">face_recognizer_mask.csta</span><span style="color: rgba(128, 0, 0, 1)">"</span>; <span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">218</span> <span style="color: rgba(0, 0, 255, 1)">case</span> <span style="color: rgba(128, 0, 128, 1)">2</span>: modelName = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">face_recognizer_light.csta</span><span style="color: rgba(128, 0, 0, 1)">"</span>; <span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">219</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">220</span> setting.append(modelPath +<span style="color: rgba(0, 0, 0, 1)"> modelName);
</span><span style="color: rgba(0, 128, 128, 1)">221</span> <span style="color: rgba(0, 0, 0, 1)"> WriteModelName(__FUNCDNAME__, modelName);
</span><span style="color: rgba(0, 128, 128, 1)">222</span> v_faceRecognizer = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> seeta::FaceRecognizer(setting);
</span><span style="color: rgba(0, 128, 128, 1)">223</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">224</span> <span style="color: rgba(0, 0, 255, 1)">int</span> length = v_faceRecognizer-><span style="color: rgba(0, 0, 0, 1)">GetExtractFeatureSize();
</span><span style="color: rgba(0, 128, 128, 1)">225</span>
<span style="color: rgba(0, 128, 128, 1)">226</span> <span style="color: rgba(0, 0, 0, 1)"> WriteRunTime(__FUNCDNAME__, start);
</span><span style="color: rgba(0, 128, 128, 1)">227</span> <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> length;
</span><span style="color: rgba(0, 128, 128, 1)">228</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">229</span> <span style="color: rgba(0, 0, 255, 1)">catch</span> (<span style="color: rgba(0, 0, 255, 1)">const</span> std::exception&<span style="color: rgba(0, 0, 0, 1)"> e)
</span><span style="color: rgba(0, 128, 128, 1)">230</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">231</span> <span style="color: rgba(0, 0, 0, 1)"> WriteError(__FUNCDNAME__, e);
</span><span style="color: rgba(0, 128, 128, 1)">232</span> <span style="color: rgba(0, 0, 255, 1)">return</span> -<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">233</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">234</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">235</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 提取人脸特征值</span>
<span style="color: rgba(0, 128, 128, 1)">236</span> View_Api <span style="color: rgba(0, 0, 255, 1)">bool</span> V_Extract(unsigned <span style="color: rgba(0, 0, 255, 1)">char</span>* imgData, <span style="color: rgba(0, 0, 255, 1)">int</span> width, <span style="color: rgba(0, 0, 255, 1)">int</span> height, <span style="color: rgba(0, 0, 255, 1)">int</span> channels, SeetaPointF* points, <span style="color: rgba(0, 0, 255, 1)">float</span>* features, <span style="color: rgba(0, 0, 255, 1)">int</span> type = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">237</span> <span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">238</span> <span style="color: rgba(0, 0, 255, 1)">try</span>
<span style="color: rgba(0, 128, 128, 1)">239</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">240</span> clock_t start =<span style="color: rgba(0, 0, 0, 1)"> clock();
</span><span style="color: rgba(0, 128, 128, 1)">241</span>
<span style="color: rgba(0, 128, 128, 1)">242</span> SeetaImageData img =<span style="color: rgba(0, 0, 0, 1)"> { width, height, channels, imgData };
</span><span style="color: rgba(0, 128, 128, 1)">243</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (v_faceRecognizer ==<span style="color: rgba(0, 0, 0, 1)"> NULL) {
</span><span style="color: rgba(0, 128, 128, 1)">244</span> <span style="color: rgba(0, 0, 0, 1)"> seeta::ModelSetting setting;
</span><span style="color: rgba(0, 128, 128, 1)">245</span> setting.set_id(<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">246</span> <span style="color: rgba(0, 0, 0, 1)"> setting.set_device(SEETA_DEVICE_CPU);
</span><span style="color: rgba(0, 128, 128, 1)">247</span> <span style="color: rgba(0, 0, 255, 1)">string</span> modelName = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">face_recognizer.csta</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">248</span> <span style="color: rgba(0, 0, 255, 1)">switch</span><span style="color: rgba(0, 0, 0, 1)"> (type)
</span><span style="color: rgba(0, 128, 128, 1)">249</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">250</span> <span style="color: rgba(0, 0, 255, 1)">case</span> <span style="color: rgba(128, 0, 128, 1)">1</span>: modelName = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">face_recognizer_mask.csta</span><span style="color: rgba(128, 0, 0, 1)">"</span>; <span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">251</span> <span style="color: rgba(0, 0, 255, 1)">case</span> <span style="color: rgba(128, 0, 128, 1)">2</span>: modelName = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">face_recognizer_light.csta</span><span style="color: rgba(128, 0, 0, 1)">"</span>; <span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">252</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">253</span> setting.append(modelPath +<span style="color: rgba(0, 0, 0, 1)"> modelName);
</span><span style="color: rgba(0, 128, 128, 1)">254</span> <span style="color: rgba(0, 0, 0, 1)"> WriteModelName(__FUNCDNAME__, modelName);
</span><span style="color: rgba(0, 128, 128, 1)">255</span> v_faceRecognizer = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> seeta::FaceRecognizer(setting);
</span><span style="color: rgba(0, 128, 128, 1)">256</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">257</span> <span style="color: rgba(0, 0, 255, 1)">int</span> length = v_faceRecognizer-><span style="color: rgba(0, 0, 0, 1)">GetExtractFeatureSize();
</span><span style="color: rgba(0, 128, 128, 1)">258</span> std::shared_ptr<<span style="color: rgba(0, 0, 255, 1)">float</span>> _features(<span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">float</span>, std::default_delete<<span style="color: rgba(0, 0, 255, 1)">float</span>[]><span style="color: rgba(0, 0, 0, 1)">());
</span><span style="color: rgba(0, 128, 128, 1)">259</span> v_faceRecognizer->Extract(img, points, _features.<span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)">());
</span><span style="color: rgba(0, 128, 128, 1)">260</span>
<span style="color: rgba(0, 128, 128, 1)">261</span> <span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = <span style="color: rgba(128, 0, 128, 1)">0</span>; i < length; i++<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">262</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">263</span> *features = _features.<span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)">();
</span><span style="color: rgba(0, 128, 128, 1)">264</span> features++<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">265</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">266</span>
<span style="color: rgba(0, 128, 128, 1)">267</span> <span style="color: rgba(0, 0, 0, 1)"> WriteRunTime(__FUNCDNAME__, start);
</span><span style="color: rgba(0, 128, 128, 1)">268</span> <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">269</span>
<span style="color: rgba(0, 128, 128, 1)">270</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">271</span> <span style="color: rgba(0, 0, 255, 1)">catch</span> (<span style="color: rgba(0, 0, 255, 1)">const</span> std::exception&<span style="color: rgba(0, 0, 0, 1)"> e)
</span><span style="color: rgba(0, 128, 128, 1)">272</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">273</span> <span style="color: rgba(0, 0, 0, 1)"> WriteError(__FUNCDNAME__, e);
</span><span style="color: rgba(0, 128, 128, 1)">274</span> <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">275</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">276</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">277</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 人脸特征值相似度计算</span>
<span style="color: rgba(0, 128, 128, 1)">278</span> View_Api <span style="color: rgba(0, 0, 255, 1)">float</span> V_CalculateSimilarity(<span style="color: rgba(0, 0, 255, 1)">float</span>* leftFeatures, <span style="color: rgba(0, 0, 255, 1)">float</span>* rightFeatures, <span style="color: rgba(0, 0, 255, 1)">int</span> type = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">279</span> <span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">280</span> <span style="color: rgba(0, 0, 255, 1)">try</span>
<span style="color: rgba(0, 128, 128, 1)">281</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">282</span> clock_t start =<span style="color: rgba(0, 0, 0, 1)"> clock();
</span><span style="color: rgba(0, 128, 128, 1)">283</span>
<span style="color: rgba(0, 128, 128, 1)">284</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (v_faceRecognizer ==<span style="color: rgba(0, 0, 0, 1)"> NULL) {
</span><span style="color: rgba(0, 128, 128, 1)">285</span> <span style="color: rgba(0, 0, 0, 1)"> seeta::ModelSetting setting;
</span><span style="color: rgba(0, 128, 128, 1)">286</span> setting.set_id(<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">287</span> <span style="color: rgba(0, 0, 0, 1)"> setting.set_device(SEETA_DEVICE_CPU);
</span><span style="color: rgba(0, 128, 128, 1)">288</span> <span style="color: rgba(0, 0, 255, 1)">string</span> modelName = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">face_recognizer.csta</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">289</span> <span style="color: rgba(0, 0, 255, 1)">switch</span><span style="color: rgba(0, 0, 0, 1)"> (type)
</span><span style="color: rgba(0, 128, 128, 1)">290</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">291</span> <span style="color: rgba(0, 0, 255, 1)">case</span> <span style="color: rgba(128, 0, 128, 1)">1</span>: modelName = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">face_recognizer_mask.csta</span><span style="color: rgba(128, 0, 0, 1)">"</span>; <span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">292</span> <span style="color: rgba(0, 0, 255, 1)">case</span> <span style="color: rgba(128, 0, 128, 1)">2</span>: modelName = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">face_recognizer_light.csta</span><span style="color: rgba(128, 0, 0, 1)">"</span>; <span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">293</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">294</span> setting.append(modelPath +<span style="color: rgba(0, 0, 0, 1)"> modelName);
</span><span style="color: rgba(0, 128, 128, 1)">295</span> <span style="color: rgba(0, 0, 0, 1)"> WriteModelName(__FUNCDNAME__, modelName);
</span><span style="color: rgba(0, 128, 128, 1)">296</span> v_faceRecognizer = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> seeta::FaceRecognizer(setting);
</span><span style="color: rgba(0, 128, 128, 1)">297</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">298</span>
<span style="color: rgba(0, 128, 128, 1)">299</span> auto similarity = v_faceRecognizer-><span style="color: rgba(0, 0, 0, 1)">CalculateSimilarity(leftFeatures, rightFeatures);
</span><span style="color: rgba(0, 128, 128, 1)">300</span> WriteMessage(__FUNCDNAME__, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Similarity = </span><span style="color: rgba(128, 0, 0, 1)">"</span> +<span style="color: rgba(0, 0, 0, 1)"> to_string(similarity));
</span><span style="color: rgba(0, 128, 128, 1)">301</span> <span style="color: rgba(0, 0, 0, 1)"> WriteRunTime(__FUNCDNAME__, start);
</span><span style="color: rgba(0, 128, 128, 1)">302</span> <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> similarity;
</span><span style="color: rgba(0, 128, 128, 1)">303</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">304</span> <span style="color: rgba(0, 0, 255, 1)">catch</span> (<span style="color: rgba(0, 0, 255, 1)">const</span> std::exception&<span style="color: rgba(0, 0, 0, 1)"> e)
</span><span style="color: rgba(0, 128, 128, 1)">305</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">306</span> <span style="color: rgba(0, 0, 0, 1)"> WriteError(__FUNCDNAME__, e);
</span><span style="color: rgba(0, 128, 128, 1)">307</span> <span style="color: rgba(0, 0, 255, 1)">return</span> -<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">308</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">309</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">310</span>
<span style="color: rgba(0, 128, 128, 1)">311</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 释放资源</span>
<span style="color: rgba(0, 128, 128, 1)">312</span> View_Api <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> V_Dispose()
</span><span style="color: rgba(0, 128, 128, 1)">313</span> <span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">314</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (v_faceDetector != NULL) <span style="color: rgba(0, 0, 255, 1)">delete</span><span style="color: rgba(0, 0, 0, 1)"> v_faceDetector;
</span><span style="color: rgba(0, 128, 128, 1)">315</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (v_faceLandmarker != NULL) <span style="color: rgba(0, 0, 255, 1)">delete</span><span style="color: rgba(0, 0, 0, 1)"> v_faceLandmarker;
</span><span style="color: rgba(0, 128, 128, 1)">316</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (v_faceRecognizer != NULL) <span style="color: rgba(0, 0, 255, 1)">delete</span><span style="color: rgba(0, 0, 0, 1)"> v_faceRecognizer;
</span><span style="color: rgba(0, 128, 128, 1)">317</span> }</pre>
</div>
<span class="cnblogs_code_collapse">C++ 封装层</span></div>
<p>2.采用 C# 对上诉接口进行了导入。</p>
<p>因为C++的项目测CPU架构区分x86和x64,所以C# 层也需要区分架构封装</p>
<div class="cnblogs_code"><img id="code_img_closed_9bbb6485-019d-474e-ba74-eb434b364457" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_9bbb6485-019d-474e-ba74-eb434b364457" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_9bbb6485-019d-474e-ba74-eb434b364457" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Runtime.InteropServices;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Text;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> ViewFaceCore.Sharp.Model;
</span><span style="color: rgba(0, 0, 255, 1)">namespace</span><span style="color: rgba(0, 0, 0, 1)"> ViewFaceCore.Plus
{
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 日志回调函数
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="logText"></param></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">delegate</span> <span style="color: rgba(0, 0, 255, 1)">void</span> LogCallBack(<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> logText);
</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> ViewFacePlus64
{
</span><span style="color: rgba(0, 0, 255, 1)">const</span> <span style="color: rgba(0, 0, 255, 1)">string</span> LibraryPath = <span style="color: rgba(128, 0, 0, 1)">@"</span><span style="color: rgba(128, 0, 0, 1)">FaceLibraries\x64\ViewFace.dll</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 设置日志回调函数(用于日志打印)
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="writeLog"></param></span>
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> SetLogFunction(LogCallBack writeLog);
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 设置人脸模型的目录
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="path"></param></span>
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span> SetModelPath(<span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] path);
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 设置人脸模型的目录
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="path"></param></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span> SetModelPath(<span style="color: rgba(0, 0, 255, 1)">string</span> path) =><span style="color: rgba(0, 0, 0, 1)"> SetModelPath(Encoding.UTF8.GetBytes(path));
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 释放使用的资源
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> ViewDispose();
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 获取人脸模型的目录
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="path"></param></span>
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> GetModelPathEx(<span style="color: rgba(0, 0, 255, 1)">ref</span> <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> path);
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 获取人脸模型的目录
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">string</span> GetModelPath() { <span style="color: rgba(0, 0, 255, 1)">string</span> path = <span style="color: rgba(0, 0, 255, 1)">string</span>.Empty; GetModelPathEx(<span style="color: rgba(0, 0, 255, 1)">ref</span> path); <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> path; }
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 人脸检测器检测到的人脸数量
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="imgData"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="width"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="height"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="channels"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="faceSize"></span><span style="color: rgba(0, 128, 0, 1)">最小人脸是人脸检测器常用的一个概念,默认值为20,单位像素。
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><para></span><span style="color: rgba(0, 128, 0, 1)">最小人脸和检测器性能息息相关。主要方面是速度,使用建议上,我们建议在应用范围内,这个值设定的越大越好。SeetaFace采用的是BindingBox Regresion的方式训练的检测器。如果最小人脸参数设置为80的话,从检测能力上,可以将原图缩小的原来的1/4,这样从计算复杂度上,能够比最小人脸设置为20时,提速到16倍。</span><span style="color: rgba(128, 128, 128, 1)"></para></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="threshold"></span><span style="color: rgba(0, 128, 0, 1)">检测器阈值默认值是0.9,合理范围为。这个值一般不进行调整,除了用来处理一些极端情况。这个值设置的越小,漏检的概率越小,同时误检的概率会提高</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="maxWidth"></span><span style="color: rgba(0, 128, 0, 1)">可检测的图像最大宽度。默认值2000。</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="maxHeight"></span><span style="color: rgba(0, 128, 0, 1)">可检测的图像最大高度。默认值2000。</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="type"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">int</span> DetectorSize(<span style="color: rgba(0, 0, 255, 1)">byte</span>[] imgData, <span style="color: rgba(0, 0, 255, 1)">int</span> width, <span style="color: rgba(0, 0, 255, 1)">int</span> height, <span style="color: rgba(0, 0, 255, 1)">int</span> channels, <span style="color: rgba(0, 0, 255, 1)">double</span> faceSize = <span style="color: rgba(128, 0, 128, 1)">20</span>, <span style="color: rgba(0, 0, 255, 1)">double</span> threshold = <span style="color: rgba(128, 0, 128, 1)">0.9</span>, <span style="color: rgba(0, 0, 255, 1)">double</span> maxWidth = <span style="color: rgba(128, 0, 128, 1)">2000</span>, <span style="color: rgba(0, 0, 255, 1)">double</span> maxHeight = <span style="color: rgba(128, 0, 128, 1)">2000</span>, <span style="color: rgba(0, 0, 255, 1)">int</span> type = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 人脸检测器
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><para></span><span style="color: rgba(0, 128, 0, 1)">调用此方法前必须先调用 </span><span style="color: rgba(128, 128, 128, 1)"><see cref="DetectorSize(byte[], int, int, int, double, double, double, double, int)"/></para></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="score"></span><span style="color: rgba(0, 128, 0, 1)">人脸置信度集合</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="x"></span><span style="color: rgba(0, 128, 0, 1)">人脸位置集合</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="y"></span><span style="color: rgba(0, 128, 0, 1)">人脸位置集合</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="width"></span><span style="color: rgba(0, 128, 0, 1)">人脸大小集合</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="height"></span><span style="color: rgba(0, 128, 0, 1)">人脸大小集合</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> Detector(<span style="color: rgba(0, 0, 255, 1)">float</span>[] score, <span style="color: rgba(0, 0, 255, 1)">int</span>[] x, <span style="color: rgba(0, 0, 255, 1)">int</span>[] y, <span style="color: rgba(0, 0, 255, 1)">int</span>[] width, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">[] height);
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 人脸关键点数量
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">int</span> FaceMarkSize(<span style="color: rgba(0, 0, 255, 1)">int</span> type = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 人脸关键点
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="imgData"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="width"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="height"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="channels"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="x"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="y"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="fWidth"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="fHeight"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="pointX"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="pointY"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="type"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> FaceMark(<span style="color: rgba(0, 0, 255, 1)">byte</span>[] imgData, <span style="color: rgba(0, 0, 255, 1)">int</span> width, <span style="color: rgba(0, 0, 255, 1)">int</span> height, <span style="color: rgba(0, 0, 255, 1)">int</span> channels, <span style="color: rgba(0, 0, 255, 1)">int</span> x, <span style="color: rgba(0, 0, 255, 1)">int</span> y, <span style="color: rgba(0, 0, 255, 1)">int</span> fWidth, <span style="color: rgba(0, 0, 255, 1)">int</span> fHeight, <span style="color: rgba(0, 0, 255, 1)">double</span>[] pointX, <span style="color: rgba(0, 0, 255, 1)">double</span>[] pointY, <span style="color: rgba(0, 0, 255, 1)">int</span> type = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 提取特征值
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="imgData"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="width"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="height"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="channels"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="points"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="features"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="type"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> Extract(<span style="color: rgba(0, 0, 255, 1)">byte</span>[] imgData, <span style="color: rgba(0, 0, 255, 1)">int</span> width, <span style="color: rgba(0, 0, 255, 1)">int</span> height, <span style="color: rgba(0, 0, 255, 1)">int</span> channels, FaceMarkPoint[] points, <span style="color: rgba(0, 0, 255, 1)">float</span>[] features, <span style="color: rgba(0, 0, 255, 1)">int</span> type = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 特征值大小
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">int</span> ExtractSize(<span style="color: rgba(0, 0, 255, 1)">int</span> type = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 计算相似度
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="leftFeatures"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="rightFeatures"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="type"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">float</span> Similarity(<span style="color: rgba(0, 0, 255, 1)">float</span>[] leftFeatures, <span style="color: rgba(0, 0, 255, 1)">float</span>[] rightFeatures, <span style="color: rgba(0, 0, 255, 1)">int</span> type = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
}
</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> ViewFacePlus32
{
</span><span style="color: rgba(0, 0, 255, 1)">const</span> <span style="color: rgba(0, 0, 255, 1)">string</span> LibraryPath = <span style="color: rgba(128, 0, 0, 1)">@"</span><span style="color: rgba(128, 0, 0, 1)">FaceLibraries\x86\ViewFace.dll</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 设置日志回调函数(用于日志打印)
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="writeLog"></param></span>
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> SetLogFunction(LogCallBack writeLog);
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 设置人脸模型的目录
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="path"></param></span>
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span> SetModelPath(<span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] path);
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 设置人脸模型的目录
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="path"></param></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span> SetModelPath(<span style="color: rgba(0, 0, 255, 1)">string</span> path) =><span style="color: rgba(0, 0, 0, 1)"> SetModelPath(Encoding.UTF8.GetBytes(path));
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 释放使用的资源
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> ViewDispose();
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 获取人脸模型的目录
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="path"></param></span>
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> GetModelPathEx(<span style="color: rgba(0, 0, 255, 1)">ref</span> <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> path);
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 获取人脸模型的目录
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">string</span> GetModelPath() { <span style="color: rgba(0, 0, 255, 1)">string</span> path = <span style="color: rgba(0, 0, 255, 1)">string</span>.Empty; GetModelPathEx(<span style="color: rgba(0, 0, 255, 1)">ref</span> path); <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> path; }
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 人脸检测器检测到的人脸数量
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="imgData"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="width"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="height"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="channels"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="faceSize"></span><span style="color: rgba(0, 128, 0, 1)">最小人脸是人脸检测器常用的一个概念,默认值为20,单位像素。
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><para></span><span style="color: rgba(0, 128, 0, 1)">最小人脸和检测器性能息息相关。主要方面是速度,使用建议上,我们建议在应用范围内,这个值设定的越大越好。SeetaFace采用的是BindingBox Regresion的方式训练的检测器。如果最小人脸参数设置为80的话,从检测能力上,可以将原图缩小的原来的1/4,这样从计算复杂度上,能够比最小人脸设置为20时,提速到16倍。</span><span style="color: rgba(128, 128, 128, 1)"></para></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="threshold"></span><span style="color: rgba(0, 128, 0, 1)">检测器阈值默认值是0.9,合理范围为。这个值一般不进行调整,除了用来处理一些极端情况。这个值设置的越小,漏检的概率越小,同时误检的概率会提高</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="maxWidth"></span><span style="color: rgba(0, 128, 0, 1)">可检测的图像最大宽度。默认值2000。</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="maxHeight"></span><span style="color: rgba(0, 128, 0, 1)">可检测的图像最大高度。默认值2000。</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="type"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">int</span> DetectorSize(<span style="color: rgba(0, 0, 255, 1)">byte</span>[] imgData, <span style="color: rgba(0, 0, 255, 1)">int</span> width, <span style="color: rgba(0, 0, 255, 1)">int</span> height, <span style="color: rgba(0, 0, 255, 1)">int</span> channels, <span style="color: rgba(0, 0, 255, 1)">double</span> faceSize = <span style="color: rgba(128, 0, 128, 1)">20</span>, <span style="color: rgba(0, 0, 255, 1)">double</span> threshold = <span style="color: rgba(128, 0, 128, 1)">0.9</span>, <span style="color: rgba(0, 0, 255, 1)">double</span> maxWidth = <span style="color: rgba(128, 0, 128, 1)">2000</span>, <span style="color: rgba(0, 0, 255, 1)">double</span> maxHeight = <span style="color: rgba(128, 0, 128, 1)">2000</span>, <span style="color: rgba(0, 0, 255, 1)">int</span> type = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 人脸检测器
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><para></span><span style="color: rgba(0, 128, 0, 1)">调用此方法前必须先调用 </span><span style="color: rgba(128, 128, 128, 1)"><see cref="DetectorSize(byte[], int, int, int, double, double, double, double, int)"/></para></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="score"></span><span style="color: rgba(0, 128, 0, 1)">人脸置信度集合</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="x"></span><span style="color: rgba(0, 128, 0, 1)">人脸位置集合</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="y"></span><span style="color: rgba(0, 128, 0, 1)">人脸位置集合</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="width"></span><span style="color: rgba(0, 128, 0, 1)">人脸大小集合</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="height"></span><span style="color: rgba(0, 128, 0, 1)">人脸大小集合</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> Detector(<span style="color: rgba(0, 0, 255, 1)">float</span>[] score, <span style="color: rgba(0, 0, 255, 1)">int</span>[] x, <span style="color: rgba(0, 0, 255, 1)">int</span>[] y, <span style="color: rgba(0, 0, 255, 1)">int</span>[] width, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">[] height);
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 人脸关键点数量
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">int</span> FaceMarkSize(<span style="color: rgba(0, 0, 255, 1)">int</span> type = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 人脸关键点
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="imgData"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="width"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="height"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="channels"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="x"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="y"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="fWidth"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="fHeight"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="pointX"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="pointY"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="type"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> FaceMark(<span style="color: rgba(0, 0, 255, 1)">byte</span>[] imgData, <span style="color: rgba(0, 0, 255, 1)">int</span> width, <span style="color: rgba(0, 0, 255, 1)">int</span> height, <span style="color: rgba(0, 0, 255, 1)">int</span> channels, <span style="color: rgba(0, 0, 255, 1)">int</span> x, <span style="color: rgba(0, 0, 255, 1)">int</span> y, <span style="color: rgba(0, 0, 255, 1)">int</span> fWidth, <span style="color: rgba(0, 0, 255, 1)">int</span> fHeight, <span style="color: rgba(0, 0, 255, 1)">double</span>[] pointX, <span style="color: rgba(0, 0, 255, 1)">double</span>[] pointY, <span style="color: rgba(0, 0, 255, 1)">int</span> type = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 提取特征值
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="imgData"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="width"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="height"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="channels"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="points"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="features"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="type"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> Extract(<span style="color: rgba(0, 0, 255, 1)">byte</span>[] imgData, <span style="color: rgba(0, 0, 255, 1)">int</span> width, <span style="color: rgba(0, 0, 255, 1)">int</span> height, <span style="color: rgba(0, 0, 255, 1)">int</span> channels, FaceMarkPoint[] points, <span style="color: rgba(0, 0, 255, 1)">float</span>[] features, <span style="color: rgba(0, 0, 255, 1)">int</span> type = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 特征值大小
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">int</span> ExtractSize(<span style="color: rgba(0, 0, 255, 1)">int</span> type = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 计算相似度
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="leftFeatures"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="rightFeatures"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="type"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">float</span> Similarity(<span style="color: rgba(0, 0, 255, 1)">float</span>[] leftFeatures, <span style="color: rgba(0, 0, 255, 1)">float</span>[] rightFeatures, <span style="color: rgba(0, 0, 255, 1)">int</span> type = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
}
}</span></pre>
</div>
<span class="cnblogs_code_collapse">C# 导入层</span></div>
<p>3.采用 C# 的面向对象的封装</p>
<p>因为C#的项目默认都是 AnyCPU,所以为了简化调用,在这一层封装的时候增加了架构判断,当在你的项目中引用的时候,不用做任何修改。</p>
<p>且因为C++的C#导入方法在和原生的C#写法略有差异,且数据的转换和传递比较麻烦,所以类库中对外隐藏了 C# 导入层。并使用大家都更熟悉的C#的面向对象的方式进行进一步的封装和简化。</p>
<div class="cnblogs_code"><img id="code_img_closed_8a137109-953a-4572-a8e4-98b021abbbed" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_8a137109-953a-4572-a8e4-98b021abbbed" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_8a137109-953a-4572-a8e4-98b021abbbed" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(0, 128, 128, 1)">2</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 人脸识别类
</span><span style="color: rgba(0, 128, 128, 1)">3</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 128, 128, 1)">4</span> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> ViewFace
</span><span style="color: rgba(0, 128, 128, 1)">5</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">6</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> Platform64 { <span style="color: rgba(0, 0, 255, 1)">get</span>; <span style="color: rgba(0, 0, 255, 1)">set</span>; } = <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">7</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> <para>需要模型:<see langword=""/></para>
</span><span style="color: rgba(0, 128, 128, 1)">8</span>
<span style="color: rgba(0, 128, 128, 1)">9</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ctor</span>
<span style="color: rgba(0, 128, 128, 1)"> 10</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(0, 128, 128, 1)"> 11</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 使用默认的模型目录初始化人脸识别类
</span><span style="color: rgba(0, 128, 128, 1)"> 12</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 128, 128, 1)"> 13</span> <span style="color: rgba(0, 0, 255, 1)">public</span> ViewFace() : <span style="color: rgba(0, 0, 255, 1)">this</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">./model/</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">) { }
</span><span style="color: rgba(0, 128, 128, 1)"> 14</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(0, 128, 128, 1)"> 15</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 使用指定的模型目录初始化人脸识别类
</span><span style="color: rgba(0, 128, 128, 1)"> 16</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 128, 128, 1)"> 17</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="modelPath"></span><span style="color: rgba(0, 128, 0, 1)">模型目录</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(0, 128, 128, 1)"> 18</span> <span style="color: rgba(0, 0, 255, 1)">public</span> ViewFace(<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> modelPath)
</span><span style="color: rgba(0, 128, 128, 1)"> 19</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 20</span> Platform64 = IntPtr.Size == <span style="color: rgba(128, 0, 128, 1)">8</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 21</span> <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (Platform64)
</span><span style="color: rgba(0, 128, 128, 1)"> 22</span> <span style="color: rgba(0, 0, 0, 1)"> { ViewFacePlus64.SetModelPath(modelPath); }
</span><span style="color: rgba(0, 128, 128, 1)"> 23</span> <span style="color: rgba(0, 0, 255, 1)">else</span>
<span style="color: rgba(0, 128, 128, 1)"> 24</span> <span style="color: rgba(0, 0, 0, 1)"> { ViewFacePlus32.SetModelPath(modelPath); }
</span><span style="color: rgba(0, 128, 128, 1)"> 25</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)"> 26</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(0, 128, 128, 1)"> 27</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 使用指定的日志回调函数初始化人脸识别类
</span><span style="color: rgba(0, 128, 128, 1)"> 28</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 128, 128, 1)"> 29</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="action"></span><span style="color: rgba(0, 128, 0, 1)">日志回调函数</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(0, 128, 128, 1)"> 30</span> <span style="color: rgba(0, 0, 255, 1)">public</span> ViewFace(LogCallBack action) : <span style="color: rgba(0, 0, 255, 1)">this</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">./model/</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, action) { }
</span><span style="color: rgba(0, 128, 128, 1)"> 31</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(0, 128, 128, 1)"> 32</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 使用指定的模型目录、日志回调函数初始化人脸识别类
</span><span style="color: rgba(0, 128, 128, 1)"> 33</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 128, 128, 1)"> 34</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="modelPath"></span><span style="color: rgba(0, 128, 0, 1)">模型目录</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(0, 128, 128, 1)"> 35</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="action"></span><span style="color: rgba(0, 128, 0, 1)">日志回调函数</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(0, 128, 128, 1)"> 36</span> <span style="color: rgba(0, 0, 255, 1)">public</span> ViewFace(<span style="color: rgba(0, 0, 255, 1)">string</span> modelPath, LogCallBack action) : <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">(modelPath)
</span><span style="color: rgba(0, 128, 128, 1)"> 37</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 38</span> <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (Platform64)
</span><span style="color: rgba(0, 128, 128, 1)"> 39</span> <span style="color: rgba(0, 0, 0, 1)"> { ViewFacePlus64.SetLogFunction(action); }
</span><span style="color: rgba(0, 128, 128, 1)"> 40</span> <span style="color: rgba(0, 0, 255, 1)">else</span>
<span style="color: rgba(0, 128, 128, 1)"> 41</span> <span style="color: rgba(0, 0, 0, 1)"> { ViewFacePlus32.SetLogFunction(action); }
</span><span style="color: rgba(0, 128, 128, 1)"> 42</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)"> 43</span>
<span style="color: rgba(0, 128, 128, 1)"> 44</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> public property</span>
<span style="color: rgba(0, 128, 128, 1)"> 45</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(0, 128, 128, 1)"> 46</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 获取或设置模型路径
</span><span style="color: rgba(0, 128, 128, 1)"> 47</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 128, 128, 1)"> 48</span> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> ModelPath
</span><span style="color: rgba(0, 128, 128, 1)"> 49</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 50</span> <span style="color: rgba(0, 0, 255, 1)">get</span>
<span style="color: rgba(0, 128, 128, 1)"> 51</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 52</span> <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (Platform64)
</span><span style="color: rgba(0, 128, 128, 1)"> 53</span> { <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> ViewFacePlus64.GetModelPath(); }
</span><span style="color: rgba(0, 128, 128, 1)"> 54</span> <span style="color: rgba(0, 0, 255, 1)">else</span>
<span style="color: rgba(0, 128, 128, 1)"> 55</span> { <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> ViewFacePlus32.GetModelPath(); }
</span><span style="color: rgba(0, 128, 128, 1)"> 56</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)"> 57</span> <span style="color: rgba(0, 0, 255, 1)">set</span>
<span style="color: rgba(0, 128, 128, 1)"> 58</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 59</span> <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (Platform64)
</span><span style="color: rgba(0, 128, 128, 1)"> 60</span> <span style="color: rgba(0, 0, 0, 1)"> { ViewFacePlus64.SetModelPath(value); }
</span><span style="color: rgba(0, 128, 128, 1)"> 61</span> <span style="color: rgba(0, 0, 255, 1)">else</span>
<span style="color: rgba(0, 128, 128, 1)"> 62</span> <span style="color: rgba(0, 0, 0, 1)"> { ViewFacePlus32.SetModelPath(value); }
</span><span style="color: rgba(0, 128, 128, 1)"> 63</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)"> 64</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)"> 65</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(0, 128, 128, 1)"> 66</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 获取或设置人脸类型
</span><span style="color: rgba(0, 128, 128, 1)"> 67</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><para></span>
<span style="color: rgba(0, 128, 128, 1)"> 68</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><listheader></span><span style="color: rgba(0, 128, 0, 1)">此属性可影响到以下方法:</span><span style="color: rgba(128, 128, 128, 1)"></listheader><br /></span>
<span style="color: rgba(0, 128, 128, 1)"> 69</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> • </span><span style="color: rgba(128, 128, 128, 1)"><c><see cref="FaceDetector(Bitmap)"/></c><br /></span>
<span style="color: rgba(0, 128, 128, 1)"> 70</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> • </span><span style="color: rgba(128, 128, 128, 1)"><c><see cref="Extract(Bitmap, FaceMarkPoint[])"/></c><br /></span>
<span style="color: rgba(0, 128, 128, 1)"> 71</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> • </span><span style="color: rgba(128, 128, 128, 1)"><c><see cref="Similarity(float[], float[])"/></c><br /></span>
<span style="color: rgba(0, 128, 128, 1)"> 72</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></para></span>
<span style="color: rgba(0, 128, 128, 1)"> 73</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 128, 128, 1)"> 74</span> <span style="color: rgba(0, 0, 255, 1)">public</span> FaceType FaceType { <span style="color: rgba(0, 0, 255, 1)">get</span>; <span style="color: rgba(0, 0, 255, 1)">set</span>; } =<span style="color: rgba(0, 0, 0, 1)"> FaceType.Light;
</span><span style="color: rgba(0, 128, 128, 1)"> 75</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(0, 128, 128, 1)"> 76</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 获取或设置人脸关键点类型
</span><span style="color: rgba(0, 128, 128, 1)"> 77</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><para></span>
<span style="color: rgba(0, 128, 128, 1)"> 78</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><listheader></span><span style="color: rgba(0, 128, 0, 1)">此属性可影响到以下方法:</span><span style="color: rgba(128, 128, 128, 1)"></listheader><br /></span>
<span style="color: rgba(0, 128, 128, 1)"> 79</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> • </span><span style="color: rgba(128, 128, 128, 1)"><c><see cref="FaceMark(Bitmap, FaceInfo)"/></c><br /></span>
<span style="color: rgba(0, 128, 128, 1)"> 80</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></para></span>
<span style="color: rgba(0, 128, 128, 1)"> 81</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 128, 128, 1)"> 82</span> <span style="color: rgba(0, 0, 255, 1)">public</span> MarkType MarkType { <span style="color: rgba(0, 0, 255, 1)">get</span>; <span style="color: rgba(0, 0, 255, 1)">set</span>; } =<span style="color: rgba(0, 0, 0, 1)"> MarkType.Light;
</span><span style="color: rgba(0, 128, 128, 1)"> 83</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(0, 128, 128, 1)"> 84</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 获取或设置人脸检测器设置
</span><span style="color: rgba(0, 128, 128, 1)"> 85</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 128, 128, 1)"> 86</span> <span style="color: rgba(0, 0, 255, 1)">public</span> DetectorSetting DetectorSetting { <span style="color: rgba(0, 0, 255, 1)">get</span>; <span style="color: rgba(0, 0, 255, 1)">set</span>; } = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> DetectorSetting();
</span><span style="color: rgba(0, 128, 128, 1)"> 87</span>
<span style="color: rgba(0, 128, 128, 1)"> 88</span>
<span style="color: rgba(0, 128, 128, 1)"> 89</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> public method</span>
<span style="color: rgba(0, 128, 128, 1)"> 90</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(0, 128, 128, 1)"> 91</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 识别 </span><span style="color: rgba(128, 128, 128, 1)"><paramref name="bitmap"/></span><span style="color: rgba(0, 128, 0, 1)"> 中的人脸,并返回人脸的信息。
</span><span style="color: rgba(0, 128, 128, 1)"> 92</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><para></span>
<span style="color: rgba(0, 128, 128, 1)"> 93</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 当 </span><span style="color: rgba(128, 128, 128, 1)"><c><see cref="FaceType"/></span> <span style="color: rgba(128, 128, 128, 1)"><see langword="="/></span> <span style="color: rgba(128, 128, 128, 1)"><see cref="FaceType.Normal"/></span> <span style="color: rgba(128, 128, 128, 1)"><see langword="||"/></span> <span style="color: rgba(128, 128, 128, 1)"><see cref="FaceType.Light"/></c></span><span style="color: rgba(0, 128, 0, 1)"> 时, 需要模型:</span><span style="color: rgba(128, 128, 128, 1)"><see langword="face_detector.csta"/><br/></span>
<span style="color: rgba(0, 128, 128, 1)"> 94</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 当 </span><span style="color: rgba(128, 128, 128, 1)"><c><see cref="FaceType"/></span> <span style="color: rgba(128, 128, 128, 1)"><see langword="="/></span> <span style="color: rgba(128, 128, 128, 1)"><see cref="FaceType.Mask"/></c></span><span style="color: rgba(0, 128, 0, 1)"> 时, 需要模型:</span><span style="color: rgba(128, 128, 128, 1)"><see langword="mask_detector.csta"/><br/></span>
<span style="color: rgba(0, 128, 128, 1)"> 95</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></para></span>
<span style="color: rgba(0, 128, 128, 1)"> 96</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 128, 128, 1)"> 97</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="bitmap"></span><span style="color: rgba(0, 128, 0, 1)">包含人脸的图片</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(0, 128, 128, 1)"> 98</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 128, 128, 1)"> 99</span> <span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> FaceInfo[] FaceDetector(Bitmap bitmap)
</span><span style="color: rgba(0, 128, 128, 1)">100</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">101</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[] bgr = ImageSet.Get24BGRFromBitmap(bitmap, <span style="color: rgba(0, 0, 255, 1)">out</span> <span style="color: rgba(0, 0, 255, 1)">int</span> width, <span style="color: rgba(0, 0, 255, 1)">out</span> <span style="color: rgba(0, 0, 255, 1)">int</span> height, <span style="color: rgba(0, 0, 255, 1)">out</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> channels);
</span><span style="color: rgba(0, 128, 128, 1)">102</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> size;
</span><span style="color: rgba(0, 128, 128, 1)">103</span> <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (Platform64)
</span><span style="color: rgba(0, 128, 128, 1)">104</span> { size = ViewFacePlus64.DetectorSize(bgr, width, height, channels, DetectorSetting.FaceSize, DetectorSetting.Threshold, DetectorSetting.MaxWidth, DetectorSetting.MaxHeight, (<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">)FaceType); }
</span><span style="color: rgba(0, 128, 128, 1)">105</span> <span style="color: rgba(0, 0, 255, 1)">else</span>
<span style="color: rgba(0, 128, 128, 1)">106</span> { size = ViewFacePlus32.DetectorSize(bgr, width, height, channels, DetectorSetting.FaceSize, DetectorSetting.Threshold, DetectorSetting.MaxWidth, DetectorSetting.MaxHeight, (<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">)FaceType); }
</span><span style="color: rgba(0, 128, 128, 1)">107</span> <span style="color: rgba(0, 0, 255, 1)">float</span>[] _socre = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">float</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">108</span> <span style="color: rgba(0, 0, 255, 1)">int</span>[] _x = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">109</span> <span style="color: rgba(0, 0, 255, 1)">int</span>[] _y = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">110</span> <span style="color: rgba(0, 0, 255, 1)">int</span>[] _width = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">111</span> <span style="color: rgba(0, 0, 255, 1)">int</span>[] _height = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">112</span> <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (Platform64)
</span><span style="color: rgba(0, 128, 128, 1)">113</span> { _ =<span style="color: rgba(0, 0, 0, 1)"> ViewFacePlus64.Detector(_socre, _x, _y, _width, _height); }
</span><span style="color: rgba(0, 128, 128, 1)">114</span> <span style="color: rgba(0, 0, 255, 1)">else</span>
<span style="color: rgba(0, 128, 128, 1)">115</span> { _ =<span style="color: rgba(0, 0, 0, 1)"> ViewFacePlus32.Detector(_socre, _x, _y, _width, _height); }
</span><span style="color: rgba(0, 128, 128, 1)">116</span> List<FaceInfo> infos = <span style="color: rgba(0, 0, 255, 1)">new</span> List<FaceInfo><span style="color: rgba(0, 0, 0, 1)">();
</span><span style="color: rgba(0, 128, 128, 1)">117</span> <span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = <span style="color: rgba(128, 0, 128, 1)">0</span>; i < size; i++<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">118</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">119</span> infos.Add(<span style="color: rgba(0, 0, 255, 1)">new</span> FaceInfo() { Score = _socre, Location = <span style="color: rgba(0, 0, 255, 1)">new</span> FaceRect() { X = _x, Y = _y, Width = _width, Height =<span style="color: rgba(0, 0, 0, 1)"> _height } });
</span><span style="color: rgba(0, 128, 128, 1)">120</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">121</span> <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> infos.ToArray();
</span><span style="color: rgba(0, 128, 128, 1)">122</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">123</span>
<span style="color: rgba(0, 128, 128, 1)">124</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(0, 128, 128, 1)">125</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 识别 </span><span style="color: rgba(128, 128, 128, 1)"><paramref name="bitmap"/></span><span style="color: rgba(0, 128, 0, 1)"> 中指定的人脸信息 </span><span style="color: rgba(128, 128, 128, 1)"><paramref name="info"/></span><span style="color: rgba(0, 128, 0, 1)"> 的关键点坐标。
</span><span style="color: rgba(0, 128, 128, 1)">126</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><para></span>
<span style="color: rgba(0, 128, 128, 1)">127</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 当 </span><span style="color: rgba(128, 128, 128, 1)"><see cref="FaceType"/></span> <span style="color: rgba(128, 128, 128, 1)"><see langword="="/></span> <span style="color: rgba(128, 128, 128, 1)"><see cref="FaceType.Normal"/></span><span style="color: rgba(0, 128, 0, 1)"> 时, 需要模型:</span><span style="color: rgba(128, 128, 128, 1)"><see langword="face_landmarker_pts68.csta"/><br/></span>
<span style="color: rgba(0, 128, 128, 1)">128</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 当 </span><span style="color: rgba(128, 128, 128, 1)"><see cref="FaceType"/></span> <span style="color: rgba(128, 128, 128, 1)"><see langword="="/></span> <span style="color: rgba(128, 128, 128, 1)"><see cref="FaceType.Mask"/></span><span style="color: rgba(0, 128, 0, 1)"> 时, 需要模型:</span><span style="color: rgba(128, 128, 128, 1)"><see langword="face_landmarker_mask_pts5.csta"/><br/></span>
<span style="color: rgba(0, 128, 128, 1)">129</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 当 </span><span style="color: rgba(128, 128, 128, 1)"><see cref="FaceType"/></span> <span style="color: rgba(128, 128, 128, 1)"><see langword="="/></span> <span style="color: rgba(128, 128, 128, 1)"><see cref="FaceType.Light"/></span><span style="color: rgba(0, 128, 0, 1)"> 时, 需要模型:</span><span style="color: rgba(128, 128, 128, 1)"><see langword="face_landmarker_pts5.csta"/><br/></span>
<span style="color: rgba(0, 128, 128, 1)">130</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></para></span>
<span style="color: rgba(0, 128, 128, 1)">131</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 128, 128, 1)">132</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="bitmap"></span><span style="color: rgba(0, 128, 0, 1)">包含人脸的图片</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(0, 128, 128, 1)">133</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="info"></span><span style="color: rgba(0, 128, 0, 1)">指定的人脸信息</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(0, 128, 128, 1)">134</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 128, 128, 1)">135</span> <span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> FaceMarkPoint[] FaceMark(Bitmap bitmap, FaceInfo info)
</span><span style="color: rgba(0, 128, 128, 1)">136</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">137</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[] bgr = ImageSet.Get24BGRFromBitmap(bitmap, <span style="color: rgba(0, 0, 255, 1)">out</span> <span style="color: rgba(0, 0, 255, 1)">int</span> width, <span style="color: rgba(0, 0, 255, 1)">out</span> <span style="color: rgba(0, 0, 255, 1)">int</span> height, <span style="color: rgba(0, 0, 255, 1)">out</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> channels);
</span><span style="color: rgba(0, 128, 128, 1)">138</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> size;
</span><span style="color: rgba(0, 128, 128, 1)">139</span> <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (Platform64)
</span><span style="color: rgba(0, 128, 128, 1)">140</span> { size = ViewFacePlus64.FaceMarkSize((<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">)MarkType); }
</span><span style="color: rgba(0, 128, 128, 1)">141</span> <span style="color: rgba(0, 0, 255, 1)">else</span>
<span style="color: rgba(0, 128, 128, 1)">142</span> { size = ViewFacePlus32.FaceMarkSize((<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">)MarkType); }
</span><span style="color: rgba(0, 128, 128, 1)">143</span> <span style="color: rgba(0, 0, 255, 1)">double</span>[] _pointX = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">double</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">144</span> <span style="color: rgba(0, 0, 255, 1)">double</span>[] _pointY = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">double</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">145</span> <span style="color: rgba(0, 0, 255, 1)">bool</span><span style="color: rgba(0, 0, 0, 1)"> val;
</span><span style="color: rgba(0, 128, 128, 1)">146</span> <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (Platform64)
</span><span style="color: rgba(0, 128, 128, 1)">147</span> { val = ViewFacePlus64.FaceMark(bgr, width, height, channels, info.Location.X, info.Location.Y, info.Location.Width, info.Location.Height, _pointX, _pointY, (<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">)MarkType); }
</span><span style="color: rgba(0, 128, 128, 1)">148</span> <span style="color: rgba(0, 0, 255, 1)">else</span>
<span style="color: rgba(0, 128, 128, 1)">149</span> { val = ViewFacePlus32.FaceMark(bgr, width, height, channels, info.Location.X, info.Location.Y, info.Location.Width, info.Location.Height, _pointX, _pointY, (<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">)MarkType); }
</span><span style="color: rgba(0, 128, 128, 1)">150</span> <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (val)
</span><span style="color: rgba(0, 128, 128, 1)">151</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">152</span> List<FaceMarkPoint> points = <span style="color: rgba(0, 0, 255, 1)">new</span> List<FaceMarkPoint><span style="color: rgba(0, 0, 0, 1)">();
</span><span style="color: rgba(0, 128, 128, 1)">153</span> <span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = <span style="color: rgba(128, 0, 128, 1)">0</span>; i < size; i++<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">154</span> { points.Add(<span style="color: rgba(0, 0, 255, 1)">new</span> FaceMarkPoint() { X = _pointX, Y =<span style="color: rgba(0, 0, 0, 1)"> _pointY }); }
</span><span style="color: rgba(0, 128, 128, 1)">155</span> <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> points.ToArray();
</span><span style="color: rgba(0, 128, 128, 1)">156</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">157</span> <span style="color: rgba(0, 0, 255, 1)">else</span>
<span style="color: rgba(0, 128, 128, 1)">158</span> { <span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span> Exception(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">人脸关键点获取失败</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">); }
</span><span style="color: rgba(0, 128, 128, 1)">159</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">160</span>
<span style="color: rgba(0, 128, 128, 1)">161</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(0, 128, 128, 1)">162</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 提取人脸特征值。
</span><span style="color: rgba(0, 128, 128, 1)">163</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><para></span>
<span style="color: rgba(0, 128, 128, 1)">164</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 当 </span><span style="color: rgba(128, 128, 128, 1)"><see cref="FaceType"/></span> <span style="color: rgba(128, 128, 128, 1)"><see langword="="/></span> <span style="color: rgba(128, 128, 128, 1)"><see cref="FaceType.Normal"/></span><span style="color: rgba(0, 128, 0, 1)"> 时, 需要模型:</span><span style="color: rgba(128, 128, 128, 1)"><see langword="face_recognizer.csta"/><br/></span>
<span style="color: rgba(0, 128, 128, 1)">165</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 当 </span><span style="color: rgba(128, 128, 128, 1)"><see cref="FaceType"/></span> <span style="color: rgba(128, 128, 128, 1)"><see langword="="/></span> <span style="color: rgba(128, 128, 128, 1)"><see cref="FaceType.Mask"/></span><span style="color: rgba(0, 128, 0, 1)"> 时, 需要模型:</span><span style="color: rgba(128, 128, 128, 1)"><see langword="face_recognizer_mask.csta"/><br/></span>
<span style="color: rgba(0, 128, 128, 1)">166</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 当 </span><span style="color: rgba(128, 128, 128, 1)"><see cref="FaceType"/></span> <span style="color: rgba(128, 128, 128, 1)"><see langword="="/></span> <span style="color: rgba(128, 128, 128, 1)"><see cref="FaceType.Light"/></span><span style="color: rgba(0, 128, 0, 1)"> 时, 需要模型:</span><span style="color: rgba(128, 128, 128, 1)"><see langword="face_recognizer_light.csta"/><br/></span>
<span style="color: rgba(0, 128, 128, 1)">167</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></para></span>
<span style="color: rgba(0, 128, 128, 1)">168</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 128, 128, 1)">169</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="bitmap"></param></span>
<span style="color: rgba(0, 128, 128, 1)">170</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="points"></param></span>
<span style="color: rgba(0, 128, 128, 1)">171</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 128, 128, 1)">172</span> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">float</span><span style="color: rgba(0, 0, 0, 1)">[] Extract(Bitmap bitmap, FaceMarkPoint[] points)
</span><span style="color: rgba(0, 128, 128, 1)">173</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">174</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[] bgr = ImageSet.Get24BGRFromBitmap(bitmap, <span style="color: rgba(0, 0, 255, 1)">out</span> <span style="color: rgba(0, 0, 255, 1)">int</span> width, <span style="color: rgba(0, 0, 255, 1)">out</span> <span style="color: rgba(0, 0, 255, 1)">int</span> height, <span style="color: rgba(0, 0, 255, 1)">out</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> channels);
</span><span style="color: rgba(0, 128, 128, 1)">175</span> <span style="color: rgba(0, 0, 255, 1)">float</span><span style="color: rgba(0, 0, 0, 1)">[] features;
</span><span style="color: rgba(0, 128, 128, 1)">176</span> <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (Platform64)
</span><span style="color: rgba(0, 128, 128, 1)">177</span> { features = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">float</span>; }
</span><span style="color: rgba(0, 128, 128, 1)">178</span> <span style="color: rgba(0, 0, 255, 1)">else</span>
<span style="color: rgba(0, 128, 128, 1)">179</span> { features = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">float</span>; }
</span><span style="color: rgba(0, 128, 128, 1)">180</span>
<span style="color: rgba(0, 128, 128, 1)">181</span> <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (Platform64)
</span><span style="color: rgba(0, 128, 128, 1)">182</span> { ViewFacePlus64.Extract(bgr, width, height, channels, points, features, (<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">)FaceType); }
</span><span style="color: rgba(0, 128, 128, 1)">183</span> <span style="color: rgba(0, 0, 255, 1)">else</span>
<span style="color: rgba(0, 128, 128, 1)">184</span> { ViewFacePlus32.Extract(bgr, width, height, channels, points, features, (<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">)FaceType); }
</span><span style="color: rgba(0, 128, 128, 1)">185</span> <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> features;
</span><span style="color: rgba(0, 128, 128, 1)">186</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">187</span>
<span style="color: rgba(0, 128, 128, 1)">188</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(0, 128, 128, 1)">189</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 计算特征值相似度。
</span><span style="color: rgba(0, 128, 128, 1)">190</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><para></span><span style="color: rgba(0, 128, 0, 1)">只能计算相同 </span><span style="color: rgba(128, 128, 128, 1)"><see cref="FaceType"/></span><span style="color: rgba(0, 128, 0, 1)"> 计算出的特征值</span><span style="color: rgba(128, 128, 128, 1)"></para></span>
<span style="color: rgba(0, 128, 128, 1)">191</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><para></span>
<span style="color: rgba(0, 128, 128, 1)">192</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 当 </span><span style="color: rgba(128, 128, 128, 1)"><see cref="FaceType"/></span> <span style="color: rgba(128, 128, 128, 1)"><see langword="="/></span> <span style="color: rgba(128, 128, 128, 1)"><see cref="FaceType.Normal"/></span><span style="color: rgba(0, 128, 0, 1)"> 时, 需要模型:</span><span style="color: rgba(128, 128, 128, 1)"><see langword="face_recognizer.csta"/><br/></span>
<span style="color: rgba(0, 128, 128, 1)">193</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 当 </span><span style="color: rgba(128, 128, 128, 1)"><see cref="FaceType"/></span> <span style="color: rgba(128, 128, 128, 1)"><see langword="="/></span> <span style="color: rgba(128, 128, 128, 1)"><see cref="FaceType.Mask"/></span><span style="color: rgba(0, 128, 0, 1)"> 时, 需要模型:</span><span style="color: rgba(128, 128, 128, 1)"><see langword="face_recognizer_mask.csta"/><br/></span>
<span style="color: rgba(0, 128, 128, 1)">194</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 当 </span><span style="color: rgba(128, 128, 128, 1)"><see cref="FaceType"/></span> <span style="color: rgba(128, 128, 128, 1)"><see langword="="/></span> <span style="color: rgba(128, 128, 128, 1)"><see cref="FaceType.Light"/></span><span style="color: rgba(0, 128, 0, 1)"> 时, 需要模型:</span><span style="color: rgba(128, 128, 128, 1)"><see langword="face_recognizer_light.csta"/><br/></span>
<span style="color: rgba(0, 128, 128, 1)">195</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></para></span>
<span style="color: rgba(0, 128, 128, 1)">196</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 128, 128, 1)">197</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><exception cref="ArgumentException"/></span>
<span style="color: rgba(0, 128, 128, 1)">198</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><exception cref="ArgumentNullException"/></span>
<span style="color: rgba(0, 128, 128, 1)">199</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="leftFeatures"></param></span>
<span style="color: rgba(0, 128, 128, 1)">200</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="rightFeatures"></param></span>
<span style="color: rgba(0, 128, 128, 1)">201</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 128, 128, 1)">202</span> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">float</span> Similarity(<span style="color: rgba(0, 0, 255, 1)">float</span>[] leftFeatures, <span style="color: rgba(0, 0, 255, 1)">float</span><span style="color: rgba(0, 0, 0, 1)">[] rightFeatures)
</span><span style="color: rgba(0, 128, 128, 1)">203</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">204</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (leftFeatures.Length == <span style="color: rgba(128, 0, 128, 1)">0</span> || rightFeatures.Length == <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">205</span> <span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span> ArgumentNullException(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">参数不能为空</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, nameof(leftFeatures));
</span><span style="color: rgba(0, 128, 128, 1)">206</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (leftFeatures.Length !=<span style="color: rgba(0, 0, 0, 1)"> rightFeatures.Length)
</span><span style="color: rgba(0, 128, 128, 1)">207</span> <span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span> ArgumentException(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">两个参数长度不一致</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">208</span>
<span style="color: rgba(0, 128, 128, 1)">209</span>
<span style="color: rgba(0, 128, 128, 1)">210</span> <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (Platform64)
</span><span style="color: rgba(0, 128, 128, 1)">211</span> { <span style="color: rgba(0, 0, 255, 1)">return</span> ViewFacePlus64.Similarity(leftFeatures, rightFeatures, (<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">)FaceType); }
</span><span style="color: rgba(0, 128, 128, 1)">212</span> <span style="color: rgba(0, 0, 255, 1)">else</span>
<span style="color: rgba(0, 128, 128, 1)">213</span> { <span style="color: rgba(0, 0, 255, 1)">return</span> ViewFacePlus32.Similarity(leftFeatures, rightFeatures, (<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">)FaceType); }
</span><span style="color: rgba(0, 128, 128, 1)">214</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">215</span>
<span style="color: rgba(0, 128, 128, 1)">216</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(0, 128, 128, 1)">217</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 判断相似度是否为同一个人。
</span><span style="color: rgba(0, 128, 128, 1)">218</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 128, 128, 1)">219</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="similarity"></span><span style="color: rgba(0, 128, 0, 1)">相似度</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(0, 128, 128, 1)">220</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 128, 128, 1)">221</span> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> IsSelf(<span style="color: rgba(0, 0, 255, 1)">float</span> similarity) => similarity ><span style="color: rgba(0, 0, 0, 1)"> Face.Threshold;
</span><span style="color: rgba(0, 128, 128, 1)">222</span>
<span style="color: rgba(0, 128, 128, 1)">223</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(0, 128, 128, 1)">224</span> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 释放资源
</span><span style="color: rgba(0, 128, 128, 1)">225</span> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 128, 128, 1)">226</span> ~<span style="color: rgba(0, 0, 0, 1)">ViewFace()
</span><span style="color: rgba(0, 128, 128, 1)">227</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">228</span> <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (Platform64)
</span><span style="color: rgba(0, 128, 128, 1)">229</span> <span style="color: rgba(0, 0, 0, 1)"> { ViewFacePlus64.ViewDispose(); }
</span><span style="color: rgba(0, 128, 128, 1)">230</span> <span style="color: rgba(0, 0, 255, 1)">else</span>
<span style="color: rgba(0, 128, 128, 1)">231</span> <span style="color: rgba(0, 0, 0, 1)"> { ViewFacePlus32.ViewDispose(); }
</span><span style="color: rgba(0, 128, 128, 1)">232</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">233</span> }</pre>
</div>
<span class="cnblogs_code_collapse">C# 面向对象层</span></div>
<p> </p>
<h2><strong>五、也许…</strong></h2>
<ul>
<li><strong>此项目还未实现 SeetaFace6 中的许多特性,也许:</strong></li>
</ul>
<p> 想起 GitHub 密码,持续更新…<br> <span style="text-decoration: line-through">删除代码仓库跑路…</span></p>
<ul>
<li><strong>如果在使用过程中遇到问题,你也许可以:</strong></li>
</ul>
<p> 在 GitHub 报告Bug…<br> 向我 发送邮件</p><br><br>
来源:https://www.cnblogs.com/view12138/p/ViewFaceCore.html
頁:
[1]