- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想知道是否有人可以阐明一种能够在每帧的基础上对轮廓进行排序的策略。
我正在尝试检测“事件” - 在本例中,事件被定义为 4 帧的运动增长。
如果轮廓“增长”/在 4 个连续帧中具有更大的轮廓区域,则会记录一个事件,并且我必须存储并输出增长的第一帧的轮廓中心位置。
如果只检测到一个事件,我可以通过对轮廓区域列表执行成对检查来粗略地检测事件的起源,如果这是真的,则通过采用 (currentFrameNo - 4) 位置元素轮廓位置列表。
但是,尝试检测多个事件似乎是完全不同的游戏。
在任何给定的帧上,可能会找到 (n) 个轮廓。每个轮廓都被传递到一个候选对象中,并具有表征轮廓的属性,例如帧号、位置和轮廓大小。
最终,我需要一种在每帧的基础上对这些轮廓进行排序的方法,这样我就可以根据它们的相对位置来组织它们,然后对轮廓的“正确列表”执行成对检查。
我不确定是否需要多个(4+)列表,每个可能的事件一个,然后在每一帧上根据最近的中心位置将候选者传递到一个单独的列表,或者我是否应该继续将它们添加到单个列表,然后查询该列表。
我希望在使用 linq/排序集合方面有更多经验的人可以帮助确定合适的方法。
感谢您花时间阅读这篇文章。
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 帧检索中心位置。
最佳答案
您可以使用 circular buffers 的列表存储每个候选人的历史记录:
public class CandidateBufferList
{
private List<CircularBuffer<Candidate>> _candidateList = new List<CircularBuffer<Candidate>>();
private void Add(Candidate candidate)
{
//Find a matching buffer for the candidate based on distance. More on this later
//here maxDistance is the maximum distance a candidate can move each frame
var matches = _candidateList.Where(cb => Distance(candidate.Location, cb.Last.Location) < maxDistance);
int matchCount = matches.Count();
if (matchCount == 0)
{
var cb = new CircularBuffer<Candidate>();
cb.Add(candidate);
_candidateList.Add(cb);
}
else if (matchCount == 1)
{
var match = matches.First();
if (match.Last.FrameNumber == candidate.FrameNumber)
{
// Ambiguous match 1.
throw new Exception("A candidate was already added to this buffer this frame.");
}
match.Add(candidate);
}
else
{
// Ambiguous match 2.
throw new Exception("More than one matching buffer was found for this candidate");
}
}
public void Update(int frameNumber, List<Candidate> candidates)
{
candidates.ForEach(c => Add(c));
//Remove buffers that didn't match this frame.
_candidateList.RemoveAll(cb => cb.Last.FrameNumber != frameNumber);
}
public List<Point> GetEvents()
{
return _candidateList
.Where(cb => ContourHasGrouwn(cb))
.Select(cb => cb.First.Location)
.ToList();
}
private bool ContourHasGrouwn(CircularBuffer<Candidate> cb)
{
//if contour is not older than 4 frames
if (!cb.IsFull) return false;
for (int i = 1; i < cb.Size; i++)
{
if (cb[i].ContourSize < cb[i - 1].ContourSize) return false;
}
return true;
}
}
在每个 ProcessFrame 上:
//CandidateBufferList candidatesHistory
//List<Candidate> candidatesThisFrame
candidatesHistory.Update(frameNumber, candidatesThisFrame);
var events = candidatesHistory.GetEvents();
我想我应该提到,如果您尝试仅通过距离查找匹配项,可能会或可能不会出现问题,具体取决于您的具体问题:
候选人可能更接近另一个候选人中心,例如。一个新的候选者被添加到靠近另一个候选者的中心(模糊匹配 1)
候选人可能会获得多个匹配项,您可以选择距离最小的匹配项,但如何确定这是正确的? (不明确匹配 2)
这是CircularBuffer
实现:
class CircularBuffer<T>
{
private const int _size = 4;
private int _index;
private T[] _elements = new T[_size];
public int Size => _size;
public int Count { get; private set; }
public bool IsFull => Count == Size;
public T this[int i] => _elements[(_index + i)%_size];
public T First => this[0];
public T Last => this[_size-1];
public void Add(T element)
{
_elements[_index] = element;
_index = (_index+1) % _size;
if (Count < _size) Count++;
}
}
关于c# - 如何对轮廓进行排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60325511/
我喜欢 smartcase,也喜欢 * 和 # 搜索命令。但我更希望 * 和 # 搜索命令区分大小写,而/和 ?搜索命令遵循 smartcase 启发式。 是否有隐藏在某个地方我还没有找到的设置?我宁
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题? Update the question所以它是on-topic对于堆栈溢出。 10年前关闭。 Improve this qu
从以下网站,我找到了执行java AD身份验证的代码。 http://java2db.com/jndi-ldap-programming/solution-to-sslhandshakeexcepti
似乎 melt 会使用 id 列和堆叠的测量变量 reshape 您的数据框,然后通过转换让您执行聚合。 ddply,从 plyr 包看起来非常相似..你给它一个数据框,几个用于分组的列变量和一个聚合
我的问题是关于 memcached。 Facebook 使用 memcached 作为其结构化数据的缓存,以减少用户的延迟。他们在 Linux 上使用 UDP 优化了 memcached 的性能。 h
在 Camel route ,我正在使用 exec 组件通过 grep 进行 curl ,但使用 ${HOSTNAME} 的 grep 无法正常工作,下面是我的 Camel 路线。请在这方面寻求帮助。
我正在尝试执行相当复杂的查询,在其中我可以排除与特定条件集匹配的项目。这是一个 super 简化的模型来解释我的困境: class Thing(models.Model) user = mod
我正在尝试执行相当复杂的查询,我可以在其中排除符合特定条件集的项目。这里有一个 super 简化的模型来解释我的困境: class Thing(models.Model) user = mod
我发现了很多嵌入/内容项目的旧方法,并且我遵循了在这里找到的最新方法(我假设):https://blog.angular-university.io/angular-ng-content/ 我正在尝试
我正在寻找如何使用 fastify-nextjs 启动 fastify-cli 的建议 我曾尝试将代码简单地添加到建议的位置,但它不起作用。 'use strict' const path = req
我正在尝试将振幅 js 与 React 和 Gatsby 集成。做 gatsby developer 时一切看起来都不错,因为它发生在浏览器中,但是当我尝试 gatsby build 时,我收到以下错
我试图避免过度执行空值检查,但同时我想在需要使代码健壮的时候进行空值检查。但有时我觉得它开始变得如此防御,因为我没有实现 API。然后我避免了一些空检查,但是当我开始单元测试时,它开始总是等待运行时异
尝试进行包含一些 NOT 的 Kibana 搜索,但获得包含 NOT 的结果,因此猜测我的语法不正确: "chocolate" AND "milk" AND NOT "cow" AND NOT "tr
我正在使用开源代码共享包在 iOS 中进行 facebook 集成,但收到错误“FT_Load_Glyph failed: glyph 65535: error 6”。我在另一台 mac 机器上尝试了
我正在尝试估计一个标准的 tobit 模型,该模型被审查为零。 变量是 因变量 : 幸福 自变量 : 城市(芝加哥,纽约), 性别(男,女), 就业(0=失业,1=就业), 工作类型(失业,蓝色,白色
我有一个像这样的项目布局 样本/ 一种/ 源/ 主要的/ java / java 资源/ .jpg 乙/ 源/ 主要的/ java / B.java 资源/ B.jpg 构建.gradle 设置.gr
如何循环遍历数组中的多个属性以及如何使用map函数将数组中的多个属性显示到网页 import React, { Component } from 'react'; import './App.css'
我有一个 JavaScript 函数,它进行 AJAX 调用以返回一些数据,该调用是在选择列表更改事件上触发的。 我尝试了多种方法来在等待时显示加载程序,因为它当前暂停了选择列表,从客户的 Angul
可能以前问过,但找不到。 我正在用以下形式写很多语句: if (bar.getFoo() != null) { this.foo = bar.getFoo(); } 我想到了三元运算符,但我认
我有一个表单,在将其发送到 PHP 之前我正在执行一些验证 JavaScript,验证后的 JavaScript 函数会发布用户在 中输入的文本。页面底部的标签;然而,此消息显示短暂,然后消失...
我是一名优秀的程序员,十分优秀!