我想让你知道,@Kathiravan_Natarajan,你的解决方案很棒,而且我以前使用过它并取得了巨大的成功。我将更详细地说明必须按照您所说的顺序执行哪些步骤
使用机器默认安装的python
但是,我不会更改 Cygwin 环境变量。我想尽可能使用 Cygwin 的 python3。当我需要使用cv2 时,我将简单地给出我的Windows 安装python 的完整路径。 警告:如果您在 Cygwin 中使用 Windows 的 python 并尝试为其提供文件/路径/等。来自 Cygwin,您可能会遇到问题。我将在路径问题部分讨论这些问题
好的,就在 Cygwin(以及从它的终端),我有
bballdave025@MY-MACHINE ~
$ which python3
/usr/bin/python3
bballdave025@MY-MACHINE ~
$ python3 --version
Python 3.6.9
现在,来自CMD,我的 Windows 资料。
C:\Windows\system32>where python
C:\Users\bballdave025\AppData\Local\Programs\Python\Python38\python.exe
C:\Users\bballdave025\AppData\Local\Programs\Python\Python38-32\python.exe
C:\Users\bballdave025\AppData\Local\Programs\Python\Python36\python.exe
C:\Users\bballdave025\AppData\Local\Microsoft\WindowsApps\python.exe
C:\Windows\system32>:: Ignore that last one - it takes you to the Microsoft Store
C:\Windows\system32>python --version
Python 3.8.2
@Kathiravan_Natarajan 描述的方法的工作示例
好的。让我们得到一个不需要cv2 的快速脚本。当我们这样做时,我正在引导路径类型可能存在的问题。我们将使用 bash heredocs。
bballdave025@MY-MACHINE ~
$ cat > my_pwd.py<<EOF
> #!/usr/bin/python3
> # -*- coding: utf-8 -*-
> #
> import os
>
> print(os.getcwd())
> EOF
bballdave025@MY-MACHINE ~
$ chmod +x my_pwd.py
bballdave025@MY-MACHINE ~
$ # If you wanted, you could use `./my_pwd.py`, but that doesn't go to my point
bballdave025@MY-MACHINE ~
$ python3 my_pwd.py
/home/bballdave025
现在,尽管这不是我们通常想要做的,让我们用 Windows 版本运行脚本。 (由于我们通常不想这样做,所以我没有将 Windows 版本的 Python 放在 Cygwin 的路径上)。
bballdave025@MY-MACHINE ~
$ /cygdrive/c/Users/bballdave025/AppData/Local/Programs/Python/Python38/python my_pwd.py
C:\cygwin64\home\bballdave025
如果输入python 的长路径确实让您感到困扰,请参阅第一个脚注1。
我建议在 Cygwin 中运行 rm my_pwd.py 以删除不必要的文件。
希望这能让您了解为什么我们不想在 Cygwin 中使用 Windows 的 python 而不是 Cygwin - 尽管 Cygwin 本身可以可能处理这条路径,但我们将讨论这在路径问题部分。
CV2 和路径
现在我们已经使用了代码没有 cv2,让我们看看代码有 cv2。
在 Windows CMD 中,确保您有用于 Python 的 opencv,并且。
python -m pip install opencv-python
现在,我将用几个脚本来说明,一个 bash 和一个 python,它们处理一个包含五个图像的目录。
bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win
$ ls
image_1.png image_2.png image_3.png image_4.png image_5.png
现在,为两个脚本编写代码。第一个是python 脚本,它将保持不变。第二个是 Cygwin 的 shell 脚本的问题显示(即损坏)版本。
#!/cygdrive/c/Users/bballdave025/AppData/Local/Programs/Python/Python38/python
# -*- coding: utf-8 -*-
#
#@file : show_img_and_wait.py
#
import cv2
import sys
this_img_fname = sys.argv[1]
print("Let us show {}".format(this_img_fname))
this_img = cv2.imread(this_img_fname)
cv2.imshow(this_img_fname, this_img)
cv2.waitKey(0)
print("[Trust me that {} showed up fine.]".format(this_img_fname))
print("Now, we are done showing it.")
下一个代码仅用于显示问题。它不会工作2 - 它会给出错误并且不会显示任何东西!
#!/bin/bash
#
#@file broken_img_displays_from_path.sh
#
find /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win \
-mindepth 1 -maxdepth 1 -type f -name "*.png" | \
sort > tmp_imagepaths.txt
while read -r line; do
img_fname="${line}"
"/cygdrive/c/Users/bballdave025/AppData/Local/Programs/Python/Python38/"\
"python" -u show_img_and_wait.py "${img_fname}"
done < tmp_imagepaths.txt
rm tmp_imagepaths.txt
来自 Cygwin 的终端:
bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win
$ chmod +x show_img_and_wait.py
bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win
$ chmod +x broken_img_displays_from_path.sh
让我们首先测试python 代码。请注意,由于 shebang 行(以 #! 开头的行),我们可以运行它并让 Windows python 处理所有事情。我显示没有显示的那一行是为了强调一切都通过 Windows 运行的事实。还要记住,不会有路径问题,因为我们使用的是工作目录中的图像。
(另请注意,尝试 Cygwin 的 python 时,我们会收到错误消息,指出没有 cv2;运行 python3 -m pip install opencv-python 失败,至少在今天,2020 年 5 月 1 日,纪元 ts:$ date +'%s' => 1588360101。这就是OP提出问题的原因。)
bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win
$ echo $DISPLAY
bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win
$ ./show_img_and_wait.py image_1.png
Let us show image_1.png
[Trust me that image_1.png showed up fine.]
Now, we are done showing it.
现在,让我们试试 Cygwin 的 bash 脚本。
bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win
$ ./broken_img_displays_from_path.sh
Let us show /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win/image_1.png
Traceback (most recent call last):
File "show_img_and_wait.py", line 11, in <module>
cv2.imshow(this_img_fname, this_img)
cv2.error: OpenCV(4.2.0) C:\projects\opencv-python\opencv\modules\highgui\src\wi
ndow.cpp:376: error: (-215:Assertion failed) size.width>0 && size.height>0 in fu
nction 'cv::imshow'
Let us show /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win/image_2.png
Traceback (most recent call last):
File "show_img_and_wait.py", line 11, in <module>
cv2.imshow(this_img_fname, this_img)
cv2.error: OpenCV(4.2.0) C:\projects\opencv-python\opencv\modules\highgui\src\wi
ndow.cpp:376: error: (-215:Assertion failed) size.width>0 && size.height>0 in fu
nction 'cv::imshow'
Let us show /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win/image_3.png
Traceback (most recent call last):
File "show_img_and_wait.py", line 11, in <module>
cv2.imshow(this_img_fname, this_img)
cv2.error: OpenCV(4.2.0) C:\projects\opencv-python\opencv\modules\highgui\src\wi
ndow.cpp:376: error: (-215:Assertion failed) size.width>0 && size.height>0 in fu
nction 'cv::imshow'
Let us show /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win/image_4.png
Traceback (most recent call last):
File "show_img_and_wait.py", line 11, in <module>
cv2.imshow(this_img_fname, this_img)
cv2.error: OpenCV(4.2.0) C:\projects\opencv-python\opencv\modules\highgui\src\wi
ndow.cpp:376: error: (-215:Assertion failed) size.width>0 && size.height>0 in fu
nction 'cv::imshow'
Let us show /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win/image_5.png
Traceback (most recent call last):
File "show_img_and_wait.py", line 11, in <module>
cv2.imshow(this_img_fname, this_img)
cv2.error: OpenCV(4.2.0) C:\projects\opencv-python\opencv\modules\highgui\src\wi
ndow.cpp:376: error: (-215:Assertion failed) size.width>0 && size.height>0 in fu
nction 'cv::imshow'
这些错误有点神秘。让我们讨论一下发生了什么。
路径问题(和解决方案)
这里发生的情况是 Windows python 及其版本的 cv2 需要 Windows 样式的路径。但是,如输出所示,它获得了 Cygwin 版本,例如
Let us show /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win/image_1.png
Windows python/cv2 想看,例如
Let us show C:\Users\bballdave025\Desktop\testing_cv2_python_win\image_1.png3。
这是为什么我们需要在 Cygwin 终端上使用 Windows python 的光滑解决方案时跟踪诸如路径之类的事情的一个示例。
解决方案是将cygpath 与-w 标志一起使用。这是一个修改后的bash 脚本,允许使用find 结果进行图像显示。
解决方案
#!/bin/bash
#
#@file img_displays_from_path.sh
#
find /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win \
-mindepth 1 -maxdepth 1 -type f -name "*.png" | \
sort > tmp_imagepaths.txt
while read -r line; do
img_fname=$(cygpath -w "${line}")
"/cygdrive/c/Users/bballdave025/AppData/Local/Programs/Python/Python38/"\
"python" -u show_img_and_wait.py "${img_fname}"
done < tmp_imagepaths.txt
rm tmp_imagepaths.txt
回到 Cygwin 的终端,
bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win
$ chmod +x img_displays_from_path.sh
bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win
$ ./img_displays_from_path.sh
Let us show C:\Users\13852\Desktop\testing_cv2_python_win\image_1.png
[Trust me that C:\Users\13852\Desktop\testing_cv2_python_win\image_1.png showed
up fine.]
Now, we are done showing it.
Let us show C:\Users\13852\Desktop\testing_cv2_python_win\image_2.png
[Trust me that C:\Users\13852\Desktop\testing_cv2_python_win\image_2.png showed
up fine.]
Now, we are done showing it.
Let us show C:\Users\13852\Desktop\testing_cv2_python_win\image_3.png
[Trust me that C:\Users\13852\Desktop\testing_cv2_python_win\image_3.png showed
up fine.]
Now, we are done showing it.
Let us show C:\Users\13852\Desktop\testing_cv2_python_win\image_4.png
[Trust me that C:\Users\13852\Desktop\testing_cv2_python_win\image_4.png showed
up fine.]
Now, we are done showing it.
Let us show C:\Users\13852\Desktop\testing_cv2_python_win\image_5.png
[Trust me that C:\Users\13852\Desktop\testing_cv2_python_win\image_5.png showed
up fine.]
Now, we are done showing it.
成功!如果对您有所帮助,这里有五张图片供您使用 ( )。
其他路径的东西
下面是关于使用 Cygwin 获取 Windows 路径可能出现的问题的另一个小例子。在this image 中可以看到更多(来自我自己的好奇心测试)
bballdave025@MY-MACHINE ~
$ cd 'c:'
bballdave025@MY-MACHINE /cygdrive/c
$ ls 'c:'
ls: cannot access 'c:': No such file or directory
bballdave025@MY-MACHINE ~
$ cd c:
bballdave025@MY-MACHINE /cygdrive/c
$ ls 'c:\'
'$Recycle.Bin' 'Program Files' 'System Volume Information'
cygwin64 'Program Files (x86)' Users
'Documents and Settings' ProgramData Windows
nothing_important
bballdave025@MY-MACHINE ~
$ cd c:\
> # Problem; line-continuation char; I have to [Ctrl]+[C]^C
bballdave025@MY-MACHINE ~
$ cd C:\nothing_important # another one to watch out for is this one
bballdave025@MY-MACHINE /cygdrive/c/nothing_important
$ ls C:\nothing_important
ls: cannot access 'C:nothing_important': No such file or directory
bballdave025@MY-MACHINE /cygdrive/c/nothing_important
$ ls "C:\nothing_important"
nothing_at_all
bballdave025@MY-MACHINE /cygdrive/c/nothing_important
$ cd C:/
bballdave025@MY-MACHINE /cygdrive/c
$ cd nothing_important\nothing_at_all
-bash: cd: nothing_importantnothing_at_all: No such file or directory
我正在使用和扩展@mccoolive 在this answer 中给出的示例(关于 FFMPEG,但它显示了可能的问题)。
虽然我们实际上可以说处理路径的错误来自 Windows python,但我将这一点包括在内是为了看到即使是 Cygwin 的 bash(cd 和 ls)在 Windows 与 Windows 之间也存在问题。 Cygwin 路径。
有关更多详细信息,请查看 Cygwin 的 this documentation (archived)。
脚注
1. 有两种方法可以让我通过 Cygwin 终端更轻松地访问 Windows python。
第一个,也是我推荐使用的,是修改您的~/.bashrc 文件。我这样做如下。请注意,我在更改任何内容之前备份了我以前的 ~/.bashrc。
bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win
$ date && date +'%s'
Fri, May 1, 2020 2:01:46 PM
1588363306
bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win
$ cp ~/.bashrc ~/.bashrc.$(date +'%s').bak
bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win
$ find ~ -type f -name "*.bashrc.*.bak" | tail -1
/home/bballdave025/.bashrc.1588363346.bak
bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win
$ echo -e "\n\n# Allow access to Windows' version of python, e.g. for cv2\n"\
"alias pythonwin=/cygdrive/c/Users/bballdave025/AppData/Local/Programs/Python/Python38/python\n" >> \
~/.bashrc
bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win
$ source ~/.bashrc
让我们看看它是否有效。
bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win
$ pythonwin --version
Python 3.8.2
bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win
$ # That as compared to
bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win
$ python3 --version
Python 3.6.9
bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win
$ # and as compared to
bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win
$ python --version
Python 2.7.16
为了展示第一种方法相对于第二种方法的缺点,我将尝试找出这个pythonwin 功能的来源。使用我常用的which pythonwin 不起作用,whereis pythonwin、locate -b pythonwin、apropos pythonwin 也不起作用。我没有运行它,但find / -name "*pythonwin*" 也不会得到它。实际上,我必须搜索才能找到获取信息的方法(我的发现1、2、3、4、5、6、7)。可以通过command -v pythonwin 或type pythonwin 找到该信息。
但是……
bballdave025@MY-MACHINE ~
$ which pythonwin
which: no pythonwin in ( #the whole output of my `PATH`# )
注意aliases take precedence over the PATH。
第二个是使用符号链接。如果你想这样做,并且你已经运行了alias 的命令,你可以
一个。恢复到您的备份。就我而言,这将是
bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win
$ cp ~/.bashrc.1588363346.bak .bashrc
bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win
$ unalias pythonwin
b.随意打开~/.bashrc,然后手动删除我们添加的行。
现在,对于符号链接。我把它放在user-installed programs are supposed to go(archived, Ctrl + F for "/usr/local : Local hierarchy")所在的文件夹中,即/usr/local/bin/。我会在下面进行设置并检查它们。
bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win
$ ln -s /cygdrive/c/Users/13852/AppData/Local/Programs/Python/Python38/python.exe /usr/local/bin/pythonwin
bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win
$ pythonwin --version
Python 3.8.2
bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win
$ which pythonwin
/usr/local/bin/pythonwin
bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win
$ command -v pythonwin
/usr/local/bin/pythonwin
bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win
$ type pythonwin
pythonwin is hashed (/usr/local/bin/pythonwin)
bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win
$ readlink /usr/local/bin/pythonwin
/cygdrive/c/Users/13852/AppData/Local/Programs/Python/Python38/python.exe
如果您决定要删除此符号链接,请使用
bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop/testing_cv2_python_win
$ unlink /usr/local/bin/pythonwin
2. 确实,如果我使用'.' 作为我的搜索的基本目录进行搜索,那么脚本将会完美运行。但是,除了我给出的情况之外,对于规范路径,我不知道在哪些其他疯狂的边缘情况下不同的路径可能会失败。我认为拥有规范路径的情况足以使使用cygpath -w 解决方案非常可取。
3. 众所周知,Cygwin 和 Python 都认为以下两个文件名字符串相同。
C:\Users\bballdave025\Desktop\testing_cv2_python_win\image_1.png
C:/Users/bballdave025/Desktop/testing_cv2_python_win/image_1.png
当我没有以编程方式查找路径时,我实际上会尝试使用正斜杠 ('/')。