OpenCV中的accumulateWeighted断言失败

Assertion failed with accumulateWeighted in OpenCV

本文关键字:失败 断言 accumulateWeighted 中的 OpenCV      更新时间:2023-10-16

我正在使用openCV并试图计算背景的移动平均,然后取当前帧并减去背景以确定运动(某种类型)。

然而,当运行程序时,我得到:

OpenCV Error: Assertion failed (func != 0) in accumulateWeighted, file /home/sebbe/projekt/opencv/trunk/opencv/modules/imgproc/src/accum.cpp, line 431
terminate called after throwing an instance of 'cv::Exception'
what():  /home/sebbe/projekt/opencv/trunk/opencv/modules/imgproc/src/accum.cpp:431: error: (-215) func != 0 in function accumulateWeighted

我看不出什么参数是错误的。

下面插入代码:

#include <stdio.h>
#include <stdlib.h>
#include "cv.h"
#include "highgui.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "cxcore.h"
using namespace cv;
int main( int argc, char **argv )
{
    Mat  colourFrame;
Mat  frame;
Mat greyFrame;
Mat movingAverage;
Mat difference;
Mat temp;
    int       key = 0;
VideoCapture cap(0);

/* always check */
    if ( !cap.isOpened() ) {
        fprintf( stderr, "Cannot open initialize webcam!n" );
        return 1;
    }
namedWindow("Camera Window", 0);
// Initialize
cap >> movingAverage;
    while( key != 'q' ) {
      /* get a frame */
  cap >> colourFrame;
  /* Create a running average of the motion and convert the scale */
  accumulateWeighted(colourFrame, movingAverage, 0.02, Mat() );
  /* Take the difference from the current frame to the moving average */
  absdiff(colourFrame, movingAverage, difference);
  /* Convert the image to grayscale */
  cvtColor(difference, greyFrame, CV_BGR2GRAY);
  /* Convert the image to black and white */
  threshold(greyFrame, greyFrame, 70, 255, CV_THRESH_BINARY);
        /* display current frame */
    imshow("Camera Window",greyFrame);
        /* exit if user press 'q' */
        key = cvWaitKey( 1 );
    }
    return 0;
}

查看OpenCV源代码,特别是在modules/imgproc/src/accum.cpp第431行,该断言之前的行是:

void cv::accumulateWeighted( InputArray _src, CV_IN_OUT InputOutputArray _dst,
                             double alpha, InputArray _mask )
{
    Mat src = _src.getMat(), dst = _dst.getMat(), mask = _mask.getMat();
    int sdepth = src.depth(), ddepth = dst.depth(), cn = src.channels();
    CV_Assert( dst.size == src.size && dst.channels() == cn );
    CV_Assert( mask.empty() || (mask.size == src.size && mask.type() == CV_8U) );
    intfidx = getAccTabIdx(sdepth, ddepth);
    AccWFunc func = fidx >= 0 ? accWTab[fidx] : 0;
    CV_Assert( func != 0 ); // line 431

在您的情况下发生的是getAccTabIdx()返回-1,这反过来使func为零。

要使accumulateWeighted()正常工作,colourFramemovingAverage的深度必须是以下选项之一:

colourFrame.depth() == CV_8U && movingAverage.depth() == CV_32F
colourFrame.depth() == CV_8U && movingAverage.depth() == CV_64F 
colourFrame.depth() == CV_16U && movingAverage.depth() == CV_32F
colourFrame.depth() == CV_16U && movingAverage.depth() == CV_64F
colourFrame.depth() == CV_32F && movingAverage.depth() == CV_32F
colourFrame.depth() == CV_32F && movingAverage.depth() == CV_64F
colourFrame.depth() == CV_64F && movingAverage.depth() == CV_64F

任何与此不同的内容都将使getAccTabIdx()返回-1并在第431行触发异常。

从OpenCV API的文档中可以看到,accumulateWeighted的输出图像是

  • dst -与输入图像具有相同通道数的累加器图像,32位或64位浮点。

你的初始化是错误的。您应该首先检索colorframe大小,然后执行以下操作:

cv::Mat movingAverage = cv::Mat::zeros(colourFrame.size(), CV_32FC3);

在Python上,一个可行的解决方案是使用FIRSTcolourFrame.copy().astype("float")启动movingAverage。我在这个网站上找到了解决方案