發(fā)布日期:2022-07-05 點(diǎn)擊率:27
在計(jì)算機(jī)視覺(jué)領(lǐng)域,實(shí)例分割是當(dāng)今最熱門的話題之一。
它包括圖像中對(duì)象的檢測(cè)/分割,即特定對(duì)象的定位及其所屬像素的關(guān)聯(lián)。像任何一種機(jī)器學(xué)習(xí)系統(tǒng)一樣,訓(xùn)練主干結(jié)構(gòu)需要大量圖像。更具體地說(shuō),需要大量注釋來(lái)訓(xùn)練神經(jīng)網(wǎng)絡(luò)的定位功能。
注釋是一項(xiàng)耗時(shí)的活動(dòng),可以決定項(xiàng)目是否會(huì)成功。因此,必須謹(jǐn)慎處理,以提高生產(chǎn)率。
在衛(wèi)星圖像領(lǐng)域,可以利用免費(fèi)數(shù)據(jù)集來(lái)利用研究人員或注釋人員以前所做的工作。這些數(shù)據(jù)集通常是由研究人員在從開(kāi)源圖像構(gòu)建數(shù)據(jù)集、進(jìn)行前后處理并用于訓(xùn)練和測(cè)試自己的人工智能研究系統(tǒng)后發(fā)布的。
語(yǔ)義分割和實(shí)例分割有點(diǎn)不同,但在建筑物的情況下,一個(gè)可以幫助另一個(gè)。
事實(shí)上,建筑物通常是獨(dú)特的,可以在任何圖像上進(jìn)行分離。利用這種考慮,可以從二值標(biāo)簽圖像中為每個(gè)建筑生成單獨(dú)的遮罩,然后用于更快地訓(xùn)練實(shí)例分割算法,如Mask RCNN。注釋不必手動(dòng)執(zhí)行,這是該技術(shù)的主要優(yōu)點(diǎn)。下面是一些如何做的提示!
JSON文件格式
Mask RCNN Matterport實(shí)現(xiàn)以及FAIR Detectron2平臺(tái)使用JSON文件為訓(xùn)練圖像數(shù)據(jù)集加載注釋。這種文件格式用于許多計(jì)算機(jī)科學(xué)應(yīng)用,因?yàn)樗试S以成對(duì)屬性值的格式輕松存儲(chǔ)和共享字母數(shù)字信息。
它是為Javascript語(yǔ)言構(gòu)建的,但如今,它被用于許多其他編程語(yǔ)言,如Python。專門的庫(kù)已經(jīng)建立起來(lái),能夠在Python代碼中以文本文件的形式生成和解析JSON格式的數(shù)據(jù)。VGG注釋工具格式中Mask RCNN使用的典型JSON文件將具有以下形狀:
{
"image1.png9259408": {
"filename": "image1.png",
"size": 9259408,
"regions": [
{
"shape_attributes": {
"name": "polygon",
"all_points_x": [
314,
55,
71,
303,
318,
538,
],
"all_points_y": [
1097,
1093,
1450,
1450,
1505,
1474,
]
},
"region_attributes": {
"class": "building"
}
},
{
"shape_attributes": {
"name": "rect",
"x": 515,
"y": 1808,
"width": 578,
"height": 185
},
"region_attributes": {
"class": "apple"
}
}
],
"file_attributes": {}
},
"0030fd0e6378.png236322": {
"filename": "0030fd0e6378.png",
"size": 236322,
"regions": [
{
"shape_attributes": {
"name": "polygon",
"all_points_x": [
122,
294,
258,
67,
32
],
"all_points_y": [
92,
113,
231,
221,
132
]
},
"region_attributes": {
"class": "apple"
}
},
{
"shape_attributes": {
"name": "circle",
"cx": 210,
"cy": 303,
"r": 47
},
"region_attributes": {
"class": "swan"
}
}
],
"file_attributes": {}
}
}
一個(gè)JSON注釋文件收集所有注釋數(shù)據(jù)。每個(gè)圖像注釋都堆積在一個(gè)大的JSON文件中。
一個(gè)圖像由其標(biāo)識(shí)符標(biāo)識(shí)。該標(biāo)識(shí)符由四個(gè)屬性描述:圖像的名稱(文件名)、其在磁盤上的大?。ù笮。⒆⑨尩男螤睿▍^(qū)域)和圖像上的一些元數(shù)據(jù)(文件屬性)。
每個(gè)注釋都可以由兩個(gè)元素來(lái)描述:形狀描述(形狀屬性)和注釋數(shù)據(jù)(區(qū)域?qū)傩裕?。形狀屬性描述由注釋的形狀(名稱)和兩個(gè)整數(shù)的有序列表(所有點(diǎn)x和所有點(diǎn)y)組成,它們表示構(gòu)成遮罩注釋的點(diǎn)的x和y坐標(biāo)。注釋數(shù)據(jù)region_attributes可以調(diào)整,注釋類可以保存以用于多類分割。
第四個(gè)標(biāo)識(shí)符屬性名為file_attributes,可用于存儲(chǔ)注釋圖像上的任何信息。
在語(yǔ)法方面,讓我們注意到大括號(hào){}通常用于分隔相同類型的元素,以及引用描述一個(gè)元素的屬性。方括號(hào)[]用于表示參數(shù)列表。
幸運(yùn)的是,Python有一個(gè)庫(kù)供我們讀寫JSON文件。使用帶有通用語(yǔ)法的import json代碼片段可以輕松加載它,以讀取和寫入文本文件。
在下一章中,我們將討論如何將二進(jìn)制標(biāo)簽圖像轉(zhuǎn)換為VGG注釋,尤其是如何使用JSON語(yǔ)法編寫注釋文件。
生成注釋JSON文件
本文提出的主要思想是將二進(jìn)制標(biāo)簽圖像轉(zhuǎn)換為VGG注釋格式的掩碼JSON文件。對(duì)二值標(biāo)簽圖像的每個(gè)形狀進(jìn)行個(gè)性化處理,以將其轉(zhuǎn)化為遮罩元素,例如分割。
轉(zhuǎn)換主要使用著名的OpenCV圖形庫(kù)執(zhí)行,該庫(kù)在Python中易于使用。
def Annot(preprocess_path, res=0.6, surf=100, eps=0.01):
"""
preprocess_path : path to folder with gt and images subfolder containing ground truth binary label image and visual imagery
res : spatial resolution of images in meter
surf : the minimum surface of roof considered in the study in square meter
eps : the index for Ramer–Douglas–Peucker (RDP) algorithm for contours approx to decrease nb of points describing a contours
"""
jsonf = {} # only one big annotation file
with open(os.path.join(preprocess_path,'via_region_data.json'), 'w') as js_file:
gt_path = os.path.join(preprocess_path, 'gt')
images_path = os.path.join(preprocess_path, 'images')
# All the elements in the images folders
lst = os.listdir(images_path)
for elt in tqdm(lst, desc='lst'):
# Read the binary mask, and find the contours associated
gray = cv2.imread(os.path.join(gt_path, elt))
imgray = cv2.cvtColor(gray, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(imgray, 127, 255, 0)
contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# https://www.pyimagesearch.com/2021/10/06/opencv-contour-approximation/
# Contours approximation based on Ramer–Douglas–Peucker (RDP) algorithm
areas = [cv2.contourArea(contours[idx])*res*res for idx in range(len(contours))]
large_contour = []
for i in range(len(areas)):
if areas[i]>surf:
large_contour.a(chǎn)ppend(contours[i])
approx_contour = [cv2.a(chǎn)pproxPolyDP(c, eps * cv2.a(chǎn)rcLength(c, True), True) for c in large_contour]
# -------------------------------------------------------------------------------
# BUILDING VGG ANNTOTATION TOOL ANNOTATIONS LIKE
if len(approx_contour) > 0:
regions = [0 for i in range(len(approx_contour))]
for i in range(len(approx_contour)):
shape_attributes = {}
region_attributes = {}
region_attributes['class'] = 'roof'
regionsi = {}
shape_attributes['name'] = 'polygon'
shape_attributes['all_points_x'] = approx_contour[i][:, 0][:, 0].tolist()
# https://stackoverflow.com/questions/26646362/numpy-array-is-not-json-serializable
shape_attributes['all_points_y'] = approx_contour[i][:, 0][:, 1].tolist()
regionsi['shape_attributes'] = shape_attributes
regionsi['region_attributes'] = region_attributes
regions[i] = regionsi
size = os.path.getsize(os.path.join(images_path, elt))
name = elt + str(size)
json_elt = {}
json_elt['filename'] = elt
json_elt['size'] = str(size)
json_elt['regions'] = regions
json_elt['file_attributes'] = {}
jsonf[name] = json_elt
json.dump(jsonf, js_file)
第一行是為真實(shí)標(biāo)簽和圖像文件夾構(gòu)建正確的文件夾路徑,并創(chuàng)建JSON文件注釋。
首先,使用cv2.findContours將二進(jìn)制遮罩切割成輪廓。大多數(shù)轉(zhuǎn)換(閾值、灰度轉(zhuǎn)換)實(shí)際上并不需要,因?yàn)閿?shù)據(jù)已經(jīng)是二值圖像。cv2.findContours函數(shù)提供一個(gè)等高線列表,作為一個(gè)點(diǎn)列表,這些點(diǎn)的坐標(biāo)在圖像的參考系中表示。
在大型建筑屋頂項(xiàng)目中,可以使用自定義OpenCV函數(shù)來(lái)導(dǎo)出屋頂表面,然后將其轉(zhuǎn)換為平方米,并僅選擇具有足夠面積的屋頂。在這種情況下,可以使用Ramer–Douglas–Peucker(RDP)算法來(lái)簡(jiǎn)化和近似檢測(cè)到的輪廓,以便更緊湊地存儲(chǔ)注釋數(shù)據(jù)。此時(shí),你應(yīng)該有一個(gè)點(diǎn)列表,這些點(diǎn)代表在二值圖像上檢測(cè)到的輪廓。
現(xiàn)在,你需要將整個(gè)輪廓點(diǎn)列表轉(zhuǎn)換為一個(gè)大的用于掩碼RCNN算法的via_region_data.json文件。對(duì)于JSON注釋,數(shù)據(jù)需要具有第一段中指定的格式。字典主要在將數(shù)據(jù)推送到JSON文件之前使用。
根據(jù)輪廓[]的數(shù)量,需要特定數(shù)量的 [:,0]才能獲取正確的數(shù)據(jù)。描述輪廓的整數(shù)數(shù)組必須轉(zhuǎn)換為JSON可序列化數(shù)據(jù)。制作VGG注釋JSON文件與制作俄羅斯玩偶非常相似。你可以創(chuàng)建一個(gè)空字典,指定其一個(gè)(或多個(gè))屬性的值,然后將其作為更高級(jí)別屬性的值傳遞,以將其封裝到更大的字典中。我們注意到,對(duì)于多類分割或?qū)ο髾z測(cè),region_attributes可以包含一個(gè)屬性類,該屬性類的掩碼在shape_attributes參數(shù)中指定。
最后,在將所有圖像數(shù)據(jù)放入JSON文件之前,每個(gè)圖像數(shù)據(jù)都存儲(chǔ)在一個(gè)大的“json”元素中,其名稱+大小字符串作為標(biāo)識(shí)符。這一點(diǎn)非常重要,因?yàn)槿绻看芜\(yùn)行新圖像時(shí)都寫入JSON文件,JSON文件的掩碼RCNN導(dǎo)入將失敗。這是因?yàn)閖son.load只讀取第一組大括號(hào){}的內(nèi)容,無(wú)法解釋下一組大括號(hào)。
就這樣!讓我們看看這個(gè)過(guò)程的結(jié)果是什么!
檢查注釋顯示
這一小章將展示上述過(guò)程的圖形化使用。使用的主要是美國(guó)地質(zhì)調(diào)查局通過(guò)國(guó)家地圖服務(wù)公開(kāi)發(fā)布的美國(guó)城市圖像(芝加哥、奧斯汀、舊金山)。
美國(guó)地質(zhì)調(diào)查局國(guó)家地理空間計(jì)劃提供的地圖服務(wù)和數(shù)據(jù)。該服務(wù)是開(kāi)源的,所以你可以對(duì)數(shù)據(jù)做任何你想做的事情!
在這篇文章中,處理了德克薩斯州奧斯汀附近的高分辨率圖像(空間分辨率=0.3米/像素)。
第一個(gè)圖像是視覺(jué)彩色圖像,通常以GeoTiff格式提供,它也包含嵌入的地理空間數(shù)據(jù)。它以美國(guó)城市環(huán)境的城市場(chǎng)景為特色。渲染由三個(gè)光譜視覺(jué)圖像構(gòu)建:通常的藍(lán)色、綠色和紅色。但在更復(fù)雜的圖像中,圖像供應(yīng)商可以提供近紅外圖像,以便能夠生成CNIR(彩色+近紅外圖像),以分析光譜圖像的不同方面。
第二個(gè)圖像顯示二進(jìn)制標(biāo)簽圖像??梢钥闯?,標(biāo)簽包含了與建筑物相關(guān)的每一個(gè)像素,即使是最小的彎曲形狀的像素。每個(gè)建筑都可以單獨(dú)識(shí)別,因?yàn)榻ㄖ荒苤丿B,這就證明了整個(gè)過(guò)程的合理性。
第三幅圖像由二值標(biāo)簽1和cv2檢測(cè)到的輪廓組成,以紅色突出顯示。顯示的等高線是來(lái)自O(shè)penCV函數(shù)的原始數(shù)據(jù),沒(méi)有被過(guò)濾掉,因此即使是最小的建筑也會(huì)被顯示出來(lái)。需要注意的是,cv2.findContours是一種像素級(jí)的轉(zhuǎn)換:由一個(gè)像素連接的兩座建筑將被分割在一起,而只有一行暗像素就足以將兩座相鄰的建筑分別分割。
第四幅圖像顯示具有過(guò)濾后的近似輪廓的二值標(biāo)簽圖像。正如第二章所說(shuō),就屋頂項(xiàng)目而言,對(duì)面積小于100平方米的建筑不感興趣。它還將執(zhí)行輪廓近似以減小注釋文件的大小。因此,僅在大型建筑周圍繪制輪廓,在某些情況下,輪廓與建筑形狀不完全匹配,無(wú)法啟發(fā)輪廓近似。
第五張也是最后一張圖像顯示了通常的實(shí)例分割可視化,可以使用inspect_roof_data等工具繪制。大型建筑的屋頂被單獨(dú)分割。
結(jié)論
本文展示的過(guò)程展示了如何將語(yǔ)義數(shù)據(jù)集轉(zhuǎn)換為實(shí)例分割訓(xùn)練數(shù)據(jù)集。然后可以使用它來(lái)有效地訓(xùn)練Mask-RCNN算法。該過(guò)程也可以重復(fù)使用和修改,以適應(yīng)具有不同輸入標(biāo)簽形狀的數(shù)據(jù)集。
原文標(biāo)題 : 自動(dòng)生成VGG圖像注釋文件