LabelImg 圖片標註工具 for Mac

LabelImg

圖片標註(Image Annotation)是物體檢測等工作的基礎,就是使用矩形框標註出圖片中的物體,同時指定合適的標籤。目前,比較常用的標註工具就是LabelImg。LabelImg提供可視化的標註操作界面,將圖片的標註信息存入同名的XML文件中。

本文地址https://blog.csdn.net/caroline_wendy/article/details/80435225

在LabelImg工程的主頁,有一行對於操作系統的說明:

macOS

即目前的可執行文件,僅支持Windows和Linux,macOS需要從源碼構建應用。那麼,如何在Mac中構建LabelImg應用呢?

已編譯完成的LabelImg的下載地址,在Mac中,可以直接使用。

GitHub

LabelImg是一個GitHub的開源工程,除了源碼之外,還有一些應用圖標和鏈接庫等文件,導致工程較大,下載較慢。

其實,GitHub的下載鏈接是自帶加速功能,由於國內的域名污染,在訪問鏈接時,需要跨越較多的無效域名,導致下載較慢,參考。因此,找到GitHub的真實地址,直接訪問,就可以加快下載速度。這個方法,也適用於訪問其他較慢的國外下載鏈接。

找到國外域名的真實IP地址,可以直接使用IPAddress,或訪問lookup接口均可。

IPAddress

輸入域名,即可查詢真實的IP地址,例如查詢github.com

IP

注意:查詢的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版本。

Miniconda

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是程序入口,最終的啓動效果:

LabelImg

錯誤梳理

爲什麼不使用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!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章