5iMX宗旨:分享遥控模型兴趣爱好

5iMX.com 我爱模型 玩家论坛 ——专业遥控模型和无人机玩家论坛(玩模型就上我爱模型,创始于2003年)
查看: 1693|回复: 16
打印 上一主题 下一主题

网上发现了一个比较好的代码,有用的朋友可以做来试试看

[复制链接]
跳转到指定楼层
楼主
发表于 2010-3-1 15:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
运用klman对视频中的移动物体跟踪,程序是用来处理事先录好的视频,移动物体的初始坐标也知道,会改的朋友可以把它叠加到我们的FPV返回视频中,那样效果我想回更好的哦!


#include <stdio.h>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <iostream>
using namespace std;


int main( int argc, char** argv )
{
IplImage* pFrame = NULL;

IplImage* pFrImg = NULL;

IplImage* pBkImg = NULL;

    //定义一个模板
IplImage* MBImg = NULL;
int MBSIZE=20;
//初始坐标,模板中心点
int state_ptxy[]={230,70};
    CvCapture* pCapture = NULL;

    int nFrmNum = 0;

     cvNamedWindow("video", 1);
//klman的设置
CvKalman* kalman = cvCreateKalman( 2, 2, 0 );

    CvMat* measurement = cvCreateMat( 2, 1, CV_32FC1 );

const float A[] = { 1, 0, 0, 1};

    memcpy( kalman->transition_matrix->data.fl, A, sizeof(A));

    cvSetIdentity( kalman->measurement_matrix, cvRealScalar(1) );

    cvSetIdentity( kalman->process_noise_cov, cvRealScalar(1e-5) );

    cvSetIdentity( kalman->measurement_noise_cov, cvRealScalar(0.00001) );

    cvSetIdentity( kalman->error_cov_post, cvRealScalar(1));

//初始化x(0)
    kalman->state_post->data.fl[0]=state_ptxy[0];     

    kalman->state_post->data.fl[1]=state_ptxy[1];
pCapture=cvCaptureFromFile("test.avi");
if(pCapture==0)
{
   cout<<"不能打开视频"<<endl;
}


//逐帧读取视频

while(pFrame = cvQueryFrame( pCapture ))

{

  
   nFrmNum++;       //如果是第一帧,需要申请内存,并初始化  

   if(nFrmNum == 1)
   {   
    pFrImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);

        MBImg = cvCreateImage(cvSize(MBSIZE,MBSIZE), IPL_DEPTH_8U,1);
            //控制图像是否倒转的
            pFrImg->origin = pFrame->origin;
      MBImg->origin = pFrame->origin;
    cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY); //将pFrImg转为灰度图
   

    //获取一个模板矩阵
          for(int row=0;row<MBSIZE;row++)
     for(int col=0;col<MBSIZE;col++)
      CV_IMAGE_ELEM( MBImg,unsigned char, row, col )=
                         CV_IMAGE_ELEM(pFrImg,unsigned char, state_ptxy[1]-MBSIZE/2+row,state_ptxy[0]-MBSIZE/2+col);
             //保存模板与第一帧图像
           cvSaveImage("mb.jpg",MBImg);
          cvSaveImage("first.bmp",pFrImg);
         

   }
   else
   {
    cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);
    //klman预测     

            const CvMat* prediction = cvKalmanPredict( kalman, 0 );

            CvPoint predict_pt = cvPoint(cvRound(prediction->data.fl[0]),cvRound(prediction->data.fl[1]));

  

  

     //测量
     // 运用模板匹配,找出最相近
      CvPoint measurement_pt = cvPoint(0,0);

    CvSize sizeMBImg = cvGetSize(MBImg);
            CvSize sizepFrImg = cvGetSize(pFrImg);
    double min_val,max_val;
            CvPoint min_loc;
          CvPoint max_loc;
         CvSize sizeResult = cvSize(sizepFrImg.width-sizeMBImg.width+1,sizepFrImg.height-sizeMBImg.height+1);
    IplImage* imgResult = cvCreateImage(sizeResult,IPL_DEPTH_32F,1);
  
    cvMatchTemplate(pFrImg,MBImg,imgResult,CV_TM_CCORR_NORMED);
            cvMinMaxLoc(imgResult, &min_val, &max_val,& min_loc,& max_loc, 0 );
    //得到测量点坐标
      measurement_pt.x=max_loc.x+MBSIZE/2;
      measurement_pt.y=max_loc.y+MBSIZE/2;
  

      measurement->data.fl[0]=measurement_pt.x;
      measurement->data.fl[1]=measurement_pt.y;

         //调整klman的状态
           cvKalmanCorrect( kalman, measurement);
    CvPoint post_pt=cvPoint(cvRound(kalman->state_post->data.fl[0]),cvRound(kalman->state_post->data.fl[1]));
   
    //画点
            #define draw_cross( center, color, d )                                 \
        cvLine( pFrame, cvPoint( center.x - d, center.y - d ),                \
        cvPoint( center.x + d, center.y + d ), color, 1, CV_AA, 0); \
        cvLine( pFrame, cvPoint( center.x + d, center.y - d ),                \
    cvPoint( center.x - d, center.y + d ), color, 1, CV_AA, 0 )
    // draw_cross( predict_pt, CV_RGB(255,255,0), 5 );   //画出预测点 黄点
    draw_cross(measurement_pt, CV_RGB(255,0,0), 5 ); //画测量点 红点
    draw_cross(cvPoint(cvRound(kalman->state_post->data.fl[0]),
                   cvRound(kalman->state_post->data.fl[1])),CV_RGB(0,255,0), 5); //画矫正点,绿点
   
            printf("测量点坐标: %d,%d\n", measurement_pt.x,measurement_pt.y);
    printf("预测点坐标:%d,%d\n", predict_pt.x, predict_pt.y);
    printf("矫正点坐标:%d,%d\n ",post_pt.x,post_pt.y);
    printf("相关系数最大值:%f\n\n",max_val);

    cvShowImage("video", pFrame);   

    if( cvWaitKey(2) >= 0 )  

     break;
   }

}


//销毁窗口

cvDestroyWindow("video");

//释放图像和矩阵

cvReleaseImage(&pFrImg);

cvReleaseImage(&MBImg);

cvReleaseCapture(&pCapture);

cvReleaseKalman(&kalman);
return 0;

}

欢迎继续阅读楼主其他信息

沙发
发表于 2010-3-1 15:05 | 只看该作者
跟踪移动的目标?!:em13: 如果真行的话,岂不是可以做dao dan了,还是图像识别的!
3
 楼主| 发表于 2010-3-1 15:07 | 只看该作者
哈哈!不是那个意思哦!这个代码只是读取已经录制好的视频,当然大家可以进行修改制作成跟踪xx目标的那种,那样用FPV飞起来追踪飞机就更容易了哦!
4
 楼主| 发表于 2010-3-1 15:14 | 只看该作者
还有一种可以直接跟踪物体的机器人这个功能也能利用到FPV项目,大家伙也看看吧!
5
发表于 2010-3-1 16:25 | 只看该作者
哇,太先进了吧,感觉好爽。但是我怕用在飞机上如果移动物体的速度太慢了,那飞机不是要失速了?还有跟随的距离问题~~!
6
发表于 2010-3-1 16:26 | 只看该作者
好中意个机器人:em26:
7
发表于 2010-3-1 17:03 | 只看该作者
不懂原理,但好像是3个超声波探头:em13:
8
发表于 2010-3-1 17:41 | 只看该作者
真好玩。
9
发表于 2010-3-1 18:51 | 只看该作者
3个超声传感器检测移动的物体,然后进行反应。单片机编程,呵呵不错
10
发表于 2010-3-1 18:57 | 只看该作者
很适合多机编队:em15:
11
发表于 2010-3-1 20:47 | 只看该作者
每秒20帧的画面,信息量是很大的,单片机恐怕难以胜任,最起码也要DSP
还有就是,当平台更换后原有的软件包能否使用还是个问题
12
发表于 2010-3-1 23:14 | 只看该作者
记得92年刚毕业时做过汉字识别
那时是黑白X-Y轴方向分别做隔行扫描去样
再统计分布图
对照还字编码库识别
数据量并不大
用8位机24点X24点阵
3字节X24行=74字节
13
发表于 2010-3-1 23:23 | 只看该作者
录像中的应该更简单
3个传感器取样三个
状态码:000-111
1.0-0-0:没有
2.0-0-1:居左
3.0-1-0:居中
4.0-1-1:中左
5.1-0-0:居右
6.1-0-1:两个
7.1-1-0:中右
8.1-1-1:超大
14
发表于 2010-3-1 23:24 | 只看该作者
距离随动应该是用闭环模拟的信号
15
发表于 2010-3-2 08:15 | 只看该作者

这不就是个倒车雷达么

这不就是个倒车雷达么
16
发表于 2010-3-2 08:19 | 只看该作者
哦,高手啊
17
发表于 2010-3-5 09:31 | 只看该作者
:em23: 我只会C#
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

关闭

【站内推荐】上一条 /1 下一条

快速回复 返回顶部 返回列表