OpenCV Canny Edge直播视频

OpenCV Canny Edge on Live Video

本文关键字:直播视频 Edge Canny OpenCV      更新时间:2023-10-16

我正试图在网络摄像头的实时视频上实现opencv的精明边缘检测。然而,我得到了这个错误:

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

我想这是一个格式问题。我可以将3通道的8位RGB图像转换为1通道的灰度图像帧,然后对结果进行边缘检测。然而,我也无法在图像上实现rgb2灰度转换<此转换代码的通道数不正确>

下面是我在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;
}

问题是您在每个上都传递一个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;
}

您正在使用OpenCV 2.x吗?以下是同样有效的代码,但在以下几点之前:

  1. 请记住,OpenCV与BGR配合使用,因此在转换时,请使用CV_BGR2GRAY
  2. 小心Canny中的阈值,它们应该不同,并且比率为2或3(推荐(。可能会尝试100-200
  3. 尽量避免在每个循环中打印,这会降低代码的速度
  4. 对于过滤器,尽量不要使用大窗口。一个尺寸最多3或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灵活得多,事实上(不再发布图像…(

#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函数拍摄的方式。