深度学习图像标注工具labelme
來源:極客Merry
前言
在深度學習中若是沒有帶標注的數據,這可能會阻礙研究的進展,所以深度學習第一步就是制作數據集,手動去標注一些數據。LabelMe就是這樣一個在線的圖像數據標注工具:
LabelMe工具地址
http://labelme.csail.mit.edu/Release3.0/
今天要介紹的圖像標注工具是受到LabelMe啟發的,使用Python和PyQT進行重寫的一個離線工具labelme:
labelme的GitHub地址
https://github.com/wkentaro/labelme
labelme可以通過多邊形,矩形,圓形,直線和點的方式對圖像進行標注,能夠滿足語義分割和目標檢測等任務的標注要求。同時,labelme通過json文件存儲標注的信息。
01
labelme安裝
各個平臺的安裝方法在GitHub上已有說明,我使用的是Win10,在Win10,Python3環境下的安裝也很簡單:
pip?install?pyqt5
pip?install?labelme
如果安裝速度過慢,可以考慮換源:
pip?install?labelme??-i?https://pypi.tuna.tsinghua.edu.cn/simple
安裝完成后,在命令行執行以下命令,就會出現labelme的界面
labelme
然后就可以對圖像進行標注了。Open選項是打開一張圖像,對單張圖像進行標注,OpenDir選項是選中要標記的圖像文件夾,對文件夾內的所有圖像進行標注。
02
語義分割標注
點擊"open",打開需要標注的圖像,選擇"CreatePolygons",然后對目標區域進行標注。
"CreatePolygons"是采用多邊形方式標注,同樣有矩形(Rectangle),圓形(Circle),線段(Line)和點(Point)的方式進行標注,可根據需要自由選擇。
標注完成后,點擊"save"會生成一個json文件,這個文件就保存了圖像標注的信息。打開json文件看看里面都是什么東東。限于篇幅原因,只展示關鍵的數據信息。
下面的json文件只展示了桌子的標注信息(上圖中兩個人的標注信息由于太長,故刪去)。可以看到,"shapes"字段包含了整幅圖像所有區域的標注點信息,具體的各個區域標注的點的信息都存在"points"里,它表示的是圖像上構成多邊形標注的各點坐標,"label"指明該目標區域的類別,"imageData"參數保存了原始圖像的信息。
{"version":?"4.5.7","flags":?{},"shapes":?[{"label":?"tabel","points":?[[304.34715025906735,274.3523316062176],[330.7720207253886,268.13471502590676],[367.0414507772021,268.9119170984456],[393.98445595854923,279.01554404145077],[422.74093264248705,295.0777202072539],[432.0673575129534,316.0621761658031],[426.6269430051814,331.0880829015544],[422,337],[292,337],[277.4041450777202,336.7875647668394],[273.25906735751295,303.8860103626943],[283.10362694300517,290.1554404145078]],"group_id":?null,"shape_type":?"polygon","flags":?{}}],"imagePath":?"2011_000003.jpg","imageData":?"巨長巨長的圖像數據","imageHeight":?338,"imageWidth":?500
}
然后將json文件轉換為對應的標簽圖像。進入json文件所在目錄下,在命令行執行以下命令
labelme_json_to_dataset?2011_000003.json
在同一級目錄下會生成一個與json同名的文件夾,里面有四個文件:
"label.png"就是語義分割需要的標簽數據了。這張圖像標注了兩類區域(加上背景總共三類),一類是"person",另一類是"tabel",同一類別的區域用同一種顏色填充。
讀取"label.png"看看里面底層數據都是什么妖魔鬼怪:寫一個腳本將圖像數據轉換為ASCII碼,并且保存到txt文件中,這個過程有點像是圖像轉字符畫。
import?numpy?as?np
from?PIL?import?Imagepng_file?=?"label.png路徑"
img?=?Image.open(png_file)
img?=?img.resize((int(img.size[0]*0.25),int(img.size[1]*0.25)))
print(img.size)img_arr?=?np.asarray(img)
#?統計圖像中的像素點數值
label?=?np.unique(img_arr)
print(label)height,?width?=?img_arr.shape
print(height,?width)img2code?=?''
for?i?in?range(height):for?j?in?range(width):#pixel?=?img.getpixel((j,?i))#img2code?+=?ascii(pixel)img2code?+=?ascii(img_arr[i][j])img2code?+=?'\n'fo?=?open('txt存儲路徑',?'w')
fo.write(img2code)
fo.close()
打開剛剛保存的txt文件,因為太大全屏顯示不了,將字體大小設置為七號,可以看到效果如下。字符畫的寬高比例和原圖不一樣,這是因為豎直方向上顯示字符占用的空間大小和水平方向上不一樣。
從上圖可以看出,最終得到的標簽圖像,底層存儲的數值按不同類別區域設置為不同數值,背景的每個像素數值設置為0,person的每個像素數值設為1,tabel的每個像素數值設為2。
03
批量轉換json為標簽圖像
"labelme_json_to_dataset"這個命令能將json文件轉為標簽數據,但是它一次只能轉換一個,若是有成千上萬張圖像簡直難以想象,本來標注完圖像已經頭昏腦脹,難道還要我一個一個轉換?不可能的!這時需要自己寫個腳本來幫我們完成這個任務。
第一種方式借助于labelme提供的"labelme_json_to_dataset"這個命令。利用os.system()函數批量轉換json文件,每個json生成的同名文件夾與json在同一級目錄下。
import?osjson_path?=?"json文件保存路徑"for?filename?in?os.listdir(json_path):os.system("labelme_json_to_dataset?"+os.path.join(json_path,filename))
第二種方式使用labelme提供的API。使用img_b64_to_arr()函數,將json文件中"iamgeData"字段的字符轉換為原始圖像;然后根據json文件中"shapes"字段的標注信息,使用labelme_shapes_to_label()函數獲取到標簽圖像lbl。
有童鞋可能會發現,此時的lbl標簽圖像一片漆黑,什么也沒有。這是因為圖像中各點的像素值是標簽對應的數字(如同上面畫的字符畫),而這些數字都很小:0,1,2,3....,而黑色對應的像素值為0,所以lbl圖像的顏色和黑色非常接近,看起來就是一片漆黑。
這時我們只需要給圖像上色就可以了:使用putpalette()函數,而且我們可以自定義各個類別區域的顏色。
import?json
import?os
import?numpy?as?np
from?PIL?import?Image
from?labelme?import?utilsdef?json2mask_multi(json_path,?save_path):if?not?os.path.exists(save_path):os.makedirs(save_path)for?json_name?in?os.listdir(json_path):data?=?json.load(open(os.path.join(json_path,?json_name)))json_name?=?json_name.split('.')[0]#?根據imageData字段的字符可以得到原圖像img?=?utils.img_b64_to_arr(data['imageData'])#?lbl為label圖像(用類別名對應的數字來標,背景為0)#?lbl_names為label名和數字的對應關系字典lbl,?lbl_names?=?utils.labelme_shapes_to_label(img.shape,?data['shapes'])mask?=?Image.fromarray(lbl).convert('L')# putpalette給對象加上調色板,相當于上色:R,G,B#?三個數一組,對應于RGB通道,可以自己定義標簽顏色mask.putpalette([0,?0,?0,??255,?0,?255,255,?255,?0,128,?128,?128])mask.save(os.path.join(save_path,?json_name?+?".png"))json_path?=?"json文件存儲路徑"
save_path?=?"標簽圖像的保存路徑"
json2mask_multi(json_path,save_path)
本文只是對labelme簡單介紹了一番,因為自己在做語義分割時需要做一些標注,所以只介紹了語義分割上的應用,而labelme還可以滿足目標檢測和圖像分類任務的標注要求,這些功能就留給各位童鞋去探索研究,這里就不一一展開來說明。
-------?End -------
點右下角「在看」與轉發
是對我們最大的支持
特別推薦下公眾號「價值前瞻」,分享讀書、成長和投資思考,歡迎來串門。
回復「書單」?可獲取精選書單一份,包括《如何閱讀 一本書》、《巴菲特之道》、《金字塔原理》、高瓴張磊的《價值》、《投資最重要的事》、《戴維斯王朝》等書籍的筆記內容或思維導圖
價 值 前 瞻
做一個有遠見的人
掃碼關注,查看更多內容
總結
以上是生活随笔為你收集整理的深度学习图像标注工具labelme的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中获取文件名不要扩展名_如何批量修改文件
- 下一篇: 将字符串添加负数_Go语言实现LeetC