Мне интересно, может ли кто-нибудь объяснить стратегию, которая способна сортировать контуры для каждого кадра.
Я пытаюсь обнаружить «события» - в этом случае событие определяется как рост движение для 4 кадров.
Если контур «растет» / имеет большую площадь контура для 4 последовательных кадров, событие регистрируется, и я должен сохранить и вывести центральную позицию контура для первого кадра роста.
Если обнаруживается только одно событие, я могу грубо определить происхождение события, выполнив попарную проверку списка областей контура и, если это станет правдой, взяв позиционный (currentFrameNo - 4) элемент списка контурных позиций.
Однако попытка обнаружить несколько событий кажется совершенно другой игрой с мячом.
В любом данном кадре может быть (n) количество найденных контуров. Каждый контур передается в объект-кандидат с атрибутами, которые характеризуют контур, такими как номер кадра, положение и размер контура.
В конечном итоге мне нужен способ сортировки этих контуров для каждого кадра, например что я могу организовать их на основе их относительного положения, а затем выполнить попарную проверку «правильного списка» контуров.
Я не уверен, нужно ли мне несколько (4+) списков, по одному для каждого возможного события, а затем в каждом кадре передавать кандидатов в отдельный список, основанный на ближайших центральных позициях, или мне следует продолжать добавьте их в один список, а затем сделайте запрос к списку.
Я надеюсь, что кто-то с большим опытом использования коллекций linq / sorting поможет определить подходящий подход.
Спасибо, что приняли время читать этот пост.
public class CandidateList
{
public List<Candidate> candidates;
public CandidateList()
{
candidates = new List<Candidate> candidates;
}
public void Add(Candidate candidate)
{
candidates.Add(candidate)
}
}
public class Candidate
{
//Attributes shown in constructor.
public Candidate(VectorOfPoint contour, int frameNumber, double contourSize, Point location)
{
Contour = contour;
FrameNumber = frameNumber;
ContourSize = contourSize;
Location = location;
Location_x = Location.X;
Location_y = Location.Y;
}
}
_vc = new VideoCapture(someURLorFilePath);
_candidates = new CandidateList();
_vc.ImageGrabbed += ProcessFrame;
public void ProcessFrame(object sender, EventArgs e)
{
Mat _frame = new Mat();
// read frame.. + other operations to get desired data.
Mat _contourOutput = _frame.Clone();
VectorOfVectorOfPoint _contours = new VectorOfVectorOfPoint();
CvInvoke.FindContours(_contourOutput, _contours, new Mat(), RetrType.External, ChainApproxMethod.ChainApproxSimple);
// If there are any contours
if (_contours.Size > 0)
{
// Iterate through contours
for (var i = 0; i < _contours.Size; i++)
{
// Find contour area of each contour (VectorOfPoint)
double _contourArea = CvInvoke.ContourArea(_contours[i]);
// Find centre of contour
Moments M = CvInvoke.Moments(_contours[i]);
Point _contourCentre = new Point(Convert.ToInt16(M.M10 / M.M00), Convert.ToInt16(M.M01 / M.M00));
// Create a candidate based on frame number, contourSize and location
Candidate _candidate = new Candidate(_contours[i], _currentFrameNo, _contourArea, _contourCentre);
_candidates.Add(_candidate)
}
}
_currentFrameNo ++
}
Вот картинки, изображающие очень вероятный сценарий, с которым мне приходится иметь дело:
Кадр 1 - Четыре кандидата.
Кадр 2 - Четыре кандидата, слегка смещенная позиция
Кадр 3 - Четыре кандидата, слегка смещенные позиция
Кадр 4 - четыре кандидата, смещенная позиция Обнаружены два события. Получить центральные позиции из кадра 1.