【问题标题】:OpenCV Canny Edge on Live Video实时视频上的 OpenCV Canny Edge
【发布时间】:2011-11-13 04:21:43
【问题描述】:

我正在尝试对来自网络摄像头的实时视频实施 opencv 的精明边缘检测。但是,我收到此错误:

OpenCV 错误:不支持的格式或格式组合 在未知函数中,文件 ........\ocv\opencv\src\cv\cvcanny.cpp,第 66 行

我猜这是格式问题。我可以将 3 通道 8 位 RGB 图像转换为 1 通道灰度图像帧,然后对结果进行边缘检测。但是,我也无法在图像上实现 rgb2grayscale 转换;

以下是我在 VS2008 中实现的代码。有关如何解决此错误的任何想法?

#pragma once

#include <stdio.h>
#include <tchar.h>
#include <iostream>
#include <conio.h>
#include <iomanip>
#include <cv.h>
#include <cvaux.h>
#include <cxcore.h>
#include <highgui.h>
#include <math.h>
#include <string.h>
#include <cxtypes.h>


using namespace std;
using namespace cv;

int main(int, char**)
{

    cvNamedWindow("Edges", CV_WINDOW_AUTOSIZE); 
CvCapture* capture = cvCaptureFromCAM(0);

IplImage* frame;
    while(1) {
        frame = cvQueryFrame( capture );


        int depth_img =frame->depth;
        int height_img =frame->height;
        int width_img =frame->width;
        int size_img =frame->imageSize;
        int nchan_img =frame->nChannels;
        int nsize_img =frame->nSize;

        cout << setw(15) << "depth" <<  depth_img << endl;
        cout << setw(15) << "height" <<  height_img << endl;
        cout << setw(15) << "width" <<  width_img << endl;
        cout << setw(15) << "size" <<  size_img << endl;
        cout << setw(15) << "nchan" <<  nchan_img << endl;
        cout << setw(15) << "nsize" <<  nsize_img << endl;


        IplImage* out = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 3 );
        cvSmooth( frame, out, CV_GAUSSIAN, 11, 11 );
        cvCvtColor(out ,out, CV_RGB2GRAY);
        cvCanny( out, out, 10, 10, 3 );

        if( !frame ) break;
        cvShowImage( "Edge", out );
        char c = cvWaitKey(33);
        if( c == 27 ) break;
    }
    cvReleaseCapture( &capture );
    cvDestroyWindow( "Edge" );
    return 0;
}

【问题讨论】:

    标签: c++ video opencv


    【解决方案1】:

    问题是你每个人都在传递一个 3 通道图像

    IplImage* out = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 3 );
    

    创建另外两个单通道图像并使用它们:

    IplImage* gray_out = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 1 );
    IplImage* canny_out = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 1 );
    

    并将其用于:

    cvSmooth( frame, out, CV_GAUSSIAN, 11, 11 );
    cvCvtColor(out , gray_out, CV_RGB2GRAY);
    cvCanny( gray_out, canny_out, 10, 10, 3 );
    
    if( !frame ) break;
    cvShowImage( "Edge", canny_out );
    

    这对我有用:

    #include <stdio.h>
    #include <iostream>
    #include <iomanip>
    #include <cv.h>
    #include <cvaux.h>
    #include <cxcore.h>
    #include <highgui.h>
    #include <math.h>
    #include <string.h>
    
    
    using namespace std;
    using namespace cv;
    
    int main(int, char**)
    {
    
        cvNamedWindow("Edges", CV_WINDOW_AUTOSIZE); 
    CvCapture* capture = cvCaptureFromCAM(0);
    
    IplImage* frame;
        while(1) {
            frame = cvQueryFrame( capture );
    
            int depth_img =frame->depth;
            int height_img =frame->height;
            int width_img =frame->width;
            int size_img =frame->imageSize;
            int nchan_img =frame->nChannels;
            int nsize_img =frame->nSize;
    
            cout << setw(15) << "depth" <<  depth_img << endl;
            cout << setw(15) << "height" <<  height_img << endl;
            cout << setw(15) << "width" <<  width_img << endl;
            cout << setw(15) << "size" <<  size_img << endl;
            cout << setw(15) << "nchan" <<  nchan_img << endl;
            cout << setw(15) << "nsize" <<  nsize_img << endl;
    
    
            IplImage* out = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 3 );
            IplImage* gray_out = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 1 );
            IplImage* canny_out = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 1 );
            cvSmooth( frame, out, CV_GAUSSIAN, 11, 11 );
            cvCvtColor(out , gray_out, CV_RGB2GRAY);
            cvCanny( gray_out, canny_out, 10, 10, 3 );
    
            if( !frame ) break;
            cvShowImage( "Edge", canny_out );
            char c = cvWaitKey(33);
            if( c == 27 ) break;
        }
        cvReleaseCapture( &capture );
        cvDestroyWindow( "Edge" );
        return 0;
    }
    

    【讨论】:

      【解决方案2】:

      您使用的是 OpenCV 2.x 吗?下面的代码也可以,但在一些事情之前:

      1. 请记住,OpenCV 与 BGR 一起使用,因此在转换时,请使用 CV_BGR2GRAY
      2. 小心 Canny 中的阈值,它们应该不同,并且比率为 2 或 3(推荐)。可以试试 100-200...
      3. 尽量避免在每个循环中打印,这会稍微减慢您的代码速度
      4. 对于过滤器,尽量不要使用大窗口。通常最多 3 0r 5 的大小就可以了(取决于您的应用程序)。可能不需要 11 码。

      好的,代码如下:

      #include "opencv2/highgui/highgui.hpp"
      #include "opencv2/imgproc/imgproc.hpp"
      #include <iostream>
      #include <stdio.h>
      #include <stdlib.h>
      
      using namespace std;
      using namespace cv;
      
      int main(int, char**)
      {
          namedWindow( "Edges", CV_WINDOW_NORMAL ); 
          CvCapture* capture = cvCaptureFromCAM(-1);
      
          cv::Mat frame; cv::Mat out; cv::Mat out2;
      
          while(1) {
              frame = cvQueryFrame( capture );
      
              GaussianBlur( frame, out, Size(5, 5), 0, 0 );
              cvtColor( out ,out2, CV_BGR2GRAY ); // produces out2, a one-channel image (CV_8UC1)
             Canny( out2, out2, 100, 200, 3 ); // the result goes to out2 again,but since it is still one channel it is fine
      
              if( !frame.data ) break;
              imshow( "Edges", out2 );
      
              char c = cvWaitKey(33);
              if( c == 'c' ) break;
          }
          return 0;
      }
      

      顺便说一句,您可以考虑使用 cv::Mat。它比 IplImage 灵活得多,实际上(不再有 Release Image...)

      【讨论】:

        【解决方案3】:
        #include <opencv2/opencv.hpp>
        #include <iostream>
        using namespace cv;
        using namespace std;
        
        
        
        int main()
        {
            Mat img;
            VideoCapture cap(0);
        
            while (true)
            {
                cap >> img;
        
                Mat edges;
                cvtColor(img, edges, CV_BGR2GRAY);
        
                Canny(edges, edges, 30, 60);
        
                imshow("window label", edges);
                waitKey(1);
            }
        
            return 0;
        }
        

        这就是我使用canny函数拍摄的方式。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-05-18
          • 2017-07-29
          • 1970-01-01
          • 1970-01-01
          • 2013-08-14
          • 1970-01-01
          相关资源
          最近更新 更多