我正在将 EmguCV 用于 C#,无论我尝试什么配置,我都无法弄清楚为什么我的斑点检测不起作用。这是我的代码:
public static void Process(string videoPath, string folderSavePath)
{
// Create video capture with memory safety
using VideoCapture videoCapture = new(videoPath);
// Get properties of video
int fps = (int)videoCapture.Get(CapProp.Fps);
int frameCount = (int)videoCapture.Get(CapProp.FrameCount);
Size size = new(videoCapture.Width, videoCapture.Height);
Size processSize = size / 4;
// Determine new path for video output
string videoName = Path.GetFileNameWithoutExtension(videoPath) + "_out" + ".mp4";
string videoSavePath = Path.Combine(folderSavePath, videoName);
// Create video writer with memory safety
using VideoWriter videoWriter = new(videoSavePath, VideoWriter.Fourcc('H', '2', '6', '4'), fps, size, true);
// Set up background subtraction
BackgroundSubtractorMOG2 backgroundSubtractor = new();
backgroundSubtractor.History = 30;
backgroundSubtractor.VarThreshold = 40;
// Set up blob detection
SimpleBlobDetectorParams blobDetectorParams = new()
{
FilterByArea = true,
FilterByCircularity = false,
FilterByConvexity = false,
FilterByInertia = false,
MinArea = 1,
MaxArea = 100_000
};
SimpleBlobDetector blobDetector = new(blobDetectorParams);
int blobs = 0;
// Read frames from video capture
Mat[] frames = new Mat[frameCount];
Mat sourceFrame = new();
while (videoCapture.Read(sourceFrame))
{
// Resize frame
Mat downsizedFrame = new();
CvInvoke.Resize(sourceFrame, downsizedFrame, processSize, interpolation: Inter.Linear);
// Subtract the background
Mat foregroundFrame = new();
backgroundSubtractor.Apply(downsizedFrame, foregroundFrame);
// Remove noise
Mat noiselessFrame = new();
CvInvoke.MedianBlur(foregroundFrame, noiselessFrame, 5);
// Convert to binary video
Mat binaryFrame = new Mat();
CvInvoke.Threshold(noiselessFrame, binaryFrame, 127, 255, ThresholdType.Binary);
// Blob detection
VectorOfKeyPoint keypoints = new VectorOfKeyPoint();
blobDetector.Detect(binaryFrame, keypoints);
// Draw blobs
Mat blobsFrame = new Mat();
Features2DToolbox.DrawKeypoints(binaryFrame, keypoints, blobsFrame, new Bgr(0, 255, 0));
blobs += keypoints.Size;
// Resize again
Mat upsizedFrame = new();
CvInvoke.Resize(blobsFrame, upsizedFrame, size, interpolation: Inter.Cubic);
// Write frame to video
videoWriter.Write(upsizedFrame);
}
Debug.Print($"Detected {blobs} blobs.");
}
令人沮丧的是视频输出清晰的形状。我的背景扣除和噪音消除似乎工作得非常完美。然而,斑点检测仍然失败。
顺便说一句,我知道我正在向二值图像绘制绿色关键点,我相信这实际上可能不会绘制。那可以忽略不计。一旦它工作,我会将它们绘制到我的非二进制框架之一。我一直在使用打印语句来确定是否找到任何斑点,而不是实际的输出视频本身。
原来我只需要使用
blobDetector.DetectRaw(binaryFrame, keypoints);