我正在尝试学习C和OpenCV。我使用的是受O'Reilly Learning OpenCV启发的以下代码,但出现错误,并且图像未按预期显示。这段代码有什么问题吗?
# include "cv.h"
# include "highgui.h"
IplImage * doCanny(IplImage *in, double lowThresh, double highThresh, int aperture) {
if(1 != in->nChannels){
return 0;
}
IplImage *out = cvCreateImage(cvGetSize(in), IPL_DEPTH_8U, 1);
cvCanny(in, out, lowThresh, highThresh, aperture);
return out;
}
/* This layout works with other functions like cvPyrdown, but for some reason it doesn't work with cvCanny */
int main() {
double lowThresh = 50;
double highThresh = 150;
int aperture = 3;
IplImage *img = cvLoadImage("/tmp/lena.jpg", CV_LOAD_IMAGE_UNCHANGED);
IplImage *out = doCanny(img, lowThresh, highThresh, aperture);
cvNamedWindow("Example2-6", CV_LOAD_IMAGE_UNCHANGED);
cvShowImage("Example2-6", out);
cvWaitKey(0);
cvReleaseImage(&img);
cvReleaseImage(&out);
cvDestroyWindow("Example2-6");
return 0;
}
我在Mac OS X Yosemite上获得的输出是:
最佳答案
您的jpg图像很可能是三通道图像。您可以将此图像作为in
传递到doCanny()
函数中。以下代码将使doCanny()
函数返回0:
if(1 != in->nChannels){
return 0;
}
然后,您无需检查
doCanny()
函数的返回值是否有效。因此,您将空指针传递给以下函数,这可能会导致空指针错误:cvShowImage("Example2-6", out);
为了使您的代码可以使用三通道图像,您应该将
in
函数中的doCanny()
图像转换为单通道图像:IplImage * doCanny(IplImage *in, double lowThresh, double highThresh, int aperture) {
IplImage *out = cvCreateImage(cvGetSize(in), IPL_DEPTH_8U, 1);
/* Convert the three-channel input image into a single-channel image. */
IplImage* oneChannel = cvCreateImage(cvGetSize(in), IPL_DEPTH_8U, 1);
cvCvtColor(in, oneChannel, CV_BGR2GRAY);
cvCanny(oneChannel, out, lowThresh, highThresh, aperture);
return out;
}
另外,您可以通过将
CV_LOAD_IMAGE_GRAYSCALE
作为第二个参数传递给cvLoadImage()
,将输入图像直接加载为单通道图像:IplImage *img = cvLoadImage("/tmp/lena.jpg", CV_LOAD_IMAGE_GRAYSCALE);
无论如何,您应该始终检查函数返回的值是否有效。