C#开发学习人工智能的第一步

简介: C#开发学习人工智能的第一步前言作为一个软件开发者,我们除了要学会复制,黏贴,还要学会调用API和优秀的开源类库。也许,有人说C#做不了人工智能,如果你相信了,那只能说明你的思想还是狭隘的。做不了人工智能的不是C#这种语言,而是你,我这种普通的程序员。

C#开发学习人工智能的第一步
前言

作为一个软件开发者,我们除了要学会复制,黏贴,还要学会调用API和优秀的开源类库。

也许,有人说C#做不了人工智能,如果你相信了,那只能说明你的思想还是狭隘的。

做不了人工智能的不是C#这种语言,而是你,我这种普通的程序员。

做人工智能需要一定的学历背景,一定的数学基础和公司专项的资源供给;而这种机缘小之又小,你我既然是普通的程序员,就必然与此无缘。

但在人工智能如日中天的当下,接触深度学习是必然会发生的事情,所以我们要做的就是,学会调用相关的类库。

现在,让我们迈出C#学习人工智能的第一步,通过调用Affdex来锁定图片中人物的面部,然后将其截取出来。

准备工作

首先,我们需要先访问官网下载Affdex的Sdk。

在官网找中找到下载Affdex的Sdk的地方也是个挺困难的事。。。所以下载链接如下:

下载Affdex_Sdk网址

进入网页后,向下拉动滚动条,找到到下图所示位置,点击Download进行下载。

下载完成后得到Sdk,如下图:

下面,我们双击进行安装,不过安装SDK有一些限制,需要预先安装NET Framework4.0和C++ 2015。如果电脑里已经安装了,就不必担心了;如果安装的是C++2015-2017这类型的,则需要卸载了,重新安装C++2015的版本,否则Affdex的SDK将安装失败。

安装完成后,我们去安装目录找到Affdex.dll,affdex-native.dll,tensorflow.dll三个文件,如下图:

我们先将它们复制出来,等待使用。

简单的介绍一下,这三个类库中,Affdex.dll是可以被C#项目直接引用的,而另外两个文件是Affdex.dll的依赖文件;也就是说,affdex-native.dll,tensorflow.dll需要在生成时,输出到运行目录下。

有经验的朋友想必已经发现了,这里有个类库名叫tensorflow.dll,tensorflow是什么啊?稍微百度一下大家就会了解了,它是专门来做深度学习的。

也就是说Affdex是支持深度学习的。


现在我们来学习Affdex的使用。

首先我们新建一个WPF项目,然后引用Affdex.dll。

然后将项目的运行平台设置为64位,因为,这样处理图片的速度能快一点,如下图:

在Affdex中我们可以发现四个探头—VideoDetector,PhotoDetector,FrameDetector,CameraDetector。

在这里我们要处理的是图片,所以我们选择PhotoDetector,下面我们创建一个PhotoWindow.Xaml页面来使用PhotoDetector处理图片。

代码实现

首先,我们定义一个PhotoDetector的属性,用于处理图片。

然后我们在构造函数中对他进行实例化,代码如下:

1
2
3
4
5
6
7
8
9
10
private Affdex.PhotoDetector Detector { get; set; }
public PhotoWindow()
{

InitializeComponent();
uint maxNumFaces = 1;//最多识别图片中几张脸
Detector = new Affdex.PhotoDetector(maxNumFaces, Affdex.FaceDetectorMode.SMALL_FACES);           
Detector.setImageListener(this);
Detector.setProcessStatusListener(this);
Detector.start();

}
在上述代码中可以看到,除了初始化PhotoDetector,我们还做了一个图片监听设置setImageListener,那么图片监听是干什么的呢?

很简单,图片被PhotoDetector处理完,我们需要知道图片处理结果呀,而这个图片监听正是是用来返回图片处理结果的。

可以看到图片监听设置的入参是this,也就是说,需要把图片的处理结果返回给当前页面。

如果就这样写是会编译报错的,会提示setImageListener的入参错误。

我们查看setImageListener的入参,发现它的入参是一个ImageListener接口,即,setImageListener的入参是一个要实现了ImageListener接口的类。

到这里,我们就都明白了,现在我们让当前PhotoWindow.xaml窗体继承接口ImageListener,并实现接口ImageListener内的方法。

1
2
3
4
5
6
7
8

public partial class PhotoWindow : Window, Affdex.ImageListener

public void onImageCapture(Affdex.Frame frame)
{
}
public void onImageResults(Dictionary faces, Affdex.Frame frame)
{
}
如上述代码所示,在我们实现的接口onImageResults里有两个参数:faces、frame。

其中faces是最重要的,这里包含Affdex分析图片的结果。


现在,Affdex的配置代码已经写完了,我们可以把图片读取出来调用Affdex处理了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public PhotoWindow()
{

InitializeComponent();
uint maxNumFaces = 1;//最多识别图片中几张脸
Detector = new Affdex.PhotoDetector(maxNumFaces, Affdex.FaceDetectorMode.SMALL_FACES);  
Detector.setImageListener(this);
Detector.start();
 
byte[] bytes = FileHelper.FileToBytes(System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "timg.jpg"));
BitmapSource bitmapSource = ImageHelper.BytesToBitmapImage(bytes);
var w = bitmapSource.Width;
var h = bitmapSource.Height;
var stride = bitmapSource.Format.BitsPerPixel * (int)w / 8; //计算Stride 
byte[] byteList = new byte[(int)h * stride];
bitmapSource.CopyPixels(byteList, stride, 0);  
Affdex.Frame frame = new Affdex.Frame((int)w, (int)h, byteList, Affdex.Frame.COLOR_FORMAT.BGRA); 
Detector.process(frame);

}
如上述代码所示,我们在启动了Detector后,读取了一个人物图片,然后把人物图片的像素数组解析出来,生成一个Frame;这个Frame是Affdex的类,用于保存图像数据信息。

最后,我们把生成的Frame对象,扔给Detecotor的Process方法处理。

Detecotor处理完成后,会触发onImageResults方法。

在onImageResults方法里,入参faces包含了处理结果。

现在我们使用faces里的内容,来定位图片中人物面部的位置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void onImageResults(Dictionary faces, Affdex.Frame frame)
{

Face face = null;
if (faces != null && faces.Values != null && faces.Values.Count() > 0)
{
    face = faces.Values.First();//因为我们的Detector只识别了一个脸,所以这里最多只有一个数据
}
int top = (int)face.FeaturePoints.Min(r => r.X);
int left = (int)face.FeaturePoints.Min(r => r.Y);
int bottom = (int)face.FeaturePoints.Max(r => r.X);
int right = (int)face.FeaturePoints.Max(r => r.Y);
ImageHelper.cutPicture(System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "timg.jpg"),
 left, top, right , bottom - top);

}
如上述代码所示,我们在onImageResults里做了【最简单】人物面部坐标定位,并进行了剪切。

处理结果如下图所示:

结语

事实上,上面介绍的只是Affdex最基础调用,而且,这里并没有使用到深度学习的内容,只是简单的扫描和分析。

想要使用深度学习的内容还需要进一步学习该开源控件,不过,万事开头难,我们现在已经迈出了第一步。


到此C#开发学习人工智能的第一步就完成了。

代码已经传到Github上了,欢迎大家下载。

Github地址:https://github.com/kiba518/WpfAffdex


注:此文章为原创,任何形式的转载都请联系作者获得授权并注明出处!
若您觉得这篇文章还不错,请点击下方的【推荐】,非常感谢!

https://www.cnblogs.com/kiba/p/11416919.html

相关文章
|
10天前
|
机器学习/深度学习 人工智能 分布式计算
人工智能平台PAI产品使用合集之机器学习PAI的学习方法不知道如何解决
阿里云人工智能平台PAI是一个功能强大、易于使用的AI开发平台,旨在降低AI开发门槛,加速创新,助力企业和开发者高效构建、部署和管理人工智能应用。其中包含了一系列相互协同的产品与服务,共同构成一个完整的人工智能开发与应用生态系统。以下是对PAI产品使用合集的概述,涵盖数据处理、模型开发、训练加速、模型部署及管理等多个环节。
|
2天前
|
机器学习/深度学习 存储 人工智能
构建未来:AI在持续学习系统中的应用
【5月更文挑战第6天】 随着人工智能技术的飞速发展,AI在各个领域中的应用越来越广泛。本文将探讨AI在持续学习系统中的应用,以及如何通过这种技术提高教育质量和效率。我们将讨论AI如何帮助个性化学习,提供实时反馈,以及如何通过数据分析预测学生的学习进度。此外,我们还将探讨AI在教育中的潜在挑战和解决方案。
|
2天前
|
人工智能 文字识别 语音技术
学习资料大全​ | 一起来魔搭社区学AI吧!
魔搭社区特别推出研习社栏目,包含AI前沿技术解读、模型应用最佳实践、动手做AI应用(AIGC/Agent/RAG)等主题,持续更新,代码实战点击即运行
|
5天前
|
传感器 人工智能 自动驾驶
【AI 场景】如何开发用于自动驾驶的人工智能系统?
【5月更文挑战第3天】【AI 场景】如何开发用于自动驾驶的人工智能系统?
|
5天前
|
存储 人工智能 安全
【AI 初识】人工智能开发和部署的道德考虑是什么?
【5月更文挑战第3天】【AI 初识】人工智能开发和部署的道德考虑是什么?
|
5天前
|
机器学习/深度学习 人工智能
【AI 初识】什么是迁移学习,它在人工智能中有什么用?
【5月更文挑战第2天】【AI 初识】什么是迁移学习,它在人工智能中有什么用?
|
8天前
|
机器学习/深度学习 人工智能 算法
构建未来:人工智能在持续学习系统中的应用
【4月更文挑战第30天】 随着机器学习技术的不断进步,人工智能(AI)已经从静态的知识库演变为能够进行自我更新和优化的动态系统。本文探讨了AI在持续学习系统中的关键应用,分析了其如何通过实时数据分析、模式识别以及自适应算法来增强系统的学习能力和决策效率。我们还将讨论这些技术如何推动个性化服务的发展,并在不断变化的环境中维持系统的相关性和准确性。
|
8天前
|
机器学习/深度学习 人工智能 自然语言处理
构建未来:AI驱动的自适应学习系统
【4月更文挑战第30天】 随着人工智能技术的迅猛发展,教育领域正经历一场由AI驱动的变革。本文将探讨一个新兴的研究领域——自适应学习系统。这种系统通过利用机器学习算法和大数据分析,能够根据学生的学习习惯、知识水平和兴趣点提供个性化的教学方案。我们首先介绍自适应学习系统的基本概念及其在现代教育中的重要性,然后详细阐述其工作原理及关键技术,包括数据挖掘、模式识别和自然语言处理等。最后,文章将分析当前自适应学习系统面临的挑战,并提出未来的发展趋势。
|
8天前
|
机器学习/深度学习 人工智能 自然语言处理
学习AI技术
【4月更文挑战第30天】学习AI技术
23 4
|
9天前
|
机器学习/深度学习 人工智能 算法
【机器学习】探究Q-Learning通过学习最优策略来解决AI序列决策问题
【机器学习】探究Q-Learning通过学习最优策略来解决AI序列决策问题