C# OpenCV7 -人体检测
程序员文章站
2022-07-13 22:08:18
...
1. 定义识别辅助类
2. 对抓取图片进行灰度处理
3. 使用haarcascade模型进行人体上半身识别
4. 判断目标是否在目标区域
5. 绘出目标边框
public class ObjTest
{
private CascadeClassifier _cascadeClassifier;
private Capture _capture;
private Point[] _points;
public ObjTest(Point[] points)
{
_points = points;
_capture = new Capture();
_cascadeClassifier = new CascadeClassifier(Application.StartupPath + "/haarcascades/haarcascade_upperbody.xml");
}
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>();
var faces = _cascadeClassifier.DetectMultiScale(grayframe, 1.1, 10,
Size.Empty); //the actual face detection happens here
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;
}