1. 从内置摄像头获取识别图像
2. 灰度处理图片
3. 指定SVM分类器:使用HogDescriptor获取PeopleDetector
4. 使用分类器进行人体识别
5. 判断目标是否在指定区域内
6. 绘制出目标边框
public class ObjTestHog
{
private Capture _capture;
private Point[] _points;
public ObjTestHog(Point[] points)
{
_points = points;
_capture = new Capture();
}
public void ResetPoly(Point[] points)
{
_points = points;
}
public void Do(PictureBox pictureBox,Action callback)
{
using (var imageFrame = _capture.QueryFrame().ToImage<Bgr, Byte>())
{
if (imageFrame != null)
{
var grayframe = imageFrame.Convert<Gray, byte>();
using (HOGDescriptor des = new HOGDescriptor())
{
des.SetSVMDetector(HOGDescriptor.GetDefaultPeopleDetector());
MCvObjectDetection[] results = des.DetectMultiScale(grayframe);
var faces = new Rectangle[results.Length];
for (int i = 0; i < results.Length; i++)
faces[i] = results[i].Rect;
foreach (var face in faces)
{
var c = CenterRect(face);
if (Helper.IsPointInPolygon(c, _points))
{
imageFrame.Draw(face, new Bgr(Color.Chartreuse),
1); //the detected face(s) is highlighted here using a box that is drawn around it/them
if (callback != null)
{
callback();
}
}
}
imageFrame.DrawPolyline(_points, true, new Bgr(Color.Crimson), 1);
var bmp = EmguHelper.ResizeImage(imageFrame.ToBitmap(), new Size(pictureBox.Width, pictureBox.Height));
pictureBox.Image = bmp;
}
}
}
}
private Point CenterRect(Rectangle r)
{
return new Point(r.Left + r.Width / 2, r.Top + r.Height / 2);
}
}
辅助函数:判断目标点是否在多边形区域内:
public static bool IsPointInPolygon(Point point, Point[] polygon)
{
int polygonLength = polygon.Length, i = 0;
bool inside = false;
// x, y for tested point.
float pointX = point.X, pointY = point.Y;
// start / end point for the current polygon segment.
float startX, startY, endX, endY;
Point endPoint = polygon[polygonLength - 1];
endX = endPoint.X;
endY = endPoint.Y;
while (i < polygonLength)
{
startX = endX; startY = endY;
endPoint = polygon[i++];
endX = endPoint.X; endY = endPoint.Y;
//
inside ^= (endY > pointY ^ startY > pointY) /* ? pointY inside [startY;endY] segment ? */
&& /* if so, test if it is under the segment */
((pointX - endX) < (pointY - endY) * (startX - endX) / (startY - endY));
}
return inside;
}
辅助函数:resize图片大小
public static Bitmap ResizeImage(Bitmap bmp, Size size)
{
Bitmap newbmp = new Bitmap(size.Width, size.Height);
using (Graphics g = Graphics.FromImage(newbmp))
{
g.DrawImage(bmp, new Rectangle(Point.Empty, size));
}
return newbmp;
}