【问题标题】:Applying medianBlur as well as Laplacian and threshold filters应用中值模糊以及拉普拉斯和阈值过滤器
【发布时间】:2014-03-04 12:58:32
【问题描述】:

我有一个函数,签名如下:

Mat cartoonifyImage( Mat, Mat );

我还有一个 VS2010 程序,如下所示,我在其中向网络摄像头流应用了许多过滤器,如本书中所述:Mastering OpenCV

int main( int argc, const char** argv )
{

  VideoCapture camera;
  camera.open(0);

  if( !camera.isOpened() )
  {
    cerr << "Could not access the camera!" << endl;
    return  1;
  }

  while( true )
  {
    Mat cameraFrame;
    camera >> cameraFrame;

    if( cameraFrame.empty() )
    {
      cerr << "Could not grab a camera frame!" << endl;
      return  1;
    }

    // imshow( "Camera Test", cameraFrame );

    Mat displayedFrame( cameraFrame.size(), CV_8UC3 );

    cartoonifyImage( cameraFrame, displayedFrame );

    imshow( "Cartoonifier!", displayedFrame );

    int keypress = waitKey( 20 );
    if( keypress == 27 ) break;
  }

}

这是我的函数定义:

Mat cartoonifyImage( Mat srcColor, Mat mask )
{
  Mat gray, edges;

  cvtColor( srcColor, gray, CV_BGR2GRAY );

  const int MEDIAN_BLUR_FILTER_SIZE = 7;
  const int LAPLACIAN_FILTER_SIZE = 5;
  const int EDGES_THRESHOLD = 80;

  medianBlur( gray, gray, MEDIAN_BLUR_FILTER_SIZE );
  Laplacian( gray, edges, CV_8U, LAPLACIAN_FILTER_SIZE );
  threshold( edges, mask, EDGES_THRESHOLD, 255, THRESH_BINARY_INV );

  return( mask );
}

当我运行程序时,我得到一个空白(灰色)窗口。 在第一个imshow 被注释掉的地方,我确保网络摄像头正在工作并且我可以在窗口中看到我自己的图像,所以问题一定出在其他地方。 谁能帮助我了解问题出在哪里以及我做错了什么?

谢谢,

【问题讨论】:

  • 我想问题是,“掩码”在函数中被重新分配。通常你可以这样做,但是当你将它提供给你的函数时,你必须确保它已经具有正确的类型和大小。其他可能性是将其作为参考参数传递或在调用函数时使用返回参数;)
  • 提示为什么mask在函数中被重新分配:你将它创建为CV_8UC3,但在你的函数中,它变成了单通道图像的阈值,所以它只是CV_8UC1跨度>
  • Micka,不,您根本不必分配 OutputArray 变量。缺少参考是问题
  • @berak:他不必分配它,但如果他不这样做,他就不能使用旧的数组地址(在旧的标头中),所以如果他确实分配了正确的 Mat开头的大小和类型,他不必使用引用变量。所以他可以这样做,但如果是故意的,他会因为错误的初始化分配而做错了。所以正如我所说,至少有三种不同的方法可以解决这个问题。

标签: c++ opencv image-processing video-capture


【解决方案1】:

您的displayedFrame 从未被填满。

(你将它传递给 func,它在那里被操纵,但由于你给了它一个副本,你不会得到结果)

从 cartoonifyImage 中返回一个 Mat:

Mat displayed = cartoonifyImage( cameraFrame );

或传递参考:

void cartoonifyImage( const Mat & cameraFrame, Mat & displayedFrame );

【讨论】:

  • 我使用了你的建议来传递引用,并且成功了,所以谢谢,但是我没有将返回类型更改为void,因为它仍然返回一系列图像;即矩阵。我说的对吗?
  • 是的,好的。上面的“空白”更多地是为了放大不同的方法。
【解决方案2】:
Mat cartoonifyImage( Mat srcColor )
{
    Mat gray, edges, mask;

    cvtColor( srcColor, gray, CV_BGR2GRAY );

    const int MEDIAN_BLUR_FILTER_SIZE = 7;
    const int LAPLACIAN_FILTER_SIZE = 5;
    const int EDGES_THRESHOLD = 80;

    medianBlur( gray, gray, MEDIAN_BLUR_FILTER_SIZE );
    Laplacian( gray, edges, CV_8U, LAPLACIAN_FILTER_SIZE );
    threshold( edges, mask, EDGES_THRESHOLD, 255, THRESH_BINARY_INV );

    return ( mask );
}

int main( int argc, const char** argv )
{

    VideoCapture camera;
    camera.open(0);

    if( !camera.isOpened() )
    {
        cerr << "Could not access the camera!" << endl;
        return  1;
    }

    while( true )
    {
        Mat cameraFrame;
        camera >> cameraFrame;

        if( cameraFrame.empty() )
        {
            cerr << "Could not grab a camera frame!" << endl;
            return  1;
        }

        //imshow( "Camera Test", cameraFrame );

        Mat displayedFrame( cameraFrame.size(), CV_8UC3 );

        displayedFrame = cartoonifyImage(cameraFrame);

        imshow( "Cartoonifier!", displayedFrame );

        int keypress = waitKey( 20 );
        if( keypress == 27 ) break;
    }
}

【讨论】:

  • 备注:在这种方法中分配 Mat 数组 ( cameraFrame.size(), CV_8UC3) 已过时,因为据我所知,它已被 CV_8UC1 图像取代。
猜你喜欢
  • 2011-04-28
  • 2021-02-26
  • 2019-02-02
  • 2011-02-02
  • 2016-11-13
  • 1970-01-01
  • 1970-01-01
  • 2016-08-09
相关资源
最近更新 更多