#include "cv.h"
#include "highgui.h"
IplImage* doCanny(
IplImage* in,
double lowThresh,
double highThresh,
double aperture)
{
if (in->nChannels != 1)
return(0); // Canny only handles gray scale images
IplImage* out = cvCreateImage(
cvGetSize( in ),
in->depth, //IPL_DEPTH_8U,
1);
cvCanny( in, out, lowThresh, highThresh, aperture );
return( out );
};
int main( int argc, char** argv )
{
IplImage* img_rgb = cvLoadImage( argv[1] );
IplImage* img_gry = cvCreateImage( cvSize( img_rgb->width,img_rgb->height ), img_rgb->depth, 1);
cvCvtColor(img_rgb, img_gry ,CV_BGR2GRAY);
cvNamedWindow("Example Gray", CV_WINDOW_AUTOSIZE );
cvNamedWindow("Example Canny", CV_WINDOW_AUTOSIZE );
cvShowImage("Example Gray", img_gry );
IplImage* img_cny = doCanny( img_gry, 10, 100, 3 );
cvShowImage("Example Canny", img_cny );
cvWaitKey(0);
cvReleaseImage( &img_rgb);
cvReleaseImage( &img_gry);
cvReleaseImage( &img_cny);
cvDestroyWindow("Example Gray");
cvDestroyWindow("Example Canny");
}
前面的实现使更加容易进行一些连续的变换
IplImage* doCanny(
··
IplImage* in,
double lowThresh,
double highThresh,
double aperture)
{
if (in->nChannels != 1)
return(0); // Canny only handles gray scale images
IplImage* out = cvCreateImage(
cvGetSize( in ),
in->depth, //IPL_DEPTH_8U,
1);
cvCanny( in, out, lowThresh, highThresh, aperture );
return( out );
};
如下例,可以简单地操作组合。
IplImage* img_pyr = doPyrDown( img_gry, IPL_GAUSSIAN_5x5 );
IplImage* img_pyr2 = doPyrDown( img_pyr, IPL_GAUSSIAN_5x5 );
IplImage* img_cny = doCanny( img_pyr2, 10, 100, 3 );
...
cvReleaseImage( &img_pyr);
cvReleaseImage( &img_pyr2);
cvReleaseImage( &img_cny);
以下是完整程序:
#include "cv.h"
#include "highgui.h"
IplImage* doCanny(
IplImage* in,
double lowThresh,
double highThresh,
double aperture)
{
IplImage* out = cvCreateImage(
cvGetSize( in ),
in->depth, //IPL_DEPTH_8U,
1);
cvCanny( in, out, lowThresh, highThresh, aperture );
return( out );
};
IplImage* doPyrDown(
IplImage* in,
int filter = IPL_GAUSSIAN_5x5)
{
// Best to make sure input image is divisible by two.
//
assert( in->width%2 == 0 && in->height%2 == 0 );
IplImage* out = cvCreateImage(
cvSize( in->width/2, in->height/2 ),
in->depth,
in->nChannels
);
cvPyrDown( in, out );
return( out );
};
int main( int argc, char** argv )
{
IplImage* img_rgb = cvLoadImage( argv[1] );
IplImage* img_gry = cvCreateImage( cvSize( img_rgb->width,img_rgb->height ), img_rgb->depth, 1);
cvCvtColor(img_rgb, img_gry ,CV_BGR2GRAY);
IplImage* img_pyr = doPyrDown( img_gry, IPL_GAUSSIAN_5x5 );
IplImage* img_pyr2 = doPyrDown( img_pyr, IPL_GAUSSIAN_5x5 );
IplImage* img_cny = doCanny( img_pyr2, 10, 100, 3 );
cvNamedWindow("Example Gray", CV_WINDOW_AUTOSIZE );
cvNamedWindow("Example Pyr", CV_WINDOW_AUTOSIZE );
cvNamedWindow("Example Canny", CV_WINDOW_AUTOSIZE );
cvShowImage("Example Gray", img_gry );
cvShowImage("Example Pyr", img_pyr2 );
cvShowImage("Example Canny", img_cny );
cvWaitKey(0);
cvReleaseImage( &img_rgb);
cvReleaseImage( &img_gry);
cvReleaseImage( &img_pyr);
cvReleaseImage( &img_pyr2);
cvReleaseImage( &img_cny);
cvDestroyWindow("Example Gray");
cvDestroyWindow("Example Pyr");
cvDestroyWindow("Example Canny");
}
通过每个独立阶段释放内存来简化上例中图像处理流程:
out = doPyrDown( out );
out = doPyrDown( out );
out = doCanny( out, 10, 100, 3 );
...
cvReleaseImage( &out);
以下是完整程序:
#include "cv.h"
#include "highgui.h"
IplImage* doCanny(
IplImage* in,
double lowThresh,
double highThresh,
double aperture)
{
IplImage* out = cvCreateImage(
cvGetSize( in ),
in->depth, //IPL_DEPTH_8U,
1);
cvCanny( in, out, lowThresh, highThresh, aperture );
return( out );
};
IplImage* doPyrDown(
IplImage* in,
int filter = IPL_GAUSSIAN_5x5)
{
// Best to make sure input image is divisible by two.
//
assert( in->width%2 == 0 && in->height%2 == 0 );
IplImage* out = cvCreateImage(
cvSize( in->width/2, in->height/2 ),
in->depth,
in->nChannels
);
cvPyrDown( in, out );
return( out );
};
int main( int argc, char** argv )
{
cvNamedWindow("Example Gray", CV_WINDOW_AUTOSIZE );
cvNamedWindow("Example Pyr", CV_WINDOW_AUTOSIZE );
cvNamedWindow("Example Canny", CV_WINDOW_AUTOSIZE );
IplImage* img_rgb = cvLoadImage( argv[1] );
IplImage* out;
out = cvCreateImage( cvSize( img_rgb->width,img_rgb->height ), img_rgb->depth, 1);
cvCvtColor(img_rgb, out ,CV_BGR2GRAY);
cvShowImage("Example Gray", out );
out = doPyrDown( out );
out = doPyrDown( out );
cvShowImage("Example Pyr", out );
out = doCanny( out, 10, 100, 3 );
cvShowImage("Example Canny", out );
cvWaitKey(0);
cvReleaseImage( &out);
cvDestroyWindow("Example Gray");
cvDestroyWindow("Example Pyr");
cvDestroyWindow("Example Canny");
}
【问题】:用opencv3.0运行打开摄像头的程序时,只显示灰色。并且运行几次后要求选择摄像头,随后闪退。
【原因】:
以下是网络版,2.4.9,3.0运行成功:
#include
#include
#include
using namespace cv;//命名空间
int main()
{
VideoCapture capture(0);//创建VideoCapture对象
if (!capture.isOpened())//判断是否打开摄像头,打开isOpened返回ture
return 1;
bool stop(false);//定义一个用来停止循环的变量
Mat frame;//用来存放读取的视频序列,承载每一帧的图像 ,Mat类是用于保存图像以及其他矩阵数据的数据结构
namedWindow("Camera");//创建一个窗口,显示每一帧的窗口
while (!stop)
{
if (!capture.read(frame))//如果没有读取到就中断
{
break;
}
imshow("Camera", frame);//正常显示,把获取的视频填充到窗口中
char c = cvWaitKey(33);
if (c == 32)break; //使用空格键来停止ASCII 为32
}
capture.release();//释放
}
以下是书p30的版本,出现闪退情况,待解决:
#include "cv.h"
#include "highgui.h"
int main(int argc, char** argv) {
cvNamedWindow("Example2_9", CV_WINDOW_AUTOSIZE);
CvCapture* capture;
if (argc == 1) {
capture = cvCreateCameraCapture(0);
}
else {
capture = cvCreateFileCapture(argv[1]);
}
assert(capture != NULL);
IplImage* frame;
while (1) {
frame = cvQueryFrame(capture);
if (!frame) break;
cvShowImage("Example2_9", frame);
char c = cvWaitKey(10);
if (c == 27) break;
}
cvReleaseCapture(&capture);
cvDestroyWindow("Example2_9");
}
网上的测试程序,3.0无法打开,2.4.9可以:
#include
#include
using namespace std;
int main(int argc, char** argv)
{
//声明IplImage指针
IplImage* pFrame = NULL;
//获取摄像头
CvCapture* pCapture = cvCaptureFromCAM(0);// cvCreateCameraCapture(0);
cvWaitKey(200);
//创建窗口
cvNamedWindow("Video", 1);
//显示视屏
while (1)
{
pFrame = cvQueryFrame(pCapture);
if (!pFrame)break;
cvShowImage("Video", pFrame);
char c = cvWaitKey(33);
if (c == 27)break;
}
cvReleaseCapture(&pCapture);
cvDestroyWindow("Video");
return 0;
}
【问题】:不能显示图像。
【原因】:命令参数里有别的变量忘记删了。
网上的测试程序,显示灰色:
//#include "stdafx.h"
#include
#include
#include
int main(int argc, char** argv)
{
//声明IplImage 指针
IplImage* pFrame = NULL;
//获取摄像头
CvCapture* pCapture = cvCreateCameraCapture(-1);
//创建窗口
cvNamedWindow("video", 1);
//显示视屏
while (1)
{
pFrame = cvQueryFrame(pCapture);
if (!pFrame)break;
cvShowImage("video", pFrame);
char c = cvWaitKey(33);
if (c == 27)break;
}
cvReleaseCapture(&pCapture);
cvDestroyWindow("video");
}
【问题】:#include "stdafx.h"
没有这个文件。若注释掉则出现选择摄像机的界面且闪退。
【解决】:注释掉#include "stdafx.h"
;
CvCapture* pCapture = cvCreateCameraCapture(-1);
不可用
【原因】:
所谓头文件预编译,就是把一个工程(Project)中使用的一些MFC标准头文件(如Windows.H、Afxwin.H)预先编译,以后该工程编译时,不再编译这部分头文件,仅仅使用预编译的结果。这样可以加快编译速度,节省时间。
预编译头文件通过编译stdafx.cpp生成,以工程名命名,由于预编译的头文件的后缀是“pch”,所以编译结果文件是projectname.pch。
编译器通过一个头文件stdafx.h来使用预编译头文件。stdafx.h这个头文件名是可以在project的编译设置里指定的。编译器认为,所有在指令#include “stdafx.h”前的代码都是预编译的,它跳过#include “stdafx. h”指令,使用projectname.pch编译这条指令之后的所有代码。
因此,所有的MFC实现文件第一条语句都是:#include “stdafx.h”。
小结:摄像头打不开,有版本问题,命令参数问题,(可能是stdafx.h问题)。
ps:对于闪退问题,从网上查到的解决方法是:在return语句前面加上system(“pause”);,另外加上头文件include