图像处理之前景检测(五)之基于样本一致性背景检测(SACON)

SACON(SAmple CONsensus)算法是基于样本一致性的运动目标检测算法。该算法通过对每个像素进行样本一致性判断来判定像素是否为背景。

具体原理参考:

Belial_2010      基于样本一致性的背景减除运动目标检测算法(SACON)(文献1)

Zhang_P_Y   【计算机视觉】基于样本一致性的背景减除运动目标检测算法(SACON)    (文献2)

C接口代码见:

星zai                   前景检测算法-SACON(SAMPLE CONSENSUS)

这里对于代码进行升级,函数对应进行替换为C++接口,环境为VS2015+opencv3.2 contrib版。

头文件:sacon.h

#include<iostream>
#include<opencv.hpp>
using namespace std;
using namespace cv;class SACON
{
public://SACON();// 构造函数,其中iteration表示样本的数目,也即用于学习的帧数N  SACON(Mat img, int iteration);/* Description:To implement the function to distinguish whether a pixel is foreground or backgroundand then update the background model */void Detect(Mat img);/* 设置当前像素是否为背景还是前景,即当前像素与背景样本比较,存在较大差异的数目该值与样本的数目gIteration相关,默认为gIteration*2*/void SetAlpha(double al) { gAlpha = al; }// 设置两个像素值的差异,默认为15  void SetValDiff(int ival) { valDiff = ival; }// 用于标记一个像素最多为  void SetTomTh(int Count) { Th_Tom = Count; }Mat getForeground() { return pForeImg; }//~SACON();
private:void InnerDetect(Mat img);// 填充前景区域的空洞,思想是填充,  void ValidateForeground(Mat foreImg);Mat* pBkImgArr;Mat pForeImg;Mat pPreImg;Mat pGray;Mat pDiffImg;int gHeight;int gWidth;//Size gSize;int gIteration;int frmNum;int valDiff; // 两个像素值的差异  double gAlpha;//the value that determines a pixel whether a foreground or background  int **Tom; //用来记录一个像素被连续判为前景的次数  int Th_Tom; // 用于标记一个像素最多为前景的次数,默认为100
};

算法函数:sacon.cpp

#include<iostream>
#include<opencv.hpp>
#include"sacon.h"
using namespace std;
using namespace cv;
SACON::SACON(Mat img, int iteration)
{frmNum = 0;Th_Tom = 10;gHeight = img.rows;gWidth = img.cols;gIteration = iteration;gAlpha = gIteration*2; // 值的设置还有待商榷  //gSize = cvGetSize(img);//pForeImg = cvCreateImage(gSize, 8, 1);Mat x(img.rows, img.cols, CV_8UC1);pForeImg=x.clone();//pGray = cvCreateImage(gSize, 8, 1);//Mat y(img.rows, img.cols, CV_8UC1);pGray = x.clone();//pPreImg = cvCreateImage(gSize, 8, 3);Mat u(img.rows, img.cols, CV_8UC3);pPreImg = u.clone();//pDiffImg = cvCreateImage(gSize, 8, 3);//Mat z(img.rows, img.cols, CV_8UC3);pDiffImg = u.clone();int i = 0, j = 0;Tom = new int *[gHeight];for (i = 0; i<gHeight; i++){Tom[i] = new int[gWidth];for (j = 0; j<gWidth; j++){Tom[i][j] = 0;}}//pBkImgArr = new IplImage*[gIteration];pBkImgArr = new Mat[gIteration];for (i = 0; i<gIteration; i++){pBkImgArr[i] = u.clone();}img.copyTo(pBkImgArr[frmNum]);frmNum++;
}
// 实现前景检测,如果学习没完,则继续进行学习
void SACON::Detect(Mat img)
{if (frmNum<gIteration){img.copyTo(pBkImgArr[frmNum]);frmNum++;if (frmNum == gIteration){img.copyTo(pPreImg);}}else{InnerDetect(img);ValidateForeground(pForeImg);}
}
// 实现前景检测,并进行背景更新
void SACON::InnerDetect(Mat img)
{//cvZero(pForeImg);//cvZero(pGray);Mat x(pForeImg.rows, pForeImg.cols, CV_8UC1, Scalar(0));x.copyTo(pForeImg);x.copyTo(pGray);absdiff(img, pPreImg, pDiffImg);cvtColor(pDiffImg, pGray, CV_BGR2GRAY);threshold(pGray, pGray, 20, 255, CV_THRESH_BINARY);img.copyTo(pPreImg);//(个人理解,不一定对)这里的这句代码是更新背景,如果有这句代码的话,相当于用帧差法检测运动像素,出来的结果仅仅是运动模型的轮廓,后续要用blob-level方法,进行轮廓填充,这个方法还没有具体思路。int i = 0, j = 0, k = 0, p = 0;int cnt = 0, iTom;Scalar cs0, cs1, cs2, cs3;//cs3.val[0] = 255;cs3.val[0] = 255;for (i = 0; i<gHeight; i++){for (j = 0; j<gWidth; j++){cs0 = pGray.at<uchar>( i, j);if (cs0.val[0] == 255){cs1 = img.at<Vec3b>(i, j);cnt = 0;for (k = 0; k<gIteration; k++){//cs2 = cvGet2D(pBkImgArr[k], i, j);cs2 = pBkImgArr[k].at<Vec3b>(i, j);for (p = 0; p<3; p++){if (fabs(cs1.val[p] - cs2.val[p])>valDiff){cnt++;}}}//与背景比较完成  if (cnt>gAlpha){iTom = Tom[i][j];if (iTom>Th_Tom) // 如果当前像素为前景的次数超过Th_Tom,则判为背景  {Tom[i][j] = 0;  // 怎么更新背景  }else{Tom[i][j]++;//cvSet2D(pForeImg, i, j, cs3);pForeImg.at<uchar>(i, j)=cs3.val[0];}}}else{continue;}}}
}
void SACON::ValidateForeground(Mat foreImg)
{// 膨胀腐蚀的默认结构元素是3×3的长方形  dilate(foreImg, foreImg,9);erode(foreImg, foreImg, 9);/*int i=0,j=0,p=0,q=0;int cnt;CvScalar cs0,cs;cs.val[0]=255;for (i=1;i<gHeight-1;i++){for (j=1;j<gWidth-1;j++){cnt=0;for (p=i-1;p<=i+1;p++){for(q=j-1;q<=j+1;q++){cs0=cvGet2D(foreImg,p,q);if (cs0.val[0]==255){cnt++;}}}if (cnt>5){cvSet2D(foreImg,i,j,cs);}}}*/
}

主函数:main.cpp

#include<iostream>
#include<opencv.hpp>
#include"sacon.h"
using namespace std;
using namespace cv;
int main()
{namedWindow("Raw");namedWindow("sacon");VideoCapture cap ("E://素材//2.mp4");//VideoCapture cap (0);Mat frame;cap >> frame;SACON sacon(frame, 30);//  // 开始处理视频每一帧图像  for (int i = 0;; i++){cap >> frame;//SACON sacon;if (frame.empty() == 1)return 1;//if (i == 450)//waitKey(0);sacon.Detect(frame);Mat m=sacon.getForeground();//sacon.(rawImage, 30);//sacon.Detect(rawImage);imshow("Raw", frame);imshow("sacon", m);//cvShowImage("sacon", saconmask);waitKey(10);}return 0;
}

运行结果:

这里的运行结果较之前的算法来看,稍微有些奇怪,这里检测出来的更像是运动物体的轮廓,轮廓包含的像素没有检测出来,这里(可能是)与算法的原理相关,因为sacon算法第一步提取活动像素采取的是类似帧差的方法,对于运动速度不快的目标,轮廓内像素差分消除掉了,所以显示不出来。这里(文献2)中提到的pixel_level的问题,后续的像素填充要用到Blob_level的算法,算法原论文中没有提到具体对策,这篇代码中也没有相应的解决方法,所以是这样的结果。

文献(2)提及相应问题:

图像处理之前景检测(五)之基于样本一致性背景检测(SACON)(主要为代码升级)相关推荐

  1. 图像处理之前景检测(四)之自组织背景检测(SOBS)(转载)

    图像处理之前景检测(四)之自组织背景检测(SOBS)(转载)        一种基于自组织神经网络(self-Organizing through artificial neural networks ...

  2. matlab 零速检测,一种基于车辆零速检测的惯性导航误差修正方法与流程

    本发明涉及车载导航与定位领域,尤其是涉及一种基于车辆零速检测的惯性导航误差修正方法. 背景技术: 惯性导航系统(inertialnavigationsystem,ins)能根据惯性传感器(陀螺仪.加速 ...

  3. 【OpenCV图像处理入门学习教程五】基于背景差分法的视频目标运动侦测

    OpenCV图像处理入门学习教程系列,上一篇第四篇:基于LoG算子的图像边缘检测 运动目标检测 关于运动目标检测的方法总结,目前能够实现运动物体检测的方法主要有以下几种: 1)背景差分法:能完整快速地 ...

  4. 单片机c语言检测压力值,基于单片机的压力检测系统设计论文.doc

    摘要 压力是工业生产过程中的重要参数之一.压力的检测或控制是保证生产和设备安全运行必不可少的条件.本设计主要通过单片机及专用芯片对传感器所测得的模拟信号进行处理,使其完成智能化功能V/F转换芯片,由其 ...

  5. 多人脸检测matlab程序,基于肤色的人脸检测matlab代码

    main close all clear all clc % 输入图像名字 img_name = input('请输入图像名字(图像必须为RGB图像,输入0结束):','s'); % 当输入0时结束 ...

  6. 【图像检测-边缘检测】基于遗传算法的边缘检测算法研究附matlab代码

    ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信.

  7. 混凝土裂缝检测专题(2)裂缝检测技术(基于图像处理的)

    裂缝检测技术-基于图像处理 1.基于阔值分割的裂缝检测方法 2.基于形态学的裂缝检测方法 3.基于区域生长的裂缝检测方法 4.基于渗流模型的裂缝检测方法 5.基于小波变换的裂缝检测算法 6.基于神经网 ...

  8. 基于语音的疲劳度检测算法研究

    基于语音的疲劳度检测算法研究 摘 要 疲劳是一种自然现象,是人体的一种自我调节和保护功能.检测疲劳状态对于当今社会从事各行各业都有积极意义.本课题提出了一种基于语音特征参数和概率神经网络的语音疲劳度识 ...

  9. 【PaddleOCR-det-finetune】一:基于PPOCRv3的det检测模型finetune训练

    文章目录 基本流程 详细步骤 打标签,构建自己的数据集 下载PPOCRv3训练模型 修改超参数,训练自己数据集 启动训练 导出模型 测试 相关参考手册在PaddleOCR项目工程中的位置: det模型 ...

最新文章

  1. BZOJ4491: 我也不知道题目名字是什么
  2. 数组传参中形参的秘密,以及数组名当作函数实际参数的特点,以及二维数组,以及外部变量和全局变量
  3. 【拔刀吧少年】之循环三兄弟for while until
  4. Maven(5)--常用插件
  5. android人脸识别demo_零门槛解决Windows人脸识别应用开发难题
  6. android 模拟器声音设置,使用android模拟器录制声音
  7. 在GNS3中如何让NETFLOW能够捕获到流量
  8. Python入门学习笔记(9)
  9. matlab 释放变量,怎么能释放已经使用的内存
  10. UBUNTU使用五笔98输入法
  11. Opencv LBP特征
  12. 引汉济渭:再续秦人治水神话_陕南赤子_新浪博客
  13. 网络数据采集分析工具tcpdump定义抓包过滤器
  14. Kafka原理——fabric1.0版本中的节点排序方法
  15. http://blog.csdn.net/congcong68/article/details/39256307
  16. 【LaTex】基础语法框架快速入门教程——Tex live+TexStudio简要安装及使用教程
  17. 微软再曝“丑闻”:在办公室看 VR 黄片,“HoloLens 之父”即将离职!
  18. Arduino Cloud 现已支持乐鑫 ESP32-S2、S3 和 C3
  19. Vue 官网学习笔记
  20. Could not set property ‘id‘ of ‘class com.example.demo.entity.User‘ with value ‘1488484032207781890‘

热门文章

  1. 新版陀螺世界app源码附视频教程
  2. 云e办学习笔记(三十三)FastDFS学习和安装
  3. 专业的选择 人生的方向
  4. MySQL进阶:sql性能分析
  5. 【转】小科普|FET、 MOSFET、 MESFET、 MODFET的区别
  6. 【python标准库】os.path详解
  7. 零售行业常见数据分析简介
  8. 你喝过LGG益生菌酸奶了吗?
  9. 计算机毕业论文java毕业设计论文题目ssm项目源码水果商城系统电商购物项目[包运行成功]
  10. 记华为AP3010DN-AGN胖转瘦过程 AP版本升级