刚开始学习使用OpenCV的程序代码,有几段的出现频率很高,但刚接触又不知道什么意思,所以每次都要去网上找解释,但好多次找到的解释真心让人无语,看了也没看懂,往往要综合不同人的解释才能弄明白,所以求人不如求己,自己记录一下。
1. waitkey()问题
直接从代码上理解,当然忍不住想吐槽一下,对于直接上代码(完全是代码)解释的字没几个的,真心觉得可惜了我的流量 [气愤脸],对看嘴型就知道想说什么 !
言归正传:
namedWindow("Display Image",WINDOW_AUTOSIZE);
while ( capture.read(frame) )
{
if( frame.empty() )
{
printf(" --(!) No captured frame -- Break!");
break;
}
imshow("Display Image", frame);
if( waitKey(10) == 27 ) { break; } // escape
}
先说一下代码的功能,以上代码是利用电脑的摄像头采集数据,然对每一帧数据进行处理,方便突出主要矛盾,就直接显示图像了。在代码的开头部分已经使用过using namespace cv; ,所以下面就没指定命名空间。
首先第一行: namedWindow(“Display Image”,WINDOW_AUTOSIZE);
namedWindow()是OpenCV的窗口构建函数,第一参数为构建的窗口的名称,第二个参数指定窗口的尺寸大小根据图像自动调整。
while循环为不断的读取摄像头的图像,里面的第一个if判断读取的数据是否为空,为空则退出循环,否则继续,imshow()用来在窗口中显示图像,第一个参数为要用于显示的窗口名称,第二个参数为要显示的图像数据,接下来用waitKey()函数来进行等待。
这里要好好扒一扒这个函数:
作用条件
waitKey仅对窗口机制起作用,即namedWindow()&&+imshow()产生的窗口或者只有imshow()显示的窗口。若在此之前没有产生窗口,则waitKey相当于未执行。
函数说明
原型为
int waitKey(int delay=0);
当 delay <= 0 的时候,如果没有键盘触发,则一直等待,此时的返回值为-1,否则返回值为键盘对应按键的ASCII码;
当 delay > 0 时,如果没有键盘的的触发,则等待delay的时间,单位为ms,超时则返回-1,若在此期间内,键盘有触发,则返回值为键盘对应按键的ASCII码。
代码说明
if( waitKey(10) == 27 ) { break; }
这里的意思就是,在10ms之内,如果没有动作,那等足10ms,超时之后返回-1,if条件不成立,继续执行while()循环;如果在此期间内有ESC键按下,ESC的ASCII码为27,则跳出while()循环。
另外,在imshow之后如果没有waitKey语句则不会正常显示图像,其原因是imshow显示的图像的时间非常短,无限接近于0,所以如果不等待,就是一闪而逝。
2. CommandLineParser类问题
这个类可以从官方文档中详细查看,p这个类的作用是用来解析命令行的指令,下面详细对其进行说明,对于整个类的定义可以从官方文档里直接查看,这里只对其用法进行说明。
首先关于此对象的定义:
CommandLineParser parser(argc, argv,key);
前两个参数从main()函数中直接传递过来就行,第三个参数是对命令行的解析,也是我们自己可以定义的,从中可以我们定义的参数名提取参数的值。
接下来研究一下key的形式:
key参数由用于说明参数形式的字符块构成,每一字符块在形式上由一对大括号和内部的字符串组成。 内部用于说明参数构成属性的字符串由三部分构成,每一部分都由 | 进行分割,在这里不得不说明一下,从网上搜索到的一些说明这个类的贴子,有的给的是四部分,我读书少,不知道这是什么意思,反正我自己是查的官方说明。
其中的三部分分别为:
- 参数名称,是由空格隔开的选项同义词列表。(如果要标记为位置或地址,则要在参数名称前加上前缘@)
- 参数值,如果未提供参数值,则使用默认值,参数值可以为空。
- 帮助信息,用来说明此参数的作用,可以为空。
const String keys =
"{help h usage ? | | print this message }"
"{@image1 | | image1 for compare }"
"{@image2 | | image2 for compare }"
"{@repeat |1 | number }"
"{path |. | path to file }"
"{fps | -1.0 | fps for output video }"
"{N count |100 | count of objects }"
"{ts timestamp | | use time stamp }"
;
}
如以上代码所示,第一行中,参数帮助中,参数名称的同义词列表有 help ,h,usage,?共四个,所以在使用的时候,不管你用-h,-help,-usage,-?都是一样的,都会出现指令使用方法的说明信息。在程序中对参数的解析获取稍后再讲,先说明一下以下内容:
#用来进行命令的说明,一般是对你下的程序的功能,各个参数怎么用什么的,比如下行
parser.about("\nThis program demonstrates using the cv::CascadeClassifier class to detect objects (Face + eyes) in a video stream.\n\n" );
#has判断函数,判断有没有某个可用的参数名称,比如下行判断有没有help
parser.has("help");
#向设备输出about中的信息,就是这一段中第一行里面的信息
parser.printMessage();
下面看一下参数如何获取,有下面一段代码:
CommandLineParser parser(argc, argv, keys); #构造函数
parser.about("Application name v1.0.0"); #说明信息
if (parser.has("help")) #判断是否有Help函数
{
parser.printMessage(); #打印信息
return 0;
}
int N = parser.get<int>("N"); #将参数名称N后面的值以int的形式存放到变量N中
double fps = parser.get<double>("fps"); #将参数名称fps后面的值以double的形式存放到变量fps中
String path = parser.get<String>("path"); #同理
use_time_stamp = parser.has("timestamp");
String img1 = parser.get<String>(0); #这里是获取位置,位置参数可以用索引获取,就是第几个位置参数,索引从0开始
String img2 = parser.get<String>("@image2"); #也可以直接用名称获取
int repeat = parser.get<int>(2);
if (!parser.check()) #检测
{
parser.printErrors(); #输出错误
return 0;
}
OK,暂时先把这两个问题的理解写下来,再碰到需要理解且被写得有的没的再继续写!