下面是一个简单的Python测试程序。它使用os.popen()并使用imagesnap -d从选定的USB网络摄像头捕获图像并将图像保存在image.jpg。
中但是imagesnap -d命令在PyCharm环境中运行时,行为会有所不同,返回空白响应('')和失败保存所请求的图像。
在PyCharm的终端窗口内提交相同的代码,在完全中以相同的方式失败。
但是当相同的python命令提交到终端outside Pycharm时,程序将成功拍摄图像并返回报告,如下面的输出所示。
我正在运行Mac OS X Catalina,并使用PyCharm 2019.2.3 Community Edition进行开发。 Python版本是3.7.4
示例代码:
import os
return_string = os.popen("imagesnap -d 'DEVICE_NAME' 'image.jpg'").read()
print("'",return_string,"'")
在PyCharm开发环境中此程序返回以下内容,并且不创建jpg文件:
/Users/mcgregor94086/PycharmProjects/SonaScannerGUI/venv/bin/python /Users/mcgregor94086/Library/Preferences/PyCharmCE2019.2/scratches/scratch_5.py
' '
Process finished with exit code 0
[Outside PyCharm相同的代码返回:
$ python3
Python 3.7.4 (v3.7.4:e09359112e, Jul 8 2019, 14:54:52)
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> return_string = os.popen("imagesnap -d 'DEVICE_NAME' 'image.jpg'").read()
>>> print("'",return_string,"'")
' Capturing image from device "<AVCaptureDALDevice: 0x7fa9bc203330 [DEVICE_NAME][0x141717501bcf0b09]>"... '
>>>
在深入研究这个问题之后,没有任何回应,我开始在网上更广泛地寻找答案。尽管我发现几乎没有网络上的信息可以指导我发生了什么,但我现在相信我知道what阻止了我在python程序中以编程方式拍照。我还相信,对于我正在看到的结果,我现在有一个合理的假设。 我有一项工作正在解决,但我担心将来可能会消失。 我当前正在使用MacOS X 10.15.1 Catalina。 Catalina]版本中,任何连接的USB摄像头都被视为受特殊安全性约束的特殊设备 您将看到允许以编程方式访问相机的应用程序的复选框列表。
终端,UberConference,Google Chrome,Skype。
可用应用程序的列表因其他资源而异,例如联系人,日历,可访问性,完整磁盘访问等]
其中一些资源(例如Accessibility
和Full Disk Access)选择列表具有app列表下方的一对[+ |-]按钮],您可以添加或永久删除访问该资源的应用程序。 但是相机。麦克风和某些其他资源没有这样的按钮,对于这些设备,用户无法更改列表。面板建议应用程序进入列表
通过“请求对照相机的访问”,,但是我没有找到关于如何将应用程序添加到此访问列表的说明”。
列表中预定义的应用程序之一是“Terminal
”。这已经过检查,因此当我从终端窗口内运行图像快照时,程序具有必要的隐私特权,并且相机可以正常拍照。相反,当我尝试在PyCharm IDE中运行python程序时,PyCharm IDE并未将自身标识为终端
,并且请求默默地失败了。Python有多种不同的方式来启动独立程序,例如imagesnap。这些方法包括os.popen(),subprocess.run()和subprocess.Popen()。
其中有些方法是[[deprecated,因此我们将来不能依靠它们来工作。其他method()具有控制是否创建新“外壳”的其他选项,这些选项可能会使确定应用程序将看到的环境变得复杂。 我发现很难预测这些python方法中的哪个会成功打开相机,而不会成功,以及它们在IDE中运行还是在终端窗口中运行时的行为。也许其他人可以编译这样的表。变通方法:目前,我可以使用os.popen来解决此问题,方法是使用一个初始字符串打开新的终端。这似乎可以确保Apple安全将父级视为我们在控制面板中特别授权的“终端”应用程序。
然后我找到了
os.popen("open -a Terminal.app imagesnap.sh")
工作。
尽管目前这种解决方法对我有用,但我对使用os.popen()而不是其中一种子处理方法感到不满意,因为我担心它可能已被弃用。其次,这与Shell脚本(“ imagesnap.sh”)一起使用,但是我还没有弄清楚如何传递参数或运行可执行文件。也许一个知识渊博的读者可以提供更好的建议。