OpenCV学习笔记之课后习题练习4-1

第四章课后练习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 }