我正在尝试在网络摄像头的实时视频上实现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;
}
答案 0 :(得分:3)
问题是你每次传递一个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;
}
答案 1 :(得分:2)
好的,这里是代码:
#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 ......)
答案 2 :(得分:0)
#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功能拍摄的方式。