第四章课后练习1
1.本章完整讲述了基本的输入/输出编程以及OpenCV的数据结构。下面的练习是基于前面的知识做一些应用,为后面大程序的实现提供帮助。
a.创建一个程序实现以下功能:(1)从视频文件中读入数据;(2)将读入数据转换为灰度图;(3)对图像做Canny边缘检测。将三个过程的处理结果显示到不同的窗口中,每个窗口根据其内容合理命名。
b.将所有三个步骤实现显示在一个图像中。
c.在图像的三个不同部分写上合适的文字标签。
a的程序实现如下
1 /*ch4_lx4_1_a.cpp 2 本程序是learning opencv这本书的课后习题练习 3 欢迎提出问题一起讨论*/ 4 #include "highgui.h" 5 #include "cv.h" 6 IplImage* doCanny( 7 IplImage* img, 8 double lowThresh, 9 double highThresh, 10 double aperture 11 ){ 12 13 IplImage* out = cvCreateImage( 14 cvGetSize(img), 15 img->depth, 16 1); 17 18 cvCanny( img,out,lowThresh,highThresh,aperture);//void cvCanny( const CvArr* image,CvArr* edges,double threshold1,double threshold2, int 19 return(out); //aperture_size=3 ); 20 }; 21 int main( int argc,char** argv){ 22 cvNamedWindow( "frame",CV_WINDOW_AUTOSIZE); 23 cvNamedWindow( "huidu",CV_WINDOW_AUTOSIZE); 24 cvNamedWindow( "bianyuan",CV_WINDOW_AUTOSIZE); 25 CvCapture* capture = cvCreateFileCapture(argv[1]); 26 IplImage* frame; 27 while(1){ 28 frame = cvQueryFrame( capture); 29 IplImage* huidu = cvCreateImage( cvSize( frame->width,frame->height ), frame->depth, 1); 30 cvCvtColor(frame, huidu , CV_BGR2GRAY ); 31 IplImage* bianyuan = doCanny(huidu,10,100,3); 32 if( !frame ) break; 33 cvShowImage("frame",frame); 34 cvShowImage("huidu",huidu); 35 cvShowImage("bianyuan",bianyuan); 36 char c = cvWaitKey(33); //使视频以30帧每秒的速度播放 37 if( c==27) break; 38 } 39 cvReleaseCapture( &capture); 40 cvDestroyWindow( "frame"); 41 cvDestroyWindow( "huidu"); 42 cvDestroyWindow( "bianyuan"); 43 return 0; 44 }
b.的程序实现涉及到把三个图像合成到一个图像中显示,具体方法参考一篇博文:https://www.cnblogs.com/CBDoctor/archive/2011/09/19/2180998.html
但这个作者的方法中存在一个问题:第一幅图是显示原图,可是原图变成了灰色,原图的宽度被扩大3倍,只能显示出三分之一,相当于被横向拉伸了3倍。但设置的感兴趣区域是原图的大小,作者并没有给出解答。还需进一步改进。
1 /*ch4_lx4_1_b.cpp 2 本程序是learning opencv这本书的课后习题练习 3 欢迎提出问题一起讨论*/ 4 #include "highgui.h" 5 #include "cv.h" 6 IplImage* doCanny( 7 IplImage* img, 8 double lowThresh, 9 double highThresh, 10 double aperture 11 ){ 12 13 IplImage* out = cvCreateImage( 14 cvGetSize(img), 15 img->depth, 16 1); 17 18 cvCanny( img,out,lowThresh,highThresh,aperture);//void cvCanny( const CvArr* image,CvArr* edges,double threshold1,double threshold2, int 19 return(out); //aperture_size=3 ); 20 }; 21 int main( int argc,char** argv){ 22 cvNamedWindow( "frame",CV_WINDOW_AUTOSIZE); 23 cvNamedWindow( "huidu",CV_WINDOW_AUTOSIZE); 24 cvNamedWindow( "bianyuan",CV_WINDOW_AUTOSIZE); 25 cvNamedWindow( "chuangkou",CV_WINDOW_AUTOSIZE); 26 CvCapture* capture = cvCreateFileCapture(argv[1]); 27 IplImage* frame; 28 while(1){ 29 frame = cvQueryFrame( capture); 30 IplImage* chuangkou = cvCreateImage(cvSize( frame->width*3.0,frame->height),frame->depth,frame->nChannels); 31 cvZero(chuangkou); 32 IplImage* huidu = cvCreateImage( cvSize( frame->width,frame->height ), frame->depth, 1); 33 cvCvtColor(frame, huidu , CV_BGR2GRAY ); 34 IplImage* bianyuan = doCanny(huidu,10,100,3); 35 if( !frame ) break; 36 //---------------------------------- 37 //载入原图像到目标图像 38 cvSetImageROI(chuangkou, cvRect(0, 0, frame->width, frame->height)); 39 cvCopy(frame, chuangkou); 40 cvResetImageROI(chuangkou); 41 //载入灰度图像到目标图像 42 cvSetImageROI(chuangkou, cvRect(frame->width, 0, frame->width, frame->height)); 43 chuangkou->nChannels =1; 44 cvCopy(huidu, chuangkou); 45 cvResetImageROI(chuangkou); 46 //载入边缘检测图像到目标图像 47 cvSetImageROI(chuangkou, cvRect((frame->width) *2.0, 0, frame->width, frame->height)); 48 chuangkou->nChannels =1; 49 cvCopy(bianyuan, chuangkou); 50 cvResetImageROI(chuangkou); 51 //--------------------------------------- 52 cvShowImage("chuangkou",chuangkou); 53 cvShowImage("frame",frame); 54 cvShowImage("huidu",huidu); 55 cvShowImage("bianyuan",bianyuan); 56 char c = cvWaitKey(33); //使视频以30帧每秒的速度播放 57 if( c==27) break; 58 } 59 cvReleaseCapture( &capture); 60 cvDestroyWindow( "frame"); 61 cvDestroyWindow( "huidu"); 62 cvDestroyWindow( "bianyuan"); 63 return 0; 64 }
c.在图像的三个不同部分写上合适的文字标签。主要是调用cvPutText()函数。
1 /*ch4_lx4_1_c.cpp 2 添加功能:为三个图像添加文字 3 本程序是learning opencv这本书的课后习题练习 4 欢迎提出问题一起讨论*/ 5 #include "highgui.h" 6 #include "cv.h" 7 IplImage* doCanny( 8 IplImage* img, 9 double lowThresh, 10 double highThresh, 11 double aperture 12 ){ 13 14 IplImage* out = cvCreateImage( 15 cvGetSize(img), 16 img->depth, 17 1); 18 19 cvCanny( img,out,lowThresh,highThresh,aperture);//void cvCanny( const CvArr* image,CvArr* edges,double threshold1,double threshold2, int 20 return(out); //aperture_size=3 ); 21 }; 22 int main( int argc,char** argv){ 23 cvNamedWindow( "frame",CV_WINDOW_AUTOSIZE); 24 cvNamedWindow( "huidu",CV_WINDOW_AUTOSIZE); 25 cvNamedWindow( "bianyuan",CV_WINDOW_AUTOSIZE); 26 cvNamedWindow( "chuangkou",CV_WINDOW_AUTOSIZE); 27 CvCapture* capture = cvCreateFileCapture(argv[1]); 28 IplImage* frame; 29 while(1){ 30 frame = cvQueryFrame( capture); 31 IplImage* chuangkou = cvCreateImage(cvSize( frame->width*3.0,frame->height),frame->depth,frame->nChannels); 32 cvZero(chuangkou); 33 IplImage* huidu = cvCreateImage( cvSize( frame->width,frame->height ), frame->depth, 1); 34 cvCvtColor(frame, huidu , CV_BGR2GRAY ); 35 IplImage* bianyuan = doCanny(huidu,10,100,3); 36 //为三幅图像添加文字 37 CvFont* font; 38 cvInitFont(font,CV_FONT_HERSHEY_SIMPLEX,1.0,1.0,0.0,1,8); 39 cvPutText(frame,"liuyutong",cvPoint(0,50),font,cvScalar(255,0,0)); 40 cvPutText(huidu,"liuyutong",cvPoint(0,50),font,cvScalar(255,0,0)); 41 cvPutText(bianyuan,"liuyutong",cvPoint(0,50),font,cvScalar(255,0,0)); 42 if( !frame ) break; 43 //---------------------------------- 44 //载入原图像到目标图像 45 cvSetImageROI(chuangkou, cvRect(0, 0, frame->width, frame->height)); 46 cvCopy(frame, chuangkou); 47 cvResetImageROI(chuangkou); 48 //载入灰度图像到目标图像 49 cvSetImageROI(chuangkou, cvRect(frame->width, 0, frame->width, frame->height)); 50 chuangkou->nChannels =1; 51 cvCopy(huidu, chuangkou); 52 cvResetImageROI(chuangkou); 53 //载入边缘检测图像到目标图像 54 cvSetImageROI(chuangkou, cvRect((frame->width) *2.0, 0, frame->width, frame->height)); 55 chuangkou->nChannels =1; 56 cvCopy(bianyuan, chuangkou); 57 cvResetImageROI(chuangkou); 58 //--------------------------------------- 59 cvShowImage("chuangkou",chuangkou); 60 cvShowImage("frame",frame); 61 cvShowImage("huidu",huidu); 62 cvShowImage("bianyuan",bianyuan); 63 char c = cvWaitKey(33); //使视频以30帧每秒的速度播放 64 if( c==27) break; 65 } 66 cvReleaseCapture( &capture); 67 cvDestroyWindow( "frame"); 68 cvDestroyWindow( "huidu"); 69 cvDestroyWindow( "bianyuan"); 70 return 0; 71 }