圖片標註(Image Annotation)是物體檢測等工作的基礎,就是使用矩形框標註出圖片中的物體,同時指定合適的標籤。目前,比較常用的標註工具就是LabelImg。LabelImg提供可視化的標註操作界面,將圖片的標註信息存入同名的XML文件中。
本文地址:https://blog.csdn.net/caroline_wendy/article/details/80435225
在LabelImg工程的主頁,有一行對於操作系統的說明:
即目前的可執行文件,僅支持Windows和Linux,macOS需要從源碼構建應用。那麼,如何在Mac中構建LabelImg應用呢?
已編譯完成的LabelImg的下載地址,在Mac中,可以直接使用。
GitHub
LabelImg是一個GitHub的開源工程,除了源碼之外,還有一些應用圖標和鏈接庫等文件,導致工程較大,下載較慢。
其實,GitHub的下載鏈接是自帶加速功能,由於國內的域名污染,在訪問鏈接時,需要跨越較多的無效域名,導致下載較慢,參考。因此,找到GitHub的真實地址,直接訪問,就可以加快下載速度。這個方法,也適用於訪問其他較慢的國外下載鏈接。
找到國外域名的真實IP地址,可以直接使用IPAddress,或訪問lookup接口均可。
輸入域名,即可查詢真實的IP地址,例如查詢github.com
:
注意:查詢的IP地址可能會不同,一般而言,直接使用國外的IP地址,比使用國內域名服務器的地址,能夠獲得更快下載速度。
與GitHub相關的域名有兩個,即:
- github.com:真實IP 192.30.253.xxx;
- github.global.ssl.fastly.net:真實IP 151.101.13.xxx;
查詢完成之後,將域名和域名真實IP,寫入Mac的hosts文件中,由於hosts是系統文件,需要獲取管理員權限sudo進行寫入:
sudo vi /etc/hosts
在hosts的末尾添加:
192.30.253.xxx github.com
151.101.13.xxx github.global.ssl.fastly.net
159.122.18.xxx dl.bintray.com
除GitHub的鏈接之外,也可以添加其他國外域名的IP,如dl.bintray.com
等。
Conda
在Pip源中,Qt的相關包安裝異常,因而,使用Conda源作爲Python環境。Conda與Pip的功能類似,近似於Pip與Virtualenv的結合,用於隔離Python的系統環境。由於僅僅使用Conda的Python功能,直接安裝Conda的Miniconda版本即可,選擇Python 2.7版本。
Conda的Python版本是編譯Conda功能所用的版本,與Conda所創建虛擬環境的Python版本無關,也就是說,Python 2.7版本的Conda也可以創建Python 3.6版本的虛擬環境。
下載Miniconda的sh腳本,直接執行即可,安裝目錄位於~/miniconda2
中,conda可執行文件位於miniconda2的bin文件夾下,其中就包含conda命令。由於Conda的系統環境設置問題,導致覆蓋原有的Python命令路徑,需要修改終端配置。
終端
終端shell是oh-my-zsh,即zsh終端。在zsh終端啓動時,執行.zshrc
腳本。因此,在.zshrc
的末尾添加:
source ~/.bash_profile
即執行.bash_profile
腳本。
將定製的環境配置,添加至.bash_profile
中,用於在zsh中執行:
- 將定製的可執行文件夾
~/bin
放入系統路徑PATH中; - 將Python路徑PYTHONPATH指定爲系統的python;
- 修改Miniconda2配置,將默認Python路徑位於
miniconda2/bin
路徑之前,防止干擾;
即:
export PATH="$PATH:/Users/[name]/bin"
export PYTHONPATH="/usr/local/bin/python"
# added by Miniconda2 installer
export PATH="$PATH:/Users/[name]/miniconda2/bin"
在~/bin
中,創建conda的軟鏈接:
ln -s conda /Users/[name]/miniconda2/bin/conda
即
conda -> /Users/[name]/miniconda2/bin/conda
最後,執行source ~/.bash_profile
或重啓終端,將命令導入至shell環境,直接輸入conda即可運行命令,
shell的調用流程:zsh -> .zshrc -> .bash_profile -> bin -> conda。
其他shell命令的添加方法,與此類似。
操作
conda創建虛擬環境,如Python 3.x版本的py3,
conda create -n py3 python=3
source activate py3
虛擬環境py3位於miniconda2/envs/
中,如果重名,刪除即可。
安裝Python包:
conda install pyqt
取消激活環境
source deactivate
conda的操作簡單便捷,如果一些pip源的包沒有收錄至conda源,可以在Google中搜索conda的個人源。
其他Conda命令,請參考。
加速
conda源位於國外,速度較慢,可以切換爲國內的清華鏡像,執行以下設置即可。
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --set show_channel_urls yes
conda的config文件位於~/.condarc
中。
LabelImg
系統環境已經配置完成,GitHub和Conda均可高效使用,可以開始構建LabelImg項目了。
在GitHub中下載labelImg工程:
git clone https://github.com/tzutalin/labelImg.git
創建conda的Python虛擬環境,下載依賴包,參考,環境是Qt5 + Python 2:
conda create -n py2 python=2
source activate py2
conda install qt
conda install pyqt
conda install libxml2
conda install lxml
make qt5
python labelImg.py
其中的conda安裝qt,也可以替換爲brew安裝
conda install qt
conda install pyqt
或
brew install qt
brew install pyqt
labelImg.py是程序入口,最終的啓動效果:
錯誤梳理
爲什麼不使用Qt4?
因爲Qt4與Mac系統的10.13(High Sierra)版本兼容性不好,可以編譯成功,但是無法讀取jpeg等類型的圖片,所以只能選擇Qt5進行編譯。
爲什麼安裝和編譯的是Qt5,卻顯示找不到Qt4?
提示找不到Qt4的Bug,如下:
Traceback (most recent call last):
File "labelImg.py", line 1453, in <module>
sys.exit(main())
File "labelImg.py", line 1449, in main
app, _win = get_main_app(sys.argv)
File "labelImg.py", line 1442, in get_main_app
argv[3] if len(argv) >= 4 else None)
File "labelImg.py", line 98, in __init__
self.settings.load()
File "/Users/wang/exercises/labelImg/libs/settings.py", line 33, in load
self.data = pickle.load(f)
File "/Users/wang/miniconda2/envs/py2/lib/python2.7/pickle.py", line 1384, in load
return Unpickler(file).load()
File "/Users/wang/miniconda2/envs/py2/lib/python2.7/pickle.py", line 864, in load
dispatch[key](self)
File "/Users/wang/miniconda2/envs/py2/lib/python2.7/pickle.py", line 1139, in load_reduce
value = func(*args)
ImportError: No module named PyQt4.QtCore
原因是,代碼中導入包的異常處理,當無法加載Qt5時,就選擇加載Qt4,這段邏輯簡直無厘頭,看似聰明,實則干擾調試,也不提示“無法找到 Qt5”的異常,讓開發者誤以爲還要安裝Qt4。
try:
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
except ImportError:
from PyQt4.QtGui import *
from PyQt4.QtCore import *
實際上,Qt5並未直接安裝至系統環境中,而是安裝在Python的site-packages中,即:
/usr/local/lib/python2.7/site-packages/
將這個包的文件夾,導入至Python路徑即可
export PYTHONPATH="$PYTHONPATH:/usr/local/lib/python2.7/site-packages/"
爲什麼包含兩份Qt的二進制文件?
提示有兩個Qt二進制文件的集合,如下:
objc[32802]: Class RunLoopModeTracker is implemented in both xxx and yyy. One of the two will be used. Which one is undefined.
QObject::moveToThread: Current thread (0x7fefa3512020) is not the object's thread (0x7fffb38b9380).
Cannot move to target thread (0x7fefa3512020)
You might be loading two sets of Qt binaries into the same process. Check that all plugins are compiled against the right Qt binaries. Export DYLD_PRINT_LIBRARIES=1 and check that only one set of binaries are being loaded.
This application failed to start because it could not find or load the Qt platform plugin "cocoa"
in "".
Available platform plugins are: cocoa, minimal, offscreen.
Reinstalling the application may fix this problem.
原因是,在Mac系統中,使用brew安裝一遍Qt,又使用conda安裝一遍Qt,兩個包重疊使用,卸載一個即可,優先卸載conda安裝的Qt,執行以下操作:
brew install qt
brew install pyqt
conda uninstall pyqt
conda uninstall qt
爲什麼提示Qt4和Qt5同時存在?
提示同時使用PyQt4和PyQt5,如下:
Traceback (most recent call last):
File "labelImg.py", line 1453, in <module>
sys.exit(main())
File "labelImg.py", line 1449, in main
app, _win = get_main_app(sys.argv)
File "labelImg.py", line 1442, in get_main_app
argv[3] if len(argv) >= 4 else None)
File "labelImg.py", line 98, in __init__
self.settings.load()
File "/Users/wang/exercises/labelImg/libs/settings.py", line 33, in load
self.data = pickle.load(f)
File "/Users/wang/miniconda2/envs/py2/lib/python2.7/pickle.py", line 1384, in load
return Unpickler(file).load()
File "/Users/wang/miniconda2/envs/py2/lib/python2.7/pickle.py", line 864, in load
dispatch[key](self)
File "/Users/wang/miniconda2/envs/py2/lib/python2.7/pickle.py", line 1139, in load_reduce
value = func(*args)
RuntimeError: the PyQt4.QtCore and PyQt5.QtCore modules both wrap the QObject class
根據錯誤位置定位至settings.py的加載pkl數據操作,原因是.labelImgSettings.pkl
文件可能是用Qt4生成的,刪除即可,應用則會重新生成。
self.path = os.path.join(home, '.labelImgSettings.pkl')
還有類似的PyQt4和PyQt5同時存在的問題:
Traceback (most recent call last):
File "labelImg.py", line 1453, in <module>
sys.exit(main())
File "labelImg.py", line 1449, in main
app, _win = get_main_app(sys.argv)
File "labelImg.py", line 1442, in get_main_app
argv[3] if len(argv) >= 4 else None)
File "labelImg.py", line 415, in __init__
self.filePath = ustr(defaultFilename)
File "/Users/wang/exercises/labelImg/libs/ustr.py", line 7, in ustr
from PyQt4.QtCore import QString
RuntimeError: the PyQt4.QtCore and PyQt5.QtCore modules both wrap the QObject class
根據錯誤位置定位至ustr.py文件,原因是引用Qt4的包,直接註釋或者使用Qt5重寫這一段邏輯,即可。
import sys
def ustr(x):
'''py2/py3 unicode helper'''
if sys.version_info < (3, 0, 0):
# from PyQt4.QtCore import QString
if type(x) == str:
return x.decode('utf-8')
# if type(x) == QString:
# return unicode(x)
return x
else:
return x # py3
LabelImg圖片標註工具並不完美,不過已經可以使用,爲標註工作提供了便捷。
已編譯完成的LabelImg的下載地址,在Mac中,可以直接使用。
OK, that’s all! Enjoy it!