练习:创建一个程序实现以下功能:
(1)从视频文件读入数据;
(2)将读入数据转换为灰度图;
(3)对图像做Canny边缘检测。将三个过程的处理结果显示到不同的窗口,每个窗口根据其内容合理命名。
程序运行源码如下:
#include "cv.h"
#include "highgui.h"
int main()
{
//根据要求首先定义3个不同的窗口,用于处理后图像的显示
cvNamedWindow("sourceImg",1);
cvNamedWindow("grayImg",1);
cvNamedWindow("cannyImg",1);
CvCapture *capture=cvCreateFileCapture("testVideo.avi");//读入视频数据
if(!capture)
return -1;
IplImage *sourceImg=cvQueryFrame(capture);//得到源图像视频帧,用于灰度转换
IplImage *grayImg=cvCreateImage(cvGetSize(sourceImg),IPL_DEPTH_8U,1);
IplImage *cannyImg=cvCreateImage(cvGetSize(sourceImg),IPL_DEPTH_8U,1);
while((sourceImg=cvQueryFrame(capture))!=NULL)
{
//从彩色图像转换成灰度图像
cvCvtColor(sourceImg,grayImg,CV_BGR2GRAY);
//Canny推荐的上下阈值比为2:1到3:1之间,这里使用了3:1,可自行修改highThresh:lowThresh的比例
cvCanny(grayImg,cannyImg,10,30,3);
//运行发现,灰度和canny图像翻转了,所以通过重新定义图像原点
//origin为0表示顶左结构,origin为1表示底左结构
grayImg->origin=1;
cannyImg->origin=1;
cvShowImage("sourceImg",sourceImg);
cvShowImage("grayImg",grayImg);
cvShowImage("cannyImg",cannyImg);
cvWaitKey(30);//等待30ms
}
//对于自己申请的资源,记得自己手动释放
cvReleaseImage(&grayImg);
cvReleaseImage(&cannyImg);
cvReleaseCapture(&capture);
cvDestroyWindow("sourceImg");
cvDestroyWindow("grayImg");
cvDestroyWindow("cannyImg");
return 0;
}
程序运行结果:
b、将所有三个步骤实现显示在一个图像中
提示:创建一个新的图像,其高度与原始图像相同,宽度为原来视频帧的3倍,将3副图像分别复制到新的图像中:可使用指针;或者更巧妙地创建3个图像头,3个图像头分别指向图像数据的开始处,1/3处和2/3处,然后使用函数cvCopy()复制
#include "cv.h"
#include "highgui.h"
int main()
{
//根据要求首先定义4个不同的窗口,用于处理后图像的显示
cvNamedWindow("sourceImg");
cvNamedWindow("grayImg");
cvNamedWindow("cannyImg");
cvNamedWindow("newImg");
CvCapture *capture=cvCreateFileCapture("testVideo.avi");//读入视频数据
if(!capture)
return -1;
IplImage *sourceImg=cvQueryFrame(capture);//得到源图像视频帧,用于灰度转换
int width=sourceImg->width;
int heigth=sourceImg->height;
IplImage *grayImg=cvCreateImage(cvGetSize(sourceImg),sourceImg->depth,1);
IplImage *cannyImg=cvCreateImage(cvGetSize(sourceImg),sourceImg->depth,1);
//创建一个新的图像,用来保存上述3个图像
IplImage *newImg=cvCreateImage(cvSize(3*sourceImg->width,sourceImg->height),sourceImg->depth,sourceImg->nChannels);
cvZero(newImg);
while((sourceImg=cvQueryFrame(capture))!=NULL)
{
//从彩色图像转换成灰度图像
cvCvtColor(sourceImg,grayImg,CV_BGR2GRAY);
// cvConvertImage(sourceImg,grayImg);
//Canny推荐的上下阈值比为2:1到3:1之间,这里使用了3:1,可自行修改highThresh:lowThresh的比例
cvCanny(grayImg,cannyImg,10,30,3);
//运行发现,灰度和canny图像翻转了,所以通过重新定义图像原点
//origin为0表示顶左结构,origin为1表示底左结构
grayImg->origin=1;
cannyImg->origin=1;
//载入原图像到目标图像
cvSetImageROI(newImg,cvRect(0,0,sourceImg->width,sourceImg->height));
//由于读入的是视频文件,并且原视频帧和处理后的视频帧通道数可能不同,所以此处需要手动设置通道数
newImg->nChannels=sourceImg->nChannels;
newImg->origin=1;
cvCopy(sourceImg,newImg);
cvResetImageROI(newImg);
cvSetImageROI(newImg,cvRect(sourceImg->width,0,sourceImg->width,sourceImg->height));
newImg->nChannels=1;
newImg->origin=1;
cvCopy(grayImg,newImg);
cvResetImageROI(newImg);
cvSetImageROI(newImg,cvRect(2*(sourceImg->width),0,sourceImg->width,sourceImg->height));
newImg->nChannels=1;
newImg->origin=1;
cvCopy(cannyImg,newImg);
cvResetImageROI(newImg);
cvShowImage("sourceImg",sourceImg);
cvShowImage("grayImg",grayImg);
cvShowImage("cannyImg",cannyImg);
cvShowImage("newImg",newImg);
cvWaitKey(30);//等待30ms
}
//对于自己申请的资源,记得自己手动释放
cvReleaseImage(&grayImg);
cvReleaseImage(&cannyImg);
cvReleaseImage(&newImg);
cvReleaseCapture(&capture);
cvDestroyWindow("sourceImg");
cvDestroyWindow("grayImg");
cvDestroyWindow("cannyImg");
cvDestroyWindow("newImg");
return 0;
}
处理结果:
从上图可以看出原图像sourceImg并没有完全显示出来,究其原因应该是sourceImg是3通道和后面两幅图像不同,但是目前我还没有解决此问题