日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

背景建模之单高斯实现

發布時間:2025/7/25 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 背景建模之单高斯实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

高斯分布與背景建模的關系:圖像中每一個像素點的顏色值作為一個隨機過程X,并假設該點的像素值出現的概率服從高斯分布。令I(x,y,t)表示像素點(x,y,t)在t時刻的像素值,則有:


其中和分別為t時刻該像素高斯分布的期望值和標準差。

算法流程:

1.用第一幀圖像數據初始化背景模型,其中std_init通常設置為20。




2.檢測前景與背景像素。

背景像素檢測公式:

前景像素檢測公式:

3.對、、背景值進行更新,更新公式如下:




4.返回到2直至停止。

算法實現代碼(vc6.0+opencv1.0):

// singleGaussian.cpp : Defines the entry point for the console application.

#include "stdafx.h"
#include <highgui.h>
#include <cv.h>
#include <math.h>
#include <cxcore.h>

int main(int argc, char* argv[])
{
//新建窗口
? ? cvNamedWindow("origin", CV_WINDOW_AUTOSIZE);
? ? cvNamedWindow("background", CV_WINDOW_AUTOSIZE);
? ? cvNamedWindow("foreground", CV_WINDOW_AUTOSIZE);


? ? double alpha = 0.05; ? ?//背景建模alpha值
? ? double std_init = 20; ? ?//初始標準差
? ? double var_init = std_init * std_init; ? ?//初始方差 ? ?
? ? double lamda = 2.5 * 1.2; ? ?//背景更新參數

? ? //視頻文件
? ? CvCapture *capture = NULL;
? ? //讀取視頻文件
? ? if (argc == 1)
? ? {
? ? ? ? //從攝像頭讀入
? ? ? ? capture = cvCreateCameraCapture(0);
? ? }
? ? else if (argc == 2)
? ? {
? ? ? ? //從文件讀入
? ? ? ? capture = cvCreateFileCapture(argv[1]);
? ? }
? ? else
? ? {
? ? ? ? //讀入錯誤
? ? ? ? printf("input error\n");
? ? ? ? return -1;
? ? }

? ? IplImage *frame = NULL; ? ? ? ?//原始圖像
? ? IplImage *frame_u = NULL; ? ?//期望圖像
? ? IplImage *frame_d = NULL; ? ?//前景圖像
? ? IplImage *frame_var = NULL; ? ?//方差圖像
? ? IplImage *frame_std = NULL; ? ?//標準差

? ? CvScalar pixel = {0}; ? ? ? ?//像素原始值
? ? CvScalar pixel_u = {0}; ? ? ? ?//像素期望
? ? CvScalar pixel_d = {0}; ? ? ? ?//像素前景
? ? CvScalar pixel_var = {0}; ? ?//像素方差
? ? CvScalar pixel_std = {0}; ? ?//像素標準差

? ? //初始化frame_u, frame_var, frame_std
? ? frame = cvQueryFrame(capture);
? ? frame_u = cvCreateImage(cvSize(frame->width, frame->height), IPL_DEPTH_8U, 3);
? ? frame_d = cvCreateImage(cvSize(frame->width, frame->height), IPL_DEPTH_8U, 3);
? ? frame_var = cvCreateImage(cvSize(frame->width, frame->height), IPL_DEPTH_8U, 3);
? ? frame_std = cvCreateImage(cvSize(frame->width, frame->height), IPL_DEPTH_8U, 3);

? ? for (int y = 0; y < frame->height; ++y)
? ? {
? ? ? ? for (int x = 0; x < frame->width; ++x)
? ? ? ? {
? ? ? ? ? ? pixel = cvGet2D(frame, y, x);
? ? ? ? ? ? pixel_u.val[0] = pixel.val[0];
? ? ? ? ? ? pixel_u.val[1] = pixel.val[1];
? ? ? ? ? ? pixel_u.val[2] = pixel.val[2];

? ? ? ? ? ? pixel_d.val[0] = 0;
? ? ? ? ? ? pixel_d.val[1] = 0;
? ? ? ? ? ? pixel_d.val[2] = 0;

? ? ? ? ? ? pixel_std.val[0] = std_init;
? ? ? ? ? ? pixel_std.val[1] = std_init;
? ? ? ? ? ? pixel_std.val[2] = std_init;

? ? ? ? ? ? pixel_var.val[0] = var_init;
? ? ? ? ? ? pixel_var.val[1] = var_init;
? ? ? ? ? ? pixel_var.val[2] = var_init;

? ? ? ? ? ? cvSet2D(frame_u, y, x, pixel_u);
? ? ? ? ? ? cvSet2D(frame_d, y, x, pixel_d);
? ? ? ? ? ? cvSet2D(frame_var, y, x, pixel_var);
? ? ? ? ? ? cvSet2D(frame_std, y, x, pixel_std);
? ? ? ? }
? ? }
? ? while (cvWaitKey(33) != 27) ? ? ? ?//按ESC鍵退出, 幀率33ms
? ? {
? ? ? ? frame = cvQueryFrame(capture);
? ? ? ? //視頻結束退出
? ? ? ? if (!frame)
? ? ? ? {
? ? ? ? ? ? break;
? ? ? ? }
? ? ? ? //單高斯背景更新
? ? ? ? for (int y = 0; y < frame->height; ++y)
? ? ? ? {
? ? ? ? ? ? for (int x = 0; x < frame->width; ++x)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? pixel = cvGet2D(frame, y, x);
? ? ? ? ? ? ? ? pixel_u = cvGet2D(frame_u, y, x);
? ? ? ? ? ? ? ? pixel_d = cvGet2D(frame_d, y, x);
? ? ? ? ? ? ? ? pixel_std = cvGet2D(frame_std, y, x);
? ? ? ? ? ? ? ? pixel_var = cvGet2D(frame_var, y, x);

? ? ? ? ? ? ? ? //|I-u| < lamda*std 時認為是背景, 進行更新
? ? ? ? ? ? ? ? if (fabs(pixel.val[0] - pixel_u.val[0]) < lamda * pixel_std.val[0] &&
? ? ? ? ? ? ? ? ? ? fabs(pixel.val[1] - pixel_u.val[1]) < lamda * pixel_std.val[1] &&
? ? ? ? ? ? ? ? ? ? fabs(pixel.val[2] - pixel_u.val[2]) < lamda * pixel_std.val[2])
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? //更新期望 u = (1-alpha)*u + alpha*I
? ? ? ? ? ? ? ? ? ? pixel_u.val[0] = (1 - alpha) * pixel_u.val[0] + alpha * pixel.val[0];
? ? ? ? ? ? ? ? ? ? pixel_u.val[1] = (1 - alpha) * pixel_u.val[1] + alpha * pixel.val[1];
? ? ? ? ? ? ? ? ? ? pixel_u.val[2] = (1 - alpha) * pixel_u.val[2] + alpha * pixel.val[2];


? ? ? ? ? ? ? ? ? ? //更新方差 var = (1-alpha)*var + alpha*(I-u)^2
? ? ? ? ? ? ? ? ? ? pixel_var.val[0] = (1 - alpha) * pixel_var.val[0] +
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (pixel.val[0] - pixel_u.val[0]) * (pixel.val[0] - pixel_u.val[0]);
? ? ? ? ? ? ? ? ? ? pixel_var.val[1] = (1 - alpha) * pixel_var.val[1] +
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (pixel.val[1] - pixel_u.val[1]) * (pixel.val[1] - pixel_u.val[1]);
? ? ? ? ? ? ? ? ? ? pixel_var.val[2] = (1 - alpha) * pixel_var.val[2] +
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (pixel.val[2] - pixel_u.val[2]) * (pixel.val[2] - pixel_u.val[2]);

? ? ? ? ? ? ? ? ? ? //更新標準差
? ? ? ? ? ? ? ? ? ? pixel_std.val[0] = sqrt(pixel_var.val[0]);
? ? ? ? ? ? ? ? ? ? pixel_std.val[1] = sqrt(pixel_var.val[1]);
? ? ? ? ? ? ? ? ? ? pixel_std.val[2] = sqrt(pixel_var.val[2]);

? ? ? ? ? ? ? ? ? ? //寫入矩陣
? ? ? ? ? ? ? ? ? ? cvSet2D(frame_u, y, x, pixel_u);
? ? ? ? ? ? ? ? ? ? cvSet2D(frame_var, y, x, pixel_var);
? ? ? ? ? ? ? ? ? ? cvSet2D(frame_std, y, x, pixel_std);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? else
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? pixel_d.val[0] = pixel.val[0] - pixel_u.val[0];
? ? ? ? ? ? ? ? ? ??pixel_d.val[1] = pixel.val[1] - pixel_u.val[1];
? ? ? ? ? ? ? ? ? ? pixel_d.val[2] = pixel.val[2] - pixel_u.val[2];
? ? ? ? ? ? ? ? ? ? cvSet2D(frame_d, y, x, pixel_d);
? ? ? ? ? ? ? ?}
? ? ? ? ? ? }
? ? ? ? }


? ? ? ? //顯示結果
? ? ? ? frame_u->origin = 1;
? ? ? ? frame_d->origin = 1;
? ? ? ? cvShowImage("origin", frame);
? ? ? ? cvShowImage("background", frame_u);
? ? ? ? cvShowImage("foreground", frame_d);
? ? }


? ? //釋放內存
? ? cvReleaseCapture(&capture);
? ? cvReleaseImage(&frame);
? ? cvReleaseImage(&frame_u);
? ? cvReleaseImage(&frame_var);
? ? cvReleaseImage(&frame_std);
? ? cvDestroyWindow("origin");
? ? cvDestroyWindow("background");
? ? cvDestroyWindow("foreground");


? ? return 0;
}

完善補充:

對于單高斯模型實現必須進行背景減除與陰影消除的處理,實用的模型還需要很多改進!此文僅供初學者研究。


參考鏈接:

http://underthehood.blog.51cto.com/2531780/484191

總結

以上是生活随笔為你收集整理的背景建模之单高斯实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。