- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用函数 cvCalcOpticalFlowPyrLK()
来检测和跟踪视频中的移动对象。我使用 Canny()
函数来跟踪特征。但结果并不好,它有很多来自 cvCalcOpticalFlowPyrLK()
的噪音。
请看下面我的代码:
#include <windows.h>
#include <stdio.h>
#include <vector>
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
double Distance(Point& p1, Point& p2)
{
return abs(p2.x - p1.x) + abs(p2.y - p1.y);
}
VOID EliminateBgrLines(vector<vector<Point>>* srcCountours, vector<vector<Point>>* dstCountours,
CvPoint2D32f* frame1_features, CvPoint2D32f* frame2_features, char* optical_flow_found_feature)
{
Point p, q;
int featureIndex = 0;
int numContours = srcCountours->size();
int* removeContoursIndex = new int[numContours];
int countRemoveContours = 0;
vector<vector<Point>>::iterator Iter;
int iterIndex = 0;
for(Iter = srcCountours->begin() ; Iter != srcCountours->end() ; Iter++)
{
vector<Point> contour = *Iter;
int numPoints = contour.size();
int countBgrPoints = 0;
int countTotalPointsFound = 0;
double totalDistance = 0;
for(int k = 0 ; k < numPoints; k++)
{
if(optical_flow_found_feature[featureIndex] == 0)
{
featureIndex ++;
countBgrPoints ++; //The points that can not find in the next frame will be treated as background point
continue;
}
countTotalPointsFound ++;
p. x = (int)frame1_features[featureIndex].x;
p. y = (int)frame1_features[featureIndex].y;
q. x = (int)frame2_features[featureIndex].x;
q. y = (int)frame2_features[featureIndex].y;
featureIndex ++;
double d = Distance(p, q);
totalDistance += d;
double opticalFlowThreshold = 1;
if(d < opticalFlowThreshold)
countBgrPoints ++;
}
int eliminateBgrLineThreshold = 40; //40 %
if ( (double)countBgrPoints/numPoints > (eliminateBgrLineThreshold/100) ) //eliminateBgrLineThreshold(%) is bgr point
{
removeContoursIndex[countRemoveContours] = iterIndex;
countRemoveContours ++;
}
iterIndex++;
}
for(int i = 0 ; i < numContours; i++)
{
if(trackingCoreGlobal->ISContainInArray(i, removeContoursIndex, countRemoveContours) == false)
dstCountours->insert(dstCountours->end(), srcCountours->at(i));
}
delete []removeContoursIndex;
}
int main()
{
long current_frame = 0 ;
CvSize frame_size;
long number_of_frames = 0;
CvCapture *input_video = NULL;
input_video = cvCaptureFromFile(videoPath);
if (input_video == NULL)
return false;
cvQueryFrame(input_video);
frame_size.height = (int)cvGetCaptureProperty(input_video, CV_CAP_PROP_FRAME_HEIGHT);
frame_size.width = (int)cvGetCaptureProperty(input_video, CV_CAP_PROP_FRAME_WIDTH);
/* Go to the end of the AVI (The fraction is "1") */
cvSetCaptureProperty( input_video, CV_CAP_PROP_POS_AVI_RATIO, 1.0) ;
number_of_frames = (int)cvGetCaptureProperty( input_video, CV_CAP_PROP_POS_FRAMES) ;
/* Return to the beginning */
cvSetCaptureProperty( input_video, CV_CAP_PROP_POS_FRAMES , 0.0) ;
int number_of_features = 0;
CvPoint2D32f* frame1_features = new CvPoint2D32f[NUMBER_OF_FEATURES];
CvPoint2D32f* frame2_features = new CvPoint2D32f[NUMBER_OF_FEATURES];
char* optical_flow_found_feature = new char[NUMBER_OF_FEATURES];
float* optical_flow_feature_error = new float[NUMBER_OF_FEATURES];
while(isStopped == false)
{
static IplImage * frame = NULL, * frame1_1C = NULL, * frame2_1C =
NULL, * eig_image = NULL, * temp_image = NULL, * pyramid1 = NULL, * pyramid2 = NULL;
/* Go to the frame we want. Important if multiple frames are queried in
* the loop which they of course are for optical flow. Note that the very
* first call to this is actually not needed . ( Because the correct position
* is set outsite the for () loop.)
*/
cvSetCaptureProperty( input_video, CV_CAP_PROP_POS_FRAMES, current_frame) ;
/* Get the next frame of the video.
* IMPORTANT ! cvQueryFrame() always returns a pointer to the _ same_
* memory location. So successive calls :
* frame1 = cvQueryFrame();
* frame2 = cvQueryFrame();
* frame3 = cvQueryFrame();
* will result in ( frame1 == frame2 && frame2 == frame3 ) being true.
* The solution is to make a copy of the cvQueryFrame() output .
*/
frame = cvQueryFrame(input_video);
if(frame == NULL)
return false;
frame1_1C = cvCreateImage(frame_size, IPL_DEPTH_8U, 1);
if(frame1_1C == NULL)
return false;
cvConvertImage(frame, frame1_1C);
/* Get the second frame of video. Sample principles as the first */
frame = cvQueryFrame(input_video);
if(frame == NULL)
return false;
frame2_1C = cvCreateImage(frame_size, IPL_DEPTH_8U, 1);
if(frame2_1C == NULL)
return false;
cvConvertImage(frame, frame2_1C);
/*Preparation : Allocate the necessary storage*/
eig_image = cvCreateImage(frame_size, IPL_DEPTH_32F, 1);
if(eig_image == NULL)
return false;
temp_image = cvCreateImage(frame_size, IPL_DEPTH_32F, 1);
if(temp_image == NULL)
return false;
number_of_features = 0;
/* Actually run the Shi and Tomasi algorithm !!
* "frame1 _ 1 C " is the input image.
* "eig _ image" and " temp_ image" are just workspace for the algorithm .
* The first ".01" specifies the minimum quality of the features ( based on the
eigenvalues ).
* The second ".01" specifies the minimum Euclidean distance between features .
* "NULL" means use the entire input image. You could point to a part of the
image.
* WHEN THE ALGORITHM RETURNS:
* "frame1 _ features" will contain the feature points.
* "number _ of_ features" will be set to a value < = NUMBER_OF_FEATURES indicating the number of
feature points found.
*/
//Get Features by using Canny Edges - Begin
int ratio = 3;
int kernel_size = 3;
int cannyThreshold = 40;
Mat detected_edges;
Mat frame1_1C_Mat = cvarrToMat(frame1_1C);
// Reduce noise with a kernel 3x3
blur(frame1_1C_Mat, detected_edges, Size(3,3)) ;
// Canny detector
Canny(detected_edges, detected_edges, cannyThreshold, cannyThreshold*ratio, kernel_size);
RNG rng(12345);
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(detected_edges, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
DrawContours(contours, "Before Removing Bgr Contours"); //This function will draw the result contours
//Copy feature for tracking by optical flow
int numContours = contours.size();
for(int i = 0 ; i < numContours; i++)
{
vector<Point> contour = contours.at(i);
int numPoints = contour.size();
for(int k = 0 ; k < numPoints; k++)
{
Point point = contour.at(k);
frame1_features[number_of_features].x = point.x;
frame1_features[number_of_features].y = point.y;
number_of_features++;
}
}
/*
This termination criteria tells the algorithm to stop when it has either done
20 iterations or when epsilon is better than 0.3, you can play with these parameters
for speed vs accuracy but these values work pretty well in many situations.
*/
CvTermCriteria optical_flow_termination_criteria = cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS, 20, 0.3) ;
/* This is some workspace for the algorithm.
The algorithm actually carves the image into pyramids of different resolutions
*/
pyramid1 = cvCreateImage(frame_size, IPL_DEPTH_8U, 1);
if(pyramid1 == NULL)
return false;
pyramid2 = cvCreateImage(frame_size, IPL_DEPTH_8U, 1);
if(pyramid2 == NULL)
return false;
/*Actually run Pyramidal Lucas Kanade Optical Flow!!
* "frame1_1C" is the first frame with the known features.
* "frame2_1C" is the second frame where we want to find the first frame's features.
* "pyramid1" and "pyramid2" are workspace for the algorithm.
* "frame1_features" are the features from the first frame.
* "frame2_features" is the (outputted) locations of those features in the second frame.
* "number_ of_features" is the number of features in the frame 1 _ features array .
* "optical_flow_window" is the size of the window to use to avoid the aperture problem.
* "5" is the maximum number of pyramids to use. 0 would be just one level.
* "optical_flow_found_feature" is as described above (non-zero iff feature found by the flow).
* "optical_flow_feature_error" is as described above (error in the flow for this feature).
* "optical_flow_termination_criteria" is as described above (how long the algorithm should look).
* "0" means disable enhancements. (For example , the second array isn't pre-initialized with guesses)
*/
/*This is the window size to use to avoid the aperture problem (see slide "Optical Flow: Overview")*/
int opticalFlowWindowSize = 21;
int pyramidLevel = 5;
CvSize optical_flow_window = cvSize(opticalFlowWindowSize, opticalFlowWindowSize);
cvCalcOpticalFlowPyrLK(frame1_1C, frame2_1C, pyramid1, pyramid2, frame1_features,
frame2_features, number_of_features, optical_flow_window, pyramidLevel,
optical_flow_found_feature, optical_flow_feature_error,
optical_flow_termination_criteria, 0) ;
vector<vector<Point>> afterRemoveBgrItemContours;
EliminateBgrLines(&contours, &afterRemoveBgrItemContours, frame1_features, frame2_features, optical_flow_found_feature);
DrawContours(afterRemoveBgrItemContours, "After Removing Bgr Contours"); //This function will draw the result contours
current_frame++;
if (current_frame >= number_of_frames - 1)
current_frame = 0;
detected_edges.release();
frame1_1C_Mat.release();
detected_edges.release();
cvReleaseImage(&frame1_1C);
cvReleaseImage(&frame2_1C);
cvReleaseImage(&eig_image);
cvReleaseImage(&temp_image);
cvReleaseImage(&pyramid1);
cvReleaseImage(&pyramid2);
} //End while(true)
delete []frame1_features;
delete []frame2_features;
delete []optical_flow_found_feature;
delete []optical_flow_feature_error;
}
我试过很多阈值,但都不能很好地消除噪声。
这是我尝试过的一些结果:
我尝试过许多其他阈值,但它仍然有很多噪音,有人可以告诉我改进算法以获得更好结果的方法吗?
非常感谢,
大同
最佳答案
Canny edges 不能为 Optical Flow 提供很好的特征。你应该试试名字很好的 goodFeaturesToTrack()相反。
关于c++ - 消除光流算法中的噪声?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18808791/
我编写了一些运行速度很慢的 VBA 代码。我的代码中有一系列不同的循环。我知道循环并不总是处理数据的最有效方式,所以我认为它们是问题所在。我需要有关如何更改或消除循环的想法,以便加快代码的运行时间。
我目前有一个网址:http://testsite.local/search/?q=findme一旦有人查询,我的搜索页面。我使用 mod_rewrite 重写了一些页面,想知道是否可以将其变成一个不错
有人可以帮助我执行一个查询,其中查询的重复元素被删除 Select * from table where APPNAME = 'Ap1' or APPNAME= 'Ap2' 使用 DISTINCT 的
我正在尝试在 ubuntu 上使用以下命令在一个文件夹中查找文件并通过 FFmpeg 提供并输出到另一个文件夹。问题是当它处理输出路径和文件名时,它添加了一个 .像这样的路径:/conversions
这个问题在这里已经有了答案: How can I remove all duplicates so that NONE are left in a data frame? (3 个答案) 关闭 1
我想证明以下定理: Theorem Frobenius (A: Set) (q: Prop) (p: A -> Prop) : (q \/ forall x : A, p x) -> (foral
我有一个 PHP 脚本,它只需要一些数据,将其分隔为制表符分隔格式,将其保存为 .xls 文件,然后为用户提供下载链接。 大多数情况下运行良好,但有些人正在获取导出的 .xls 文件的缓存版本。 我想
我有一个看起来有点像这个可重现代码的数据框,我想删除每列的异常值(在我们的例子中,数据点低于或高于平均值 2.5 个标准偏差)而不删除整个主题/行。 Subj mn + sd * 2.5) | (x
我正在尝试编写一个实现 fmap 的演示。在 Haskell 中与 continuation ,我的代码如下所示: #include #include template using Callba
在此 HighCharts例如,如何消除 xaxis 开始位置与 Jan 的刻度位置之间的差距。 http://jsfiddle.net/gh/get/jquery/1.7.2/highslide-s
重现步骤: 将TPanel添加到新的VCL表单并设置Align = alClient。 将 TSpeedButton 添加到面板,并将一些 bmp 图像分配给 Glyph 属性。 (可选,但更清晰:F
我得到一个 JavaScript 数组,其中包含一定数量(未指定)的各种元素(字符串、数字、 bool 值)。我需要消除字符串和 bool 值。我应该如何处理它?我应该使用typeof吗? 最佳答案
我正在寻找一个公式,可以消除字符串中空格后的空格和无用字符。 我的第一 react 是执行以下操作:=LEFT(A1,FIND("",A1)) 它适用于所有有空格的情况 但是如果单元格中没有空格,我的
我有以下问题:我正在尝试编写一个 Javascript 游戏,并且 Angular 色由箭头键控制。 问题是,当一个人按住按键时,在触发第一个按键和重复的按键之间存在短暂的延迟。 另外,当按下“向右箭
让我们考虑一个集合的集合,以及需要在管道内对内部集合的每个元素执行的操作。 为了简单起见,让它成为一个数组数组,操作简单的打印到屏幕上。为了表达我的问题,让我们还有一个元素不是集合的数组: $Arra
跟进this question关于包含源文件。我包括一个 Chapel 模块,其中包含一个名为 classes.chpl 的文件。 ,但我当前的项目也有一个 classes.chpl 。正确的消歧模式
我想知道如何在英特尔语法中的某些指令中区分标签名称和寄存器名称。例如,call rdx通常意味着间接跳转,但是如果我们在同一个汇编文件中有一个标签rdx怎么办?我相信它可以被解释为直接跳转到 rdx
据我了解,Chrome 会异步运行整个程序,这会导致我的扩展程序在单击后大约 2 秒后打开。有没有办法强制扩展程序显示带有“正在加载”消息的 html 页面,然后完成加载 javascript 并用内
我正在将 CSV 加载到 sqlite 数据库,如下所示: sqlite3 /path/to/output.db /dev/null 或者,您可以自己生成 SQL 命令,以便可以使用 INSERT 或
我的 .cabal 文件的许多节中经常有类似的属性。例如 Library x ... ghc-options: -O2 -Wall -fno-warn-missing-s
我是一名优秀的程序员,十分优秀!