C# 使用OpenCV在一张图片里寻找人脸
先上个效果图

相关库的下载
例程中用到一个库叫做emgucv,是opencv\的net封装
编译打包好的稳定版,在这:https://sourceforge.net/projects/emgucv/files/emgucv/
如果要最新代码,在这里获取:https://github.com/emgucv/emgucv
建立工程
首先建立一个C#控制台工程.添加引用:Emgu.CV.World.dll
然后添加这2个文件到工程(在emgucv的压缩包里有的,搜索下文件吧~):
注意:其中的dll文件需要根据要编译的程序是32位还是64位选不同文件

记得把"复制到输出目录"设为"较新则复制"
另外准备一张要识别的图片,放到编译输出目录.
接下来就是编辑代码了,后面所有代码都在main里
配置OpenCV使用显卡运算(如果支持的话)
使用显卡处理图像数据效率会很多,如果你的设备支持,最好打开,使用CvInvoke.HaveOpenCLCompatibleGpuDevice能返回是否支持.
配置CvInvoke.UseOpenCL能让OpenCV 启用或者停用 GPU运算
CvInvoke.UseOpenCL = CvInvoke.HaveOpenCLCompatibleGpuDevice;
构建级联分类器对象
emgu包里已经有训练好的数据了,文件名叫做"haarcascade_frontalface_alt.xml",就是上面添加的文件之一
var face = new CascadeClassifier("haarcascade_frontalface_alt.xml");
加载图像并作简单处理
在OpenCV中,大部分函数是处理灰度图的,包括这个识别物体,所以需要转成灰度图,然后再调整下亮度
//加载要识别的图片
var img = new Image<Bgr, byte>("0.png");
var img2 = new Image<Gray, byte>(img.ToBitmap());
//把图片从彩色转灰度
CvInvoke.CvtColor(img, img2, Emgu.CV.CvEnum.ColorConversion.Bgr2Gray);
//亮度增强
CvInvoke.EqualizeHist(img2, img2);
检测人脸
其实这一步反而最简单,返回的是rectangle[]格式,因为图中可能有多个人脸,所以返回的是数组.
//在这一步就已经识别出来了,返回的是人脸所在的位置和大小
var facesDetected = face.DetectMultiScale(img2, 1.1, 10, new Size(50, 50));
剪切并保存
因为是多个人脸所以需要循环剪切并保存,(→_→)这一块的代码量竟然反而比上面那堆多
//循环把人脸部分切出来并保存
int count = 0;
var b = img.ToBitmap();
foreach (var item in facesDetected)
{
count++;
var bmpOut = new Bitmap(item.Width, item.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
var g = Graphics.FromImage(bmpOut);
g.DrawImage(b, new Rectangle(0, 0, item.Width, item.Height), new Rectangle(item.X, item.Y, item.Width, item.Height), GraphicsUnit.Pixel);
g.Dispose();
bmpOut.Save($"{count}.png", System.Drawing.Imaging.ImageFormat.Png);
bmpOut.Dispose();
}
释放资源退出
//释放资源退出
b.Dispose();
img.Dispose();
img2.Dispose();
face.Dispose();
全代码和测试图片:

static void Main(string[] args)
{
//如果支持用显卡,则用显卡运算
CvInvoke.UseOpenCL = CvInvoke.HaveOpenCLCompatibleGpuDevice;
//构建级联分类器,利用已经训练好的数据,识别人脸
var face = new CascadeClassifier("haarcascade_frontalface_alt.xml");
//加载要识别的图片
var img = new Image<Bgr, byte>("0.png");
var img2 = new Image<Gray, byte>(img.ToBitmap());
//把图片从彩色转灰度
CvInvoke.CvtColor(img, img2, Emgu.CV.CvEnum.ColorConversion.Bgr2Gray);
//亮度增强
CvInvoke.EqualizeHist(img2, img2);
//在这一步就已经识别出来了,返回的是人脸所在的位置和大小
var facesDetected = face.DetectMultiScale(img2, 1.1, 10, new Size(50, 50));
//循环把人脸部分切出来并保存
int count = 0;
var b = img.ToBitmap();
foreach (var item in facesDetected)
{
count++;
var bmpOut = new Bitmap(item.Width, item.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
var g = Graphics.FromImage(bmpOut);
g.DrawImage(b, new Rectangle(0, 0, item.Width, item.Height), new Rectangle(item.X, item.Y, item.Width, item.Height), GraphicsUnit.Pixel);
g.Dispose();
bmpOut.Save($"{count}.png", System.Drawing.Imaging.ImageFormat.Png);
bmpOut.Dispose();
}
//释放资源退出
b.Dispose();
img.Dispose();
img2.Dispose();
face.Dispose();
return;
}
运行效果
编译后运行可以看到目录多了两个图片文件:

打开看看:

C# 使用OpenCV在一张图片里寻找人脸的更多相关文章
- OpenCV读一张图片并显示
Java 版本: JavaCV 用OpenCV读一张图片并显示.只需将程序运行时的截图回复.如何安装配置创建项目编写OpenCV代码,可参考何东健课件和源代码或其他资源. package com.gi ...
- opencv基于PCA降维算法的人脸识别
opencv基于PCA降维算法的人脸识别(att_faces) 一.数据提取与处理 # 导入所需模块 import matplotlib.pyplot as plt import numpy as n ...
- 【计算机视觉】OpenCV篇(9) - 轮廓(寻找/绘制轮廓)
什么是轮廓? 轮廓是一系列相连的点组成的曲线,代表了物体的基本外形. 轮廓与边缘好像挺像的? 是的,确实挺像,那么区别是什么呢?简而言之,轮廓是连续的,而边缘并不全都连续(见下图示例).其实边缘主要是 ...
- opencv—读取一张图片并滤波
#include <opencv2\opencv.hpp> #include <iostream> #include <string> using namespac ...
- 如何在UIimageview里显示一张图片里的某一部分
首先,获取想要显示的部分的大小及位置 CGRect rect: 然后,将此部分从图片中剪切出来 CGImageRef imageRef=CGImageCreateWithImageInRect([im ...
- PS CS5如何在一张图片里插入另一张图片?
帮你介绍两种比较简便的方法:1.ctrl+A全选,ctrl+C复制,在另一个图中ctrl+V粘贴即可:2.PS中的窗口可以拖动的,拉动一个窗口,选择移动工具,直接移到另一张图上即可!
- opencv如何用模板匹配寻找目标
首先使用: MatchTemplate 比较模板和重叠的图像区域 void cvMatchTemplate( const CvArr* image, const CvArr* templ, CvArr ...
- 利用opencv中的级联分类器进行人脸检測-opencv学习(1)
OpenCV支持的目标检測的方法是利用样本的Haar特征进行的分类器训练,得到的级联boosted分类器(Cascade Classification).注意,新版本号的C++接口除了Haar特征以外 ...
- 基于深度学习的人脸识别系统(Caffe+OpenCV+Dlib)【二】人脸预处理
前言 基于深度学习的人脸识别系统,一共用到了5个开源库:OpenCV(计算机视觉库).Caffe(深度学习库).Dlib(机器学习库).libfacedetection(人脸检测库).cudnn(gp ...
随机推荐
- Mysql数据库文件、表、记录的增删改查
一.数据库文件夹的的操作 create database db1 charset utf8; 增加db1文件夹 show databases ; 查看所有数据库 show create databas ...
- java 利用反射构造泛型类
1.构造BaseDao泛型类 class BaseDao<T>{ private Class<T> entityClass; // 通过反射获取实际运行的精确类 public ...
- vue组件初学--弹射小球
1. 定义每个弹射的小球组件( ocicle ) 2. 组件message自定义属性存放小球初始信息(可修改) { top: "0px", //小球距离上方坐标 left: &qu ...
- QT_FORWARD_DECLARE_CLASS
相当于class 类名. 那么他和#include 包含头文件有什么区别呢 首先我们为什么要包括头文件问题的回答很简单通常是我们需要获得某个类型的定义(definition).那么接下来的问题 ...
- Spring Boot Document Part II(上)
Part II. Getting started 这一章内容适合刚接触Spring Boot或者"Spring"家族的初学者!随着安装指导说明,你会发现对Spring boot有一 ...
- Coin Change (II)(完全背包)
Coin Change (II) Time Limit: 1000MS Mem ...
- Python系列之反射、面向对象
一.反射 说反射之前先介绍一下__import__方法,这个和import导入模块的另一种方式 1. import commons 2. __import__('commons') 如果是多层导入: ...
- hdu 4057--Rescue the Rabbit(AC自动机+状压DP)
题目链接 Problem Description Dr. X is a biologist, who likes rabbits very much and can do everything for ...
- 深刻理解反射(Reflection)
最近公司在搞自动化测试,由于版权问题,无法用 '录制脚本' 进行,也就没法用 VS 自带的 UITest 框架(蛋疼), 所以只能开源的 FlaUI 框架来搞了.其中不可避免的涉及到反射的应用,但自己 ...
- YYHS-手机信号
题目描述 输入 输出 样例输入 11 10000 query 5 construct 5 500 100 query 500 query 1000 construct 10 90 5 query 44 ...