我需要指定将要进行运动检测的区域。我要做的是计算通过某个区域的车辆数量。下面是我的代码:
private static void ProcessFrame(Mat backgroundFrame, int threshold, int erodeIterations, int dilateIterations)
{
// Find difference between background (first) frame and current frame
CvInvoke.AbsDiff(backgroundFrame, rawFrame, diffFrame);
// Apply binary threshold to grayscale image (white pixel will mark difference)
CvInvoke.CvtColor(diffFrame, grayscaleDiffFrame, ColorConversion.Bgr2Gray);
CvInvoke.Threshold(grayscaleDiffFrame, binaryDiffFrame, threshold, 255, ThresholdType.Binary);
// Remove noise with opening operation (erosion followed by dilation)
CvInvoke.Erode(binaryDiffFrame, denoisedDiffFrame, null, new Point(-1, -1), erodeIterations, BorderType.Default, new MCvScalar(1));
CvInvoke.Dilate(denoisedDiffFrame, denoisedDiffFrame, null, new Point(-1, -1), dilateIterations, BorderType.Default, new MCvScalar(1));
rawFrame.CopyTo(finalFrame);
//Rectangle rec = new Rectangle(100, 100, 100, 100);
//finalFrame = crop_color_frame(rawFrame, rec);
var img = crop_color_frame(denoisedDiffFrame, rec);
DetectObject(denoisedDiffFrame, finalFrame);
}
static int vnum = 0;
private static void DetectObject(Mat detectionFrame, Mat displayFrame)
{
using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint())
{
// Build list of contours
CvInvoke.FindContours(detectionFrame, contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple);
// Selecting largest contour
if (contours.Size > 0)
{
double maxArea = 0;
int chosen = 0;
for (int i = 0; i < contours.Size; i++)
{
VectorOfPoint contour = contours[i];
double area = CvInvoke.ContourArea(contour);
if (area > maxArea)
{
maxArea = area;
chosen = i;
}
}
// Draw on a frame
MarkDetectedObject(displayFrame, contours[chosen], maxArea, contours.Size, maxArea);
}
}
}
private static void MarkDetectedObject(Mat frame, VectorOfPoint contour, double area, double contourSize, double maxArea)
{
// Getting minimal rectangle which contains the contour
Rectangle box = CvInvoke.BoundingRectangle(contour);
// Drawing contour and box around it
CvInvoke.Polylines(frame, contour, true, drawingColor);
CvInvoke.Rectangle(frame, box, drawingColor);
// Write information next to marked object
Point center = new Point(box.X + box.Width / 2, box.Y + box.Height / 2);
Point center2 = new Point(box.Width, box.Height);
var info = new string[] {
$"Area: {area}",
$"Position: {center.X}, {center.Y}"
};
Console.WriteLine($"X: {center.X} | Y: {center.Y} | Area: {area} | Count: {vnum} | Status: {vehicleState} | contour: {contour.Size}");
switch (vehicleState)
{
case VehicleState.Entering:
if(_startCount)
{
//if(((maxArea > 15000 && maxArea <= 20000) && center.Y <= 120) || ((maxArea >= 5000 && maxArea < 10000) && center.Y >= 150))
if(center.Y >= 100 && maxArea > 20000)
{
CountVehicle();
vehicleState = VehicleState.Exiting;
_startCount = false;
}
}
break;
case VehicleState.Exiting:
if (!_startCount)
{
//if(maxArea < 12000 && center.Y <= 120)
if(center.Y <= 130 && center.X <= 100 && maxArea <= 15000)
{
vehicleState = VehicleState.Entering;
_startCount = true;
}
}
break;
}
WriteMultilineText(frame, info, new Point(box.Right + 5, center.Y));
}
目前,此代码可用于检测车辆,但我仅使用
如果(center.Y> = 100 && maxArea> 20000)条件开始对车辆进行计数
该方法的问题是,正在监视框架中的所有运动。这就是为什么我只需要设置一个特定区域的原因。
您能告诉我如何做吗?
答案 0 :(得分:2)
您可以为输入图像设置ROI
squares[2]
下面是我在图像中绘制ROI的图像,您可以通过更改此行public static Mat crop_roi(Mat input_img)
{
Image<Gray, byte> img = input_img.ToImage<Gray, byte>();
double w = input_img.Width;
double h = input_img.Height;
Rectangle r = new Rectangle((int)(w * 0.2), (int)(h * 0.4), (int)(w * 0.6), (int)(h * 0.6));
Image<Gray, byte> output = img.Copy(r);
return output.Mat;
}
//USE
private static void DetectObject(Mat detectionFrame, Mat displayFrame)
{
using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint())
{
//set roi to the frame
Mat roi = new Mat()
roi = set_roi(detectionFrame);
// Build list of contours
CvInvoke.FindContours(roi , contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple);
// Selecting largest contour
...
MarkDetectedObject(roi , contours[chosen], maxArea, contours.Size, maxArea);
}
的参数来调整ROI