基于OPENCV的背景减除方法

基于OPENCV的背景减除方法 

2009-04-27 14:59:32|  分类: openCV |  标签: |字号 订阅

//经实验发现,用背景减除方法也可以针对某些摄像机运动的情况,而非像大部分文章中所提到的该方法仅仅适合于摄像机静止的情况,而且效果还要较好!!

/*
*建立多高斯背景模型
*/
void CMotionAnalysisPlatformView::OnBackgdiff()
{
    // TODO: Add your command handler code here
    IplImage* tmp_frame = 0;
    IplImage* dst = 0;

    if(!m_capture)
    {
        MessageBox("读取视频文件失败,请重新打开真彩色(24位)视频!", "错误信息");
        return;
    }

tmp_frame = cvQueryFrame(m_capture);
dst = cvCreateImage(cvGetSize(tmp_frame), 8, 1);
dst->origin = 1;

    if(!tmp_frame)
    {
        MessageBox("读取视频文件失败,请重新打开真彩色(24位)视频!", "错误信息");
        return;
    }
    cvNamedWindow("背景图像", 1);
    cvNamedWindow("前景图像", 1);

  //创建多高斯模型
    CvBGStatModel* bg_model = cvCreateGaussianBGModel(tmp_frame); 

    for( int fr = 1;tmp_frame; tmp_frame = cvQueryFrame(m_capture), fr++ )
{
  //printf("frame# %d : ", fr);
  //获得背景模型更新过程所花费的时间,以 CPU时钟/每微秒 为单位计数
  //double t = (double)cvGetTickCount();  //模型更新之前
       
    cvUpdateBGStatModel( tmp_frame, bg_model ); 
//真正的函数实现体是在: icvUpdateFGDStatModel(tmp_frame, bg_model)
       
// t = (double)cvGetTickCount() -  t;    //模型更新之后

// 以左下角为坐标原点
bg_model->foreground->origin = bg_model->background->origin = 1;

//cvErode(bg_model->background, bg_model->background); 
//滤除噪声
//cvErode(bg_model->foreground, bg_model->foreground);   
//滤除噪声

//printf( "%.1f毫秒n", t/(cvGetTickFrequency()*1000.) );
//最后输出结果以毫秒为单位
    cvShowImage("背景图像", bg_model->background);
    cvCopy(bg_model->foreground, dst);
    cvSmooth(dst, dst, CV_GAUSSIAN, 5);
    cvMorphologyEx( dst, dst, 0, 0, CV_MOP_CLOSE, 3);
    cvMorphologyEx( dst, dst, 0, 0, CV_MOP_OPEN, 1 );
//提取轮廓 到contour序列中
//cvFindContours 仅能处理 [单通道、颜色深度为8位的图像] 的轮廓提取
    cvFindContours( dst,
  m_storage, &m_contour, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));

    for( ; m_contour != 0; m_contour = m_contour->h_next )
    {
          CvScalar color = CV_RGB( 255, 0, 255 );
          CvScalar color_rect = CV_RGB( 0, 255, 255);           
             
  m_contour_rect = cvBoundingRect(m_contour, 1);

/*if(m_contour_rect.height + m_contour_rect.width > 100 && m_contour_rect.width * m_contour_rect.height > 20 && m_contour_rect.height/m_contour_rect.width > 1.5)
*/
if(fabs(cvContourArea(m_contour)) > 500.0)
{
cvRectangle(dst, cvPoint(m_contour_rect.x, m_contour_rect.y),          cvPoint((m_contour_rect.x + m_contour_rect.width),(m_contour_rect.y + m_contour_rect.height)),  color_rect,  2, 8,  0); 

/* replace CV_FILLED with 1 to see the outlines */ 
    cvDrawContours( dst, m_contour, color, color, -1, CV_FILLED, 8, cvPoint(0,0));
          cvShowImage("前景图像",  dst);
//  cvWaitKey(0);
          }
}       
        int k = cvWaitKey(1);    //等待一毫秒
        if( k == 'q' ) break;       
    }

    cvReleaseBGStatModel( &bg_model );
    cvReleaseCapture(&m_capture);
    cvReleaseImage(&dst);
    if(m_storage) cvClearMemStorage(m_storage);
    cvDestroyWindow("背景图像");
    cvDestroyWindow("前景图像");
    return;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 OpenCV 中,您可以使用背景减除算法来在背景和物体之间的像素差异较小的情况下提取物体。常用的背景减除算法有高斯混合模型(Gaussian Mixture Model, GMM)和深度学习方法(如 DeepLabCut)。 下面是使用高斯混合模型的代码示例: ```python import cv2 # 读取视频 cap = cv2.VideoCapture(0) # 创建背景减除对象 fgbg = cv2.createBackgroundSubtractorMOG2() while(1): ret, frame = cap.read() # 背景减除 fgmask = fgbg.apply(frame) cv2.imshow('frame',fgmask) k = cv2.waitKey(30) & 0xff if k == 27: break cap.release() cv2.destroyAllWindows() ``` 该算法会将背景和前景分离开来,您可以使用 `fgmask` 变量来获取前景图像。 ### 回答2: 在使用cv2提取物体时,如果背景和物体之间的像素差异较小,可以尝试以下方法进行提取。 首先,我们需要将图像转换为灰度图像,使用cv2的cvtColor函数进行转换。这样可以将彩色图像转换为单通道的灰度图像少计算量。 然后,可以使用cv2的高斯模糊函数GaussianBlur对图像进行模糊处理,以平滑图像小噪声。通过调整模糊核的大小,可以使得背景和物体之间的差异进一步小。 接下来,使用cv2的adaptiveThreshold函数进行自适应阈值处理,将图像转换为二值图像。自适应阈值处理可以根据图像的局部特性自动调整阈值,适用于背景和物体之间像素差异较小的情况。 最后,使用cv2的findContours函数找到图像中的轮廓。可以通过设置轮廓面积阈值,筛选掉过小的轮廓。通过对轮廓的遍历和比较,可以进一步提取出物体。 以下是使用cv2进行物体提取的示例代码: ```python import cv2 # 读取图像 image = cv2.imread('image.jpg') # 转换为灰度图像 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 高斯模糊处理 blurred = cv2.GaussianBlur(gray, (5, 5), 0) # 自适应阈值处理 thresholded = cv2.adaptiveThreshold(blurred, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2) # 寻找轮廓 contours, _ = cv2.findContours(thresholded, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 遍历轮廓 for contour in contours: area = cv2.contourArea(contour) if area > 100: # 设置轮廓面积阈值进行筛选 cv2.drawContours(image, [contour], -1, (0, 255, 0), 2) # 显示提取结果 cv2.imshow('Extracted Objects', image) cv2.waitKey(0) cv2.destroyAllWindows() ``` 通过以上代码,可以在背景和物体差异较小的情况下,提取出物体并显示在图像上。根据实际情况,可以调整阈值、模糊核大小和轮廓面积阈值等参数进行优化。 ### 回答3: 在cv2中,提取物体可以使用背景法法。背景法是一种简单且常用的图像分割方法,可以用于检测和提取出图像中的物体。 要在背景和物体之间的像素差异较小的情况下提取物体,可以按照以下步骤进行: 1. 读取视频或图像序列的第一帧,并将其作为初始的背景模型。 2. 依次读取视频或图像序列的每一帧。 3. 对于每一帧,计算当前帧和背景模型的差异图像,可以使用cv2.absdiff()函数进行差分操作。 4. 将差异图像进行二值化处理,可以使用cv2.threshold()函数,将小于设定阈值的像素点置为0,大于阈值的像素点置为255。 5. 对二值化后的图像进行形态学操作,如腐蚀和膨胀,以去除噪声或填充物体内部的空洞。 6. 可选的,可以通过轮廓检测(cv2.findContours())找到物体的轮廓,进一步提取物体。 以下是一个简单的背景法的代码示例: ```python import cv2 # 读取视频第一帧作为背景模型 cap = cv2.VideoCapture('video.mp4') ret, background = cap.read() while cap.isOpened(): # 读取当前帧 ret, frame = cap.read() if not ret: break # 计算当前帧与背景模型的差异图像 diff = cv2.absdiff(frame, background) # 将差异图像二值化 _, threshold = cv2.threshold(diff, 30, 255, cv2.THRESH_BINARY) # 进行形态学操作,腐蚀和膨胀 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) threshold = cv2.erode(threshold, kernel, iterations=1) threshold = cv2.dilate(threshold, kernel, iterations=1) # 轮廓检测 contours, _ = cv2.findContours(threshold, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for contour in contours: # 根据轮廓面积进行筛选,提取大于一定面积的物体 area = cv2.contourArea(contour) if area > 100: # 在原图上绘制轮廓 cv2.drawContours(frame, [contour], -1, (0, 255, 0), 2) # 显示结果 cv2.imshow('Object Extraction', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows() ``` 上述代码可以读取视频文件,计算差异图像并提取物体,最后显示提取结果。根据具体需求,可能需要调整阈值、形态学操作或轮廓筛选的参数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值