OpenCV Canny Edge on Live Video
Solution 1
The Problem is that you are passing a 3 channel image everywere
IplImage* out = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 3 );
Create other two images of single channel and use those:
IplImage* gray_out = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 1 );
IplImage* canny_out = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 1 );
and use it in:
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 );
This works for me:
#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;
}
Solution 2
are you using OpenCV 2.x? Here is code that also works, but before a few things:
- Remember that OpenCV works with BGR, so when you convert, use the CV_BGR2GRAY
- Be careful with the threshold in Canny, they should be different and with a ratio of 2 or 3( recommended). Might try 100-200...
- Try to avoid printing in every loop, that slows down a little bit your code
- For filters, try not to use a big window. A size 3 0r 5 at most is usually fine (Depending on your application). A size 11 is probably not required.
Okay, here the code:
#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;
}
By the way, you might consider using cv::Mat. It is far more flexible than IplImage and in fact ( no more Release Image...)
Comments
-
mystique almost 2 years
i am trying to implement opencv's canny edge detection on live video from webcam. However, I am getting this error:
OpenCV Error: Unsuported format or combination of formats <> in unknown function, file ........\ocv\opencv\src\cv\cvcanny.cpp, line 66
I guess this is a format issue. I can convert the 3-channel 8-bit RGB image into a 1-channel grayscale imageframe and then perform edge detection on the result. However, I am unable to implement rgb2grayscale conversion on the image as well; < Incorrect number of channels for this conversion code>
Below is the code that I implemented In VS2008. Any thoughts on how to resolve this error?
#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; }