C++ 仅绘制存在于多个帧上的轮廓以消除闪烁
我已经在这里和其他网站上研究了一个多星期了,现在还没有任何发现 我在Linux上用C++和OpenCV编码。 我有一个云室的黑白视频()。我想画运动粒子轨迹周围的轮廓。目前我正在使用findContours和drawContours;但是,它会在所有白色像素周围绘制轮廓,包括快速出现和消失的像素。我不想在我的背景,闪烁的白色像素周围画轮廓 我的问题是背景也在移动,所以背景减法不起作用。有没有办法: a) 仅当轮廓在多个帧上大致位于同一位置时,才绘制轮廓 b) 如果在多个帧(可能至少4或5帧)中不存在白色像素,请删除该像素 谢谢你能提供的任何帮助 编辑:用于比较两个帧(第一帧和第二帧)的代码C++ 仅绘制存在于多个帧上的轮廓以消除闪烁,c++,opencv,C++,Opencv,我已经在这里和其他网站上研究了一个多星期了,现在还没有任何发现 我在Linux上用C++和OpenCV编码。 我有一个云室的黑白视频()。我想画运动粒子轨迹周围的轮廓。目前我正在使用findContours和drawContours;但是,它会在所有白色像素周围绘制轮廓,包括快速出现和消失的像素。我不想在我的背景,闪烁的白色像素周围画轮廓 我的问题是背景也在移动,所以背景减法不起作用。有没有办法: a) 仅当轮廓在多个帧上大致位于同一位置时,才绘制轮廓 b) 如果在多个帧(可能至少4或5帧)中不
Vec3b帧颜色;
Vec3b-2;
对于(int x=0;x
你可以实现你的想法:For each frame do:
For each white pixel do:
If the pixels in the neigbourhood of the last N frames are *mostly* white
Set the current pixel to white
Else
Set the current pixel to black
相邻像素可以定义为像素周围的3x3遮罩。主要是指一个合适的阈值,假设N帧中80%的帧应该支持(白色)像素位置
红色像素是当前像素(x,y),绿色像素是其相邻像素。 可以如下实现对像素(x,y)的相邻像素的比较:
const int MASK_SIZE = 3;
int numberOfSupportingFrames = 0;
for(int k = 0; k < N; k++)
{
Mat currentPreviousFrame = previousFrames.at(k);
bool whitePixelAvailable = false;
for(int i = x-(MASK_SIZE/2); i < x+(MASK_SIZE/2) && !whitePixelAvailable; i++)
{
for(int j = y-(MASK_SIZE/2); j < y+(MASK_SIZE/2) && !whitePixelAvailable; j++)
{
if(currentPreviousFrame.at<Vec3b>(Point(i, j)) == white)
{
whitePixelAvailable = true;
numberOfSupportingFrames++;
}
}
}
}
if((float)numberOfSupportingFrames / (float)N > 0.8)
secondFrameAfter.at<Vec3b>(Point(x, y)) = white;
else
secondFrameAfter.at<Vec3b>(Point(x, y)) = black;
const int MASK_SIZE=3;
int numberOfSupportingFrames=0;
对于(int k=0;k0.8)
在(点(x,y))处的第二帧之后=白色;
其他的
在(点(x,y))处的第二帧之后=黑色;
先前的帧存储在std::vector previousFrames
中该算法检查像素(x,y)的时空邻域。外部循环迭代相邻帧(时间相邻帧),而内部两个循环迭代相邻八个像素(空间邻域)。如果当前空间邻域中存在白色像素,则前一帧支持当前像素(x,y)。最后,检查是否有足够的帧支持当前像素(80%的前一帧应至少包含8个相邻像素上的白色像素)。
此代码应嵌套在两个for循环中,并进行一些修改(变量名、边界处理)。我了解如何将一帧中的像素与前一帧中相同位置的像素进行比较。我试着比较四帧,但并没有太大的改进,因为像素的整体移动。(我用比较两帧的代码编辑了我的原始问题。)我的问题是如何比较像素的邻域?
const int MASK_SIZE = 3;
int numberOfSupportingFrames = 0;
for(int k = 0; k < N; k++)
{
Mat currentPreviousFrame = previousFrames.at(k);
bool whitePixelAvailable = false;
for(int i = x-(MASK_SIZE/2); i < x+(MASK_SIZE/2) && !whitePixelAvailable; i++)
{
for(int j = y-(MASK_SIZE/2); j < y+(MASK_SIZE/2) && !whitePixelAvailable; j++)
{
if(currentPreviousFrame.at<Vec3b>(Point(i, j)) == white)
{
whitePixelAvailable = true;
numberOfSupportingFrames++;
}
}
}
}
if((float)numberOfSupportingFrames / (float)N > 0.8)
secondFrameAfter.at<Vec3b>(Point(x, y)) = white;
else
secondFrameAfter.at<Vec3b>(Point(x, y)) = black;