簡體   English   中英

實時視頻上的OpenCV Canny Edge

[英]OpenCV Canny Edge on Live Video

我正在嘗試對來自網絡攝像頭的實時視頻實施opencv的canny邊緣檢測。 但是,我收到此錯誤:

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;
}

問題是您每個人都要傳遞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 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 ...)

#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功能拍攝的方式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM