python命令行参数是在运行时赋予程序/脚本的标志。 它们包含我们程序的其他信息,以便可以执行。但并非所有程序都具有命令行参数,因为并非所有程序都需要它们。
命令行参数在运行时为程序提供了更多信息。这使我们能够在不更改代码的情况下,即时为程序提供不同的输入。
可以将命令行参数类比于函数参数。在计算机视觉和图像中的程序/脚本中,许多参数都是图像路径或视频路径。深度学习中的许多参数为模型路径。接下来将通过两个脚本示例来了解Python argparse软件包。
示例1
1 # import the necessary packages
2 import argparse
3
4 # construct the argument parse and parse the arguments
5 ap = argparse.ArgumentParser()
6 ap.add_argument("-n", "--name", required=True,
7 help="name of the user")
8 args = vars(ap.parse_args())
9
10 # display a friendly message to the user
11 print("Hi there {}, it's nice to meet you!".format(args["name"]))
首先,我们需要argparse软件包,因此我们在第2行将其导入。
在第5行,我们将ArgumentParser对象实例化为ap。
然后在第6行和第7行,我们添加唯一的参数--name。 我们必须同时指定速记版本(-n),required = True表示这是必填参数。
如果需要,第7行的 help 字符串将在终端中提供其他信息。 要查看命令用法帮助,您可以在终端中输入以下内容(直接在下面输出):
$ python simple_example.py --help
usage: simple_example.py [-h] -n NAME
optional arguments:
-h, --help show this help message and exit
-n NAME, --name NAME name of the user
请注意我是如何指定所有三个的:
- 可执行文件(python)
- 我们的Python脚本文件(simple_example.py)
- 还有一个参数(--help)以打印用法。
脚本的第8行指示Python和argparse库解析命令行参数。我还在对象上调用vars,将解析的命令行参数转换为Python字典,其中字典的键是命令行参数的名称,值是为命令行参数提供的字典的值。
虽然是可选的,但我更喜欢将arguments对象转换为字典,以便可以通过命令行或Jupyter Notebook执行脚本。使用Jupyter Notebook时,我可以简单地删除命令行参数解析代码,并插入带有任何硬编码值的名为args的字典。
现在您可能想知道:如何从命令行参数中访问值?
很简单,该脚本的第11行有一个示例。
在格式字符串中,我们指定args [“ name”]。很快您就会看到,我们将使用此命令行参数将名称动态打印到屏幕上。
示例代码命令行运行如下:
$ python simple_example.py --name Adrian
Hi there Adrian, it's nice to meet you!
$
$ python simple_example.py --name Stephanie
Hi there Stephanie, it's nice to meet you!
$
$ python simple_example.py --name YourNameHere
Hi there YourNameHere, it's nice to meet you!
注意:如果我执行的第5步没有命令行参数(或带有错误的参数),则会看到如下所示的用法/错误信息。
$ python simple_example.py
usage: simple_example.py [-h] -n NAME
simple_example.py: error: argument -n/--name is required
这个简单的例子帮助我们掌握了命令行参数的概念。 但是,打印包含我们姓名的句子不是很有用。
在下一节中,我将提供使用命令行参数的更实际的示例
示例2
在下一个示例中,我们将对任何给定的输入图像中的形状进行计数,同时注释要写入磁盘的输出图像。
我们将再次使用命令行参数来指定输入图像路径和输出图像路径。
因此,我们创建一个名为shape_counter.py的新脚本:
1 Codeblock #1: Lines 1-20# import the necessary packages
2 import argparse
3 import imutils
4 import cv2
5
6 # construct the argument parser and parse the arguments
7 ap = argparse.ArgumentParser()
8 ap.add_argument("-i", "--input", required=True,
9 help="path to input image")
10 ap.add_argument("-o", "--output", required=True,
11 help="path to output image")
12 args = vars(ap.parse_args())
13
14 # load the input image from disk
15 image = cv2.imread(args["input"])
16
17 # convert the image to grayscale, blur it, and threshold it
18 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
19 blurred = cv2.GaussianBlur(gray, (5,5), 0)
20 thresh = cv2.threshold(blurred, 60, 255, cv2.THRESH_BINARY)[1]
我们在第2行上导入argparse -这是将帮助我们解析和访问命令行参数的软件包。
然后,在第7-12行,我们解析两个命令行参数。这些代码在这些行上非常易读,您可以看到如何格式化参数。
在第7行,我们将ArgumentParser对象实例化为ap。
然后在第8行和第9行,我们添加--input参数。我们必须指定速记(-i ),其中任何一个标记都可以在命令行中使用。这是必填参数,如required = True所示。
同样,在第10行和第11行,我们指定了--output参数,这也是必需的。
从那里,我们使用路径加载图像。请记住,输入图像路径包含在args [“ input”]中,因此这是cv2.imread的参数。
其余各行是针对图像处理的。
在18-20行,我们完成了三个操作:
- 将图像转换为灰度
- 模糊灰度图像
- 阈值模糊图像
我们已经准备好寻找并绘制形状轮廓:
22 # extract contours from the image
23 cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
24 cv2.CHAIN_APPROX_SIMPLE)
25 cnts = imutils.grab_contours(cnts)
26
27 # loop over the contours and draw them on the input image
28 for c in cnts:
29 cv2.drawContours(image, [c], -1, (0, 0, 255), 2)
30
31 # display the total number of shapes on the image
32 text = "I found {} total shapes".format(len(cnts))
33 cv2.putText(image, text, (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5,
34 (0, 0, 255), 2)
35
36 # write the output image to disk
37 cv2.imwrite(args["output"], image)
在第23-25行,我们在图像中找到形状轮廓。
在第28和29行,我们在输入图像上绘制轮廓。
然后,我们将文本组合在图像上(第32-34行)。 文本包含形状的总数。
最后,我们使用--output image path参数使用 cv2.imwrite(第37行)将映像写入磁盘。
让我们用两个参数执行命令:
$ python shape_counter.py --input input_01.png --output output_01.png
如果检查工作目录,您会发现出现了output_01.png图像:
我们在这里所做的是使用一个不变的脚本,并为其提供了不同的参数
注意
我想与您分享另一个“陷阱”。 有时我的命令行参数标志中带有“-”(破折号),例如--features-db。 在获取参数所包含的值时,您需要使用“ _”(下划线),这有点令人困惑,并且有点麻烦。如下:
# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-d", "--dataset", required=True, help="Path to the directory of indexed images")
ap.add_argument("-f", "--features-db", required=True, help="Path to the features database")
ap.add_argument("-c", "--codebook", required=True, help="Path to the codebook")
ap.add_argument("-o", "--output", required=True, help="Path to output directory")
args = vars(ap.parse_args())
# load the codebook and open the features database
vocab = pickle.loads(open(args["codebook"], "rb").read())
featuresDB = h5py.File(args["features_db"], mode="r")
print("[INFO] starting distance computations...")
请注意,在突出显示的行中,我已将参数定义为--features-db(带短划线),但我通过args [“ features_db”](带下划线)对其进行了引用。 这是因为argparse Python库在解析过程中用下划线替换了破折号。