语义分割:基于openCV和深度学习(二)
語義分割:基于openCV和深度學(xué)習(xí)(二)
Semantic segmentation in images with OpenCV
開始吧-打開segment.py歸檔并插入以下代碼:
Semantic segmentation with
OpenCV and deep learning
import the necessary packages
import numpy as np
import argparse
import
imutils
import time
import cv2
從輸入必要的依賴包開始。對于這個(gè)腳本,推薦OpenCV 3.4.1或更高版本。可以按照一個(gè)安裝教程進(jìn)行操作—只要確保在執(zhí)行步驟時(shí)指定要下載和安裝的OpenCV版本。還需要安裝OpenCV便利功能包imutils-只需使用pip安裝該包:
Semantic segmentation with
OpenCV and deep learning
$ pip install --upgrade imutils
如果使用的是Python虛擬環(huán)境,不要忘記在使用pip安裝imutils之前使用work-on命令! 接下來,分析一下命令行參數(shù):
Semantic segmentation with
OpenCV and deep learning
#construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-m", “–model”, required=True,
help=“path
to deep learning segmentation model”)
ap.add_argument("-c", “–classes”, required=True,
help=“path
to .txt file containing class labels”)
ap.add_argument("-i", “–image”, required=True,
help=“path
to input image”)
ap.add_argument("-l", “–colors”, type=str,
help=“path
to .txt file containing colors for labels”)
ap.add_argument("-w", “–width”, type=int, default=500,
help=“desired
width (in pixels) of input image”)
args = vars(ap.parse_args())
此腳本有五個(gè)命令行參數(shù),其中兩個(gè)是可選的:
–模型:深入學(xué)習(xí)語義分割模型的途徑。
–類:包含類標(biāo)簽的文本文件的路徑。
–圖像:的輸入圖像文件路徑。 -
-顏色:顏色文本文件的可選路徑。如果沒有指定文件,則將為每個(gè)類分配隨機(jī)顏色。
–寬度:可選的所需圖像寬度。默認(rèn)情況下,該值為500像素。
如果不熟悉argparse和命令行參數(shù)的概念,一定要閱讀這篇深入介紹命令行參數(shù)的博客文章。 接下來,來分析類標(biāo)簽文件和顏色:
Semantic segmentation with
OpenCV and deep learning
#load the class label names
CLASSES = open(args[“classes”]).read().strip().split("\n")
if a colors file was supplied, load it from disk
if args[“colors”]:
COLORS = open(args[“colors”]).read().strip().split("\n")
COLORS
= [np.array(c.split(",")).astype(“int”) for c in COLORS]
COLORS = np.array(COLORS, dtype=“uint8”)
otherwise, we need to randomly generate RGB colors for
each class
#label
else:
#initialize a list of colors to represent each class label in
the mask (starting with ‘black’ for the
background/unlabeled
#regions)
np.random.seed(42)
COLORS
= np.random.randint(0, 255, size=(len(CLASSES) - 1, 3),
dtype=“uint8”)
COLORS
= np.vstack([[0, 0, 0], COLORS]).astype(“uint8”)
從提供的文本文件中將類加載到內(nèi)存中,該文件的路徑包含在命令行args字典(第23行)中。
如果文本文件中為每個(gè)類標(biāo)簽提供了一組預(yù)先指定的顏色(每行一個(gè)),將它們加載到內(nèi)存中(第26-29行)。否則,為每個(gè)標(biāo)簽隨機(jī)生成顏色(第33-40行)。
出于測試目的(并且由于有20個(gè)類),使用OpenCV繪圖函數(shù)創(chuàng)建一個(gè)漂亮的顏色查找圖例:
Semantic segmentation with
OpenCV and deep learning
#initialize the legend visualization
legend = np.zeros(((len(CLASSES) * 25) + 25, 300, 3), dtype=“uint8”)
loop over the class names + colors
for (i, (className, color)) in enumerate(zip(CLASSES,
COLORS)):
draw the class name + color on the legend
color =
[int? for c in color]
cv2.putText(legend, className, (5, (i * 25) + 17),
cv2.FONT_HERSHEY_SIMPLEX,
0.5, (0, 0, 255), 2)
cv2.rectangle(legend, (100, (i * 25)), (300, (i * 25) + 25),
tuple(color), -1)
生成一個(gè)圖例可視化,就可以很容易地可視化地將類標(biāo)簽與顏色關(guān)聯(lián)起來。圖例由類標(biāo)簽及其旁邊的彩色矩形組成。這是通過創(chuàng)建畫布(第43行)和使用循環(huán)動態(tài)構(gòu)建圖例(第46-52行)快速創(chuàng)建的。本文中介紹了繪畫基礎(chǔ)知識。
結(jié)果如下:
Figure 2: Our deep learning semantic segmentation class color legend generated with OpenCV.
下一個(gè)區(qū)塊將進(jìn)行深度學(xué)習(xí)細(xì)分:
Semantic segmentation with OpenCV and deep learning
#load our serialized model from disk
print("[INFO] loading model…")
net =
cv2.dnn.readNet(args[“model”])
#load the input image, resize it, and construct a blob from it,
but keeping mind mind that the original input image
dimensions
#ENet was trained on was 1024x512
image = cv2.imread(args[“image”])
image =
imutils.resize(image, width=args[“width”])
blob = cv2.dnn.blobFromImage(image, 1 / 255.0, (1024, 512), 0,
swapRB=True,
crop=False)
#perform a forward pass using the segmentation model
net.setInput(blob)
start =
time.time()
output = net.forward()
end =
time.time()
#show the amount of time inference took
print("[INFO] inference took {:.4f} seconds".format(end - start))
為了使用Python和OpenCV對圖像進(jìn)行深入的語義分割:
加載模型(第56行)。構(gòu)造一個(gè)blob(第61-64行),在這篇博客文章中使用的ENet模型是在1024×512分辨率的輸入圖像上訓(xùn)練的,將在這里使用相同的方法。可以在這里了解更多關(guān)于OpenCV的blob是如何工作的。將blob設(shè)置為網(wǎng)絡(luò)的輸入(第67行),并執(zhí)行神經(jīng)網(wǎng)絡(luò)的前向傳遞(第69行)。用時(shí)間戳將forward pass語句括起來。將經(jīng)過的時(shí)間打印到第73行的終端。
在腳本的其余行中,將生成一個(gè)顏色映射,覆蓋在原始圖像上。每個(gè)像素都有一個(gè)對應(yīng)的類標(biāo)簽索引,能夠在屏幕上看到語義分割的結(jié)果。
首先,需要從輸出中提取卷維度信息,然后計(jì)算類圖和顏色掩碼:
Semantic segmentation with
OpenCV and deep learning
#infer the total number of classes along with the spatial dimensions
of the mask image via the shape of the output array
(numClasses,
height, width) = output.shape[1:4]
our
output class ID map will be num_classes x height x width in
size, so we take the argmax to find the class label
with the
#largest probability for each and every (x, y)-coordinate in the
image
classMap
= np.argmax(output[0], axis=0)
#given the class ID map, we can map each of the class IDs to its
corresponding color
mask = COLORS[classMap]
在第77行確定輸出體積的空間維度。接下來,讓找到輸出卷的每個(gè)(x,y)-坐標(biāo)的概率最大的類標(biāo)簽索引(第83行)。這就是現(xiàn)在所知道的類映射,它包含每個(gè)像素的類索引。 給定類ID索引,可以使用NumPy數(shù)組索引“神奇地”(更不用說超級高效地)查找每個(gè)像素(第87行)對應(yīng)的可視化顏色。彩色mask版將透明地覆蓋在原始圖像上。 讓完成腳本:
Semantic segmentation with OpenCV and deep learning
resize the mask and class map such that its dimensions match the
original size of the input image (we’re not using the
class map
#here for anything else but this is how you would resize it just in
case you wanted to extract specific pixels/classes)
mask =cv2.resize(mask, (image.shape[1],
image.shape[0]),
interpolation=cv2.INTER_NEAREST)
classMap
= cv2.resize(classMap, (image.shape[1],
image.shape[0]),
interpolation=cv2.INTER_NEAREST)
perform a weighted combination of the input image with
the mask to
#form an output visualization
output = ((0.4 * image) + (0.6 * mask)).astype(“uint8”)
show the input and output images
cv2.imshow(“Legend”, legend)
cv2.imshow(“Input”, image)
cv2.imshow(“Output”, output)
cv2.waitKey(0)
調(diào)整掩碼和類映射的大小,使它們與輸入圖像(第93-96行)具有完全相同的維度。為了保持原始的類id/mask值,使用最近鄰插值而不是三次、二次等插值是非常重要的。 現(xiàn)在大小是正確的,創(chuàng)建了一個(gè)“透明的顏色覆蓋”,通過覆蓋的原始圖像(第100行)的遮罩。這使能夠輕松地可視化分割的輸出。關(guān)于透明覆蓋層以及如何構(gòu)建它們的更多信息,可以在本文中找到。最后,圖例和原始+輸出圖像顯示在第103-105行的屏幕上。
單圖像分割結(jié)果
在使用本節(jié)中的命令之前,請確保獲取此博客文章的“下載”。為了方便起見,在zip文件中提供了模型+相關(guān)文件、圖像和Python腳本。在終端中提供的命令行參數(shù)對于復(fù)制結(jié)果很重要。如果不熟悉命令行參數(shù),請?jiān)诖颂幜私馑鼈儭?zhǔn)備好后,打開一個(gè)終端并導(dǎo)航到項(xiàng)目,然后執(zhí)行以下命令:
Semantic segmentation with
OpenCV and deep learning
$python segment.py --model enet-cityscapes/enet-model.net \
–classes enet-cityscapes/enet-classes.txt \
–colors
enet-cityscapes/enet-colors.txt \
–image images/example_01.png
[INFO]
loading model…
[INFO] inference took 0.2100
seconds
圖3:OpenCV的語義分割顯示了道路、人行道、人、自行車、交通標(biāo)志等等!
注意分割的精確程度-它清楚地分割類并準(zhǔn)確地識別人和自行車(自動駕駛汽車的安全問題)。道路,人行道,汽車,甚至樹葉都被識別出來了。
嘗試另一個(gè)示例,只需將–image命令行參數(shù)更改為不同的圖像:
Semantic segmentation with
OpenCV and deep learning
$
python segment.py --model enet-cityscapes/enet-model.net \
–classes enet-cityscapes/enet-classes.txt \
–colors
enet-cityscapes/enet-colors.txt \
–image images/example_02.jpg
[INFO]
loading model…
[INFO] inference took 0.1989
seconds
在這里插入圖片描述
圖4中的結(jié)果展示了這個(gè)語義分割模型的準(zhǔn)確性和清晰性。汽車、道路、樹木和天空都有清晰的標(biāo)記。下面是另一個(gè)例子:
Semantic segmentation with
OpenCV and deep learning
$
python segment.py --model enet-cityscapes/enet-model.net \
–classes enet-cityscapes/enet-classes.txt \
–colors
enet-cityscapes/enet-colors.txt \
–image images/example_03.png
[INFO]
loading model…
[INFO] inference took 0.1992
seconds
上圖是一個(gè)更復(fù)雜的場景,但ENet仍然可以分割走在車前的人。不幸的是,該模型錯(cuò)誤地將道路分類為人行道,但可能是因?yàn)槿藗冊谌诵械郎闲凶摺W詈笠粋€(gè)例子:
Semantic segmentation with
OpenCV and deep learning
$
python segment.py --model enet-cityscapes/enet-model.net \
–classes enet-cityscapes/enet-classes.txt \
–colors
enet-cityscapes/enet-colors.txt \
–image images/example_04.png
[INFO]
loading model…
[INFO] inference took 0.1916
seconds
通過ENet發(fā)送的最終圖像顯示了模型如何在道路、人行道、樹葉、人物等其他場景類別中清晰地分割卡車與汽車。
總結(jié)
以上是生活随笔為你收集整理的语义分割:基于openCV和深度学习(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 语义分割:基于openCV和深度学习(一
- 下一篇: 虚拟几何纹理(上)