zoukankan      html  css  js  c++  java
  • 平均场景法分割前景目标

    基本思路:计算每个像素的平均值和标准差作为它的背景模型,利用已建立的背景模型对图像进行背景差分分割出前景目标。

      1 #include "stdafx.h"
      2 #include "cv.h"
      3 #include "highgui.h"
      4 
      5 IplImage *IavgF,* IdiffF, *IprevF, *IhiF, *IlowF;
      6 
      7 IplImage *Iscratch,*Iscratch2;
      8 
      9 IplImage *Igray1,*Igray2,*Igray3;
     10 IplImage *Ilow1,*Ilow2,*Ilow3;
     11 IplImage *Ihi1,*Ihi2,*Ihi3;
     12 
     13 IplImage *Imaskt;
     14 float Icount;            //累积的帧数
     15 
     16 //初始化图像
     17 void AllocateImages(CvSize sz)
     18 {
     19     IavgF=cvCreateImage(sz,IPL_DEPTH_32F,3);
     20     IdiffF=cvCreateImage(sz,IPL_DEPTH_32F,3);
     21     IprevF=cvCreateImage(sz,IPL_DEPTH_32F,3);
     22     IhiF=cvCreateImage(sz,IPL_DEPTH_32F,3);
     23     IlowF=cvCreateImage(sz,IPL_DEPTH_32F,3);
     24     Ilow1=cvCreateImage(sz,IPL_DEPTH_32F,1);
     25     Ilow2=cvCreateImage(sz,IPL_DEPTH_32F,1);
     26     Ilow3=cvCreateImage(sz,IPL_DEPTH_32F,1);
     27     Ihi1=cvCreateImage(sz,IPL_DEPTH_32F,1);
     28     Ihi2=cvCreateImage(sz,IPL_DEPTH_32F,1);
     29     Ihi3=cvCreateImage(sz,IPL_DEPTH_32F,1);
     30     cvZero(IavgF);
     31     cvZero(IdiffF);
     32     cvZero(IprevF);
     33     cvZero(IhiF);
     34     cvZero(IlowF);
     35     Icount=0.00001;
     36 
     37     Iscratch=cvCreateImage(sz,IPL_DEPTH_32F,3);
     38     Iscratch2=cvCreateImage(sz,IPL_DEPTH_32F,3);
     39     Igray1=cvCreateImage(sz,IPL_DEPTH_32F,1);
     40     Igray2=cvCreateImage(sz,IPL_DEPTH_32F,1);
     41     Igray3=cvCreateImage(sz,IPL_DEPTH_32F,1);
     42     Imaskt=cvCreateImage(sz,IPL_DEPTH_8U,1);
     43     cvZero(Iscratch);
     44     cvZero(Iscratch2);
     45 }
     46 
     47 //累积每一帧图像
     48 void accumulateBackground(IplImage* I)
     49 {
     50     static int first=1;
     51     cvCvtScale(I,Iscratch,1,0);        
     52     if(!first)
     53     {
     54         cvAcc(Iscratch,IavgF);
     55         cvAbsDiff(Iscratch,IprevF,Iscratch2);
     56         cvAcc(Iscratch2,IdiffF);
     57         Icount+=1.0;
     58     }
     59     first=0;
     60     cvCopy(Iscratch,IprevF);
     61 }
     62 
     63 //设置阈值,IdiffF*scale+IavgF=IhiF
     64 void setHighThreshold(float scale)
     65 {
     66     cvConvertScale(IdiffF,Iscratch,scale);
     67     cvAdd(Iscratch,IavgF,IhiF);
     68     cvSplit(IhiF,Ihi1,Ihi2,Ihi3,0);
     69 }
     70 
     71 //设置阈值,IavgF-IdiffF*scale=IlowF
     72 //位于IlowF和IhiF之间的为背景,其外的为前景
     73 void setLowThreshold(float scale)
     74 {
     75     cvConvertScale(IdiffF,Iscratch,scale);
     76     cvSub(IavgF,Iscratch,IlowF);
     77     cvSplit(IlowF,Ilow1,Ilow2,Ilow3,0);
     78 }
     79 
     80 //计算视频中每个像素的均值和方差
     81 void createModelsfromStats()
     82 {
     83     cvConvertScale(IavgF,IavgF,(double)(1.0/Icount));
     84     cvConvertScale(IdiffF,IdiffF,(double)(1.0/Icount));
     85 
     86     cvAddS(IdiffF,cvScalar(1.0,1.0,1.0),IdiffF);
     87     setHighThreshold(7.0);
     88     setLowThreshold(6.0);
     89 }
     90 
     91 //根据建立的平均背景模型分割出图像的前景和背景
     92 //将分割结果转变成掩模图像Imask,在任何通道上非常大的差别都可认为是前景像素
     93 void backgroundDiff(IplImage* I,IplImage* Imask)     //Imask为单通道8位图像
     94 {
     95     cvCvtScale(I,Iscratch,1,0);
     96     cvSplit(Iscratch,Igray1,Igray2,Igray3,0);
     97 
     98     cvInRange(Igray1,Ilow1,Ihi1,Imask);
     99 
    100     cvInRange(Igray2,Ilow2,Ihi2,Imask);
    101     cvOr(Imask,Imaskt,Imaskt);
    102 
    103     cvInRange(Igray3,Ilow3,Ihi3,Imask);
    104     cvOr(Imask,Imaskt,Imaskt);
    105 
    106     cvSubRS(Imask,cvScalar(255),Imask);      //白为前景,黑为背景  
    107 }
    108 
    109 void DeallocateImages()
    110 {
    111     cvReleaseImage(&IavgF);
    112     cvReleaseImage(&IdiffF);
    113     cvReleaseImage(&IprevF);
    114     cvReleaseImage(&IhiF);
    115     cvReleaseImage(&IlowF);
    116     cvReleaseImage(&Ilow1);
    117     cvReleaseImage(&Ilow2);
    118     cvReleaseImage(&Ilow3);
    119     cvReleaseImage(&Ihi1);
    120     cvReleaseImage(&Ihi2);
    121     cvReleaseImage(&Ihi3);
    122     cvReleaseImage(&Iscratch);
    123     cvReleaseImage(&Iscratch2);
    124     cvReleaseImage(&Imaskt);
    125 }
    126 
    127 int main()
    128 {
    129     CvCapture* capture=cvCreateFileCapture("C:/Users/shark/Desktop/eagle.flv");
    130     //CvCapture* capture=cvCreateCameraCapture(0);
    131     IplImage* frame=NULL;
    132     cvNamedWindow("frame");
    133     cvNamedWindow("Imask");
    134     if(capture)
    135     {
    136         int width=(int)cvGetCaptureProperty(capture,CV_CAP_PROP_FRAME_WIDTH);
    137         int height=(int)cvGetCaptureProperty(capture,CV_CAP_PROP_FRAME_HEIGHT);
    138         CvSize size=cvSize(width,height);
    139 
    140         AllocateImages(size);
    141         IplImage* Imask=cvCreateImage(size,IPL_DEPTH_8U,1);           //要输出的掩模图像
    142         frame=cvQueryFrame(capture);                               //用摄像头获取视频时第一帧为空    
    143         for(int i=0;;i++)
    144         {
    145             if(!(frame=cvQueryFrame(capture)))
    146                 break;
    147             cvShowImage("frame",frame);
    148             if(i<=30)                                    //对前30帧进行训练
    149             {
    150                 accumulateBackground(frame);            //累积图像
    151                 if(i==30)
    152                     createModelsfromStats();            //构建平均背景模型            
    153             }
    154             else
    155             {
    156                 backgroundDiff(frame,Imask);                //分割图像
    157                 cvShowImage("Imask",Imask);
    158             }
    159             if(cvWaitKey(30)==27)
    160                 break;
    161         }
    162 
    163         DeallocateImages();
    164         cvReleaseImage(&Imask);
    165         cvDestroyAllWindows();
    166         return 0;
    167     }
    168     else
    169         return -1;
    170 }

    经实验发现对一般的视频,要调整训练的帧数和阈值等参数才有可能对前景目标实现较好的分割;对摄像头获取的视频分割效果还比较好。光线的变化对分割结果影响较大

    下一篇将实现codebook法训练背景模型来分割前景目标,与之作为比较。

  • 相关阅读:
    Swiper 自定义分页器 并实现多个用省略号显示
    Swiper插件 滚动自动切换标题
    HTML 点击返回按钮返回上一页,没有上一页转到首页
    HTML input 模仿Android原生焦点效果
    HTML基础篇(二、HTML文档结构)
    Vue开发 添加微信分享功能(全局分享)
    JS 命令模式(记读《JavaScript设计模式与开发实践》笔记)
    Vue中v-for配合使用Swiper插件问题
    permission-sudo获取权限
    使用es6模块化后打开页面报错
  • 原文地址:https://www.cnblogs.com/luckyboylch/p/5003643.html
Copyright © 2011-2022 走看看