- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
嘿,我正在做一个项目,通过使用光流法来稳定视频序列。到目前为止,我已经很好地完成了光流。但是我面前有 2 个分支机构可以处理它..1- 获得光流后,我找到了图像位移的平均值,然后我从第二帧的特征中减去平均值,我的问题是下一步该怎么做?
2- 或者我可以使用 openCV 函数来稳定图像,我计算了变换矩阵,然后我使用了 cvPerspectiveTransform,然后是 cvWarpPerspective,但是我得到了错误,这是“坏标志”
代码大家可以看看,我要的是怎么稳定图像呢?我想知道你们能提供什么解决方案吗?
enter code here
#include <stdio.h>
#include <stdlib.h>
//#include "/usr/include/opencv/cv.h"
#include <cv.h>
#include <cvaux.h>
#include <highgui.h>
#include <math.h>
#include <iostream>
#define PI 3.1415926535898
double rads(double degs)
{
return (PI/180 * degs);
}
CvCapture *cap;
IplImage *img;
IplImage *frame;
IplImage *frame1;
IplImage *frame3;
IplImage *frame2;
IplImage *temp_image1;
IplImage *temp_image2;
IplImage *frame1_1C;
IplImage *frame2_1C;
IplImage *eig_image;
IplImage *temp_image;
IplImage *pyramid1 = NULL;
IplImage *pyramid2 = NULL;
char * mapx;
char * mapy;
int h;
int corner_count;
CvMat* M = cvCreateMat(3,3,CV_32FC1);
CvPoint p,q,l,s;
double hypotenuse;
double angle;
int line_thickness = 1, line_valid = 1, pos = 0;
CvScalar line_color;
CvScalar target_color[4] = { // in BGR order
{{ 0, 0, 255, 0 }}, // red
{{ 0, 255, 0, 0 }}, // green
{{ 255, 0, 0, 0 }}, // blue
{{ 0, 255, 255, 0 }} // yellow
};
inline static double square(int a)
{
return a * a;
}
char* IntToChar(int num){return NULL;}
/*{
char* retstr = static_cast<char*>(calloc(12, sizeof(char)));
if (sprintf(retstr, "%i", num) > 0)
{
return retstr;
}
else
{
return NULL;
}
}*/
inline static void allocateOnDemand( IplImage **img, CvSize size, int depth, int channels )
{
if ( *img != NULL )
return;
*img = cvCreateImage( size, depth, channels );
if ( *img == NULL )
{
fprintf(stderr, "Error: Couldn't allocate image. Out of memory?\n");
exit(-1);
}
}
void clearImage (IplImage *img)
{
for (int i=0; i<img->imageSize; i++)
img->imageData[i] = (char) 0;
}
int main()
{
cap = cvCaptureFromCAM(0);
//cap = cvCaptureFromAVI("/home/saif/Desktop/NAO.. the project/jj/Test3.avi");
CvSize frame_size;
// Reading the video's frame size
frame_size.height = (int) cvGetCaptureProperty( cap, CV_CAP_PROP_FRAME_HEIGHT );
frame_size.width = (int) cvGetCaptureProperty( cap, CV_CAP_PROP_FRAME_WIDTH );
cvNamedWindow("Optical Flow", CV_WINDOW_AUTOSIZE);
while(true)
{
frame = cvQueryFrame( cap );
if (frame == NULL)
{
fprintf(stderr, "Error: Hmm. The end came sooner than we thought.\n");
return -1;
}
// Allocating another image if it is not allocated already.
allocateOnDemand( &frame1_1C, frame_size, IPL_DEPTH_8U, 1 );
cvConvertImage(frame, frame1_1C, 0);
allocateOnDemand( &frame1, frame_size, IPL_DEPTH_8U, 3 );
cvConvertImage(frame, frame1, 0);
//Get the second frame of video.
frame = cvQueryFrame( cap );
if (frame == NULL)
{
fprintf(stderr, "Error: Hmm. The end came sooner than we thought.\n");
return -1;
}
if(!frame)
{
printf("bad video \n");
exit(0);
}
allocateOnDemand( &frame2_1C, frame_size, IPL_DEPTH_8U, 1 );
cvConvertImage(frame, frame2_1C, 0);
allocateOnDemand( &frame2, frame_size, IPL_DEPTH_8U, 3 );
cvConvertImage(frame, frame2, 0);
CvSize optical_flow_window = cvSize(5,5);
eig_image = cvCreateImage( frame_size, IPL_DEPTH_32F, 1 );
temp_image = cvCreateImage( frame_size, IPL_DEPTH_32F, 1 );
CvTermCriteria optical_flow_termination_criteria = cvTermCriteria( CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, .3 );
// Feature tracking
CvPoint2D32f frame1_features[4];
CvPoint2D32f frame2_features[4];
//cvCornerEigenValsAndVecs(eig_image, temp_image, 1 );
corner_count = 4;
cvGoodFeaturesToTrack(frame1_1C,eig_image , temp_image, frame1_features, &corner_count, 0.1, .01, NULL, 5, 1);
cvFindCornerSubPix( frame1_1C, frame1_features, corner_count,cvSize(5, 5) ,optical_flow_window , optical_flow_termination_criteria);
if ( corner_count <= 0 )
printf( "\nNo features detected.\n" );
else
printf( "\nNumber of features found = %d\n", corner_count );
//Locus Kande method.
char optical_flow_found_feature[20];
float optical_flow_feature_error[20];
allocateOnDemand( &pyramid1, frame_size, IPL_DEPTH_8U, 1 );
allocateOnDemand( &pyramid2, frame_size, IPL_DEPTH_8U, 1 );
cvCalcOpticalFlowPyrLK(frame1_1C, frame2_1C, pyramid1, pyramid2, frame1_features, frame2_features, corner_count, optical_flow_window, 5, optical_flow_found_feature, NULL, optical_flow_termination_criteria, NULL);
/*
double sumOfDistancesX = 0;
double sumOfDistancesY = 0;
int debug = 0;
CvFont font1, font2;
CvScalar red, green, blue;
IplImage* seg_in = NULL;
IplImage *seg_out = NULL;
allocateOnDemand( &seg_in, frame_size, IPL_DEPTH_8U, 3 );
allocateOnDemand( &seg_out, frame_size, IPL_DEPTH_8U, 3 );
clearImage(seg_in);
clearImage(seg_in);
for( int i=0; i <corner_count; i++ )
{
if ( optical_flow_found_feature[i] == 0 )
continue;
p.x = (int) frame1_features[i].x;
p.y = (int) frame1_features[i].y;
q.x = (int) frame2_features[i].x;
q.y = (int) frame2_features[i].y;
angle = atan2( (double) p.y - q.y, (double) p.x - q.x );
sumOfDistancesX += q.x - p.x;
sumOfDistancesY += q.y - p.y;
//cvRemap(frame2,frame1,averageDistanceX , averageDistanceY,CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS, cvScalarAll(0));
}
*/
/*
int averageDistanceX = sumOfDistancesX / corner_count;
int averageDistanceY = sumOfDistancesY / corner_count;
l.x = averageDistanceX - q.x;
s.y = averageDistanceY - q.y;
*/
#define cvWarpPerspectiveQMatrix cvGetPerspectiveTransform
//CvMat* N = cvCreateMat(3,3,CV_32FC1);
cvGetPerspectiveTransform(frame2_features, frame1_features, M);
cvPerspectiveTransform(frame1_features, frame2_features, M);
cvWarpPerspective( frame2_features, frame1_features, M,CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS,cvScalarAll(0) );
cvShowImage("Optical Flow", frame1);
cvWaitKey(50);
}
cvReleaseCapture(&cap);
cvReleaseMat(&M);
return 0;
}
最佳答案
您不想从第二张图像中减去平均位移,而是希望通过平均位移转换(移动)第二张图像,使其“匹配”第一张图像。您使用的“位移”取决于您的情况。
编辑对于选项 2,您基本上需要做的是计算最后几帧帧之间平均移动的平均值。你可以通过多种方式做到这一点,但我建议使用卡尔曼滤波器之类的东西。然后,对于新帧,您可以计算该帧与(更正后的)前一帧之间的移动。从运动中减去到该点的平均运动,然后将新帧移动该差值。
关于c++ - 图像稳定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4247700/
如果输入稳定,我想触发 AJAX 请求(以便不在每个新字符后发送请求)。我尝试了以下方法: $('#input').keyup(function(){ // Get the value when
我读到,我们可以插入以将选择排序更改为稳定排序,而不是交换。我在网上得到了以下相同的实现。 void selection ( int a[], int n ) { while ( --n >
我正在尝试创建一个非常节省空间的不寻常的关联数组实现,我需要一个满足以下所有条件的排序算法: 稳定(不改变具有等键的元素的相对顺序。) 就地或几乎就地(O(log n) 堆栈很好,但没有 O(n) 空
我有一个节点的无线网状网络,每个节点都能够向其邻居报告其“距离”,以(简化的)信号强度来衡量。节点在地理上位于 3d 空间中,但由于 radio 干扰,节点之间的距离不需要在三角(三角?)上一致。即,
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我正在实现一个玩具调度程序,它读取进程规范(例如到达时间、总运行时间)的输入文件,然后根据随机 io/cpu 突发调度进程。 文件格式 Arrival time, total CPU time, CP
我正在使用 JRedis 的同步实现,但我打算切换到异步方式与 Redis 服务器通信。 但在此之前我想问一下社区 JRedisFuture 是否实现了 alphazero 的 jredis对于生产使
我们正在为我们的公司构建一个RESTful API,它将提供XML,JSON和可能的其他内容类型。 我的团队正在寻找一个框架(按优先顺序排列): 有据可查 理想的情况下,它具有出色的教程以及繁荣的社区
我的网站希望用户上传他们的照片...但我该如何保护我们的服务器免受伤害?只允许 JPG 应该可以避免病毒问题,但如果有人选择 10Gb 文件怎么办 - 这会减慢整个网站的速度吗? 我们使用的是经典 A
关闭。这个问题需要更多 focused .它目前不接受答案。 想改进这个问题?更新问题,使其仅关注一个问题 editing this post . 8 个月前关闭。 Improve this ques
据我所知,paintEvent() 是在 QApplication 对象的“主循环”中执行的,并且可以为其内部系统任务花费时间,从而延迟执行排队槽或其他事件。 但是,如果我需要播放非常流畅的动画并且我
我想对随机排序的 ActiveRecord 模型列表(来自 MySQL 数据库的行)进行分页。 但是,这种随机化需要在每个 session 的基础上持续存在,以便访问该网站的其他人也会收到一个随机的、
在 Flutter Web 稳定后,我尝试按照文档中给出的说明将我的 Flutter Mobile 应用程序转换为 Flutter Web。一切都很好,但这里的问题是 Web 上的文本不可选择!我刚刚
我正在尝试制作一个包含 Nginx stable 最新使用 vts 模块编译的 dockerfile .... 我遇到了一个大问题,当我放入将下载的 docker 文件时我找不到一些汽车链接安装最新的
已结束。此问题正在寻求书籍、工具、软件库等的推荐。它不满足Stack Overflow guidelines 。目前不接受答案。 我们不允许提出寻求书籍、工具、软件库等推荐的问题。您可以编辑问题,以便
我正在使用以下命令将 Airflow 部署到 Kubernetes 中:https://github.com/helm/charts/tree/master/stable/airflow 我正在尝
我已经安装了本地测试elasticsearch和logstash,它们似乎看不到本地es-知道在集群/ ns中如何看到es吗? helm repo add elastic https://helm.e
我最近加入了一家公司,担任发布工程师,在这里,大量的开发团队以各种语言开发了众多服务,应用程序和Web应用程序,它们之间具有各种相互依赖性。 我正在尝试找到一种简化并最好自动发布的方法。当前,发布团队
已结束。此问题正在寻求书籍、工具、软件库等的推荐。它不满足Stack Overflow guidelines 。目前不接受答案。 我们不允许提出寻求书籍、工具、软件库等推荐的问题。您可以编辑问题,以便
我想知道一种在 Windows 上使用简单批处理和 ffmpeg 稳定 goPro 视频的简单方法。 最佳答案 1) 在您的计算机上安装 ffmpeg:按照 steps 安装 2) 在您要处理的视频旁
我是一名优秀的程序员,十分优秀!