Prologs
Tagad internetÄ cirkulÄ video, kurÄ redzams, kÄ Teslas autopilots redz ceļu.
Man jau ilgu laiku ir gribÄjies pÄrraidÄ«t video, kas bagÄtinÄts ar detektoru, turklÄt reÄllaikÄ.
ProblÄma ir tÄda, ka es vÄlos pÄrraidÄ«t video no Raspberry, un neironu tÄ«kla detektora veiktspÄja tajÄ atstÄj daudz vÄlamo.
Intel Neural Computer Stick
Es apsvÄru dažÄdus risinÄjumus.
Š
Lai gan Intel nodroÅ”ina pÄrveidotÄjus galvenajÄm sistÄmÄm, pastÄv vairÄkas nepilnÄ«bas.
PiemÄram, vajadzÄ«gÄ tÄ«kla formÄts var bÅ«t nesaderÄ«gs, un, ja tas ir saderÄ«gs, tad daži slÄÅi var netikt atbalstÄ«ti ierÄ«cÄ, un, ja tie tiek atbalstÄ«ti, tad konvertÄÅ”anas procesÄ var rasties kļūdas, kuru rezultÄtÄ izejÄ saÅemam dÄ«vainas lietas.
KopumÄ, ja vÄlaties kaut kÄdu patvaļīgu neironu tÄ«klu, tas var nedarboties ar NCS. TÄpÄc es nolÄmu mÄÄ£inÄt atrisinÄt problÄmu, izmantojot visizplatÄ«tÄkos un pieejamÄkos rÄ«kus.
MÄkonis
AcÄ«mredzama alternatÄ«va vietÄjam aparatÅ«ras risinÄjumam ir pÄriet uz mÄkoni.
Gatavi varianti - manas acis skrien mežonīgas.
Visi vadÄ«tÄji:
... Un desmitiem mazÄk zinÄmu.
IzvÄle starp Å”o Ŕķirni nepavisam nav vienkÄrÅ”a.
Un es nolÄmu neizvÄlÄties, bet ietÄ«t veco labo darba shÄmu uz OpenCV programmÄ Docker un palaist to mÄkonÄ«.
Å Ä«s pieejas priekÅ”rocÄ«ba ir elastÄ«ba un kontrole - jÅ«s varat mainÄ«t neironu tÄ«klu, hostingu, serveri - kopumÄ jebkura kaprÄ«ze.
Serveris
SÄksim ar vietÄjo prototipu.
TradicionÄli es izmantoju Flask REST API, OpenCV un MobileSSD tÄ«klam.
InstalÄjot paÅ”reizÄjÄs versijas Docker, es atklÄju, ka OpenCV 4.1.2 nedarbojas ar mobilo SSD v1_coco_2018_01_28, un man bija jÄatgriežas uz pÄrbaudÄ«to versiju 11/06_2017.
Pakalpojuma sÄkumÄ mÄs ielÄdÄjam klaÅ”u nosaukumus un tÄ«klu:
def init():
tf_labels.initLabels(dnn_conf.DNN_LABELS_PATH)
return cv.dnn.readNetFromTensorflow(dnn_conf.DNN_PATH, dnn_conf.DNN_TXT_PATH)
VietÄjÄ dokÄ (ne pÄrÄk jaunÄ klÄpjdatorÄ) tas aizÅem 0.3 sekundes, Raspberry - 3.5.
SÄksim aprÄÄ·inu:
def inference(img):
net.setInput(cv.dnn.blobFromImage(img, 1.0/127.5, (300, 300), (127.5, 127.5, 127.5), swapRB=True, crop=False))
return net.forward()
Docker - 0.2 sek, Raspberry - 1.7.
Tensora izplÅ«des pÄrvÄrÅ”ana par lasÄmu JSON:
def build_detection(data, thr, rows, cols):
ret = []
for detection in data[0,0,:,:]:
score = float(detection[2])
if score > thr:
cls = int(detection[1])
a = {"class" : cls, "name" : tf_labels.getLabel(cls), "score" : score}
a["x"] = int(detection[3] * cols)
a["y"] = int(detection[4] * rows)
a["w"] = int(detection[5] * cols ) - a["x"]
a["h"] = int(detection[6] * rows) - a["y"]
ret.append(a)
return ret
TÄlÄk
AlternatÄ«va iespÄja, kurÄ vairÄk darba tiek pÄrcelts uz serveri: tas pats riÅÄ·o atrastos objektus un atgriež gatavo attÄlu.
Å Ä« opcija ir laba, ja mÄs nevÄlamies vilkt opencv uz serveri.
Docker
MÄs savÄcam attÄlu.
Kods ir izÄ·emmÄts un ievietots
KÄ platforma mÄs izmantosim to paÅ”u Debian Stretch kÄ Raspberry ā mÄs neatkÄpsimies no pÄrbaudÄ«tÄs tehnoloÄ£iju kopas.
Jums jÄinstalÄ flask, protobuf, requests, opencv_python, jÄlejupielÄdÄ Mobile SSD, servera kods no Github un jÄstartÄ serveris.
FROM python:3.7-stretch
RUN pip3 install flask
RUN pip3 install protobuf
RUN pip3 install requests
RUN pip3 install opencv_python
ADD http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_coco_11_06_2017.tar.gz /
RUN tar -xvf /ssd_mobilenet_v1_coco_11_06_2017.tar.gz
ADD https://github.com/tprlab/docker-detect/archive/master.zip /
RUN unzip /master.zip
EXPOSE 80
CMD ["python3", "/docker-detect-master/detect-app/app.py"]
VienkÄrÅ”s
PublicÄÅ”ana Docker Hub
Docker reÄ£istri vairojas ar Ätrumu, kas nav mazÄks par mÄkoÅu detektoru Ätrumu.
Lai neapgrÅ«tinÄtu, iesim konservatÄ«vi cauri
- ReÄ£istrÄties
- PieslÄgties:
docker pieteikÅ”anÄs - IzdomÄsim jÄgpilnu nosaukumu:
docker tag opencv-detect tprlab/opencv-detect-ssd - AugÅ”upielÄdÄjiet attÄlu serverÄ«:
docker push tprlab/opencv-detect-ssd
MÄs startÄjam mÄkonÄ«
ArÄ« izvÄle, kur palaist konteineru, ir diezgan plaÅ”a.
Visi lielie spÄlÄtÄji (Google, Microsoft, Amazon) pirmo gadu piedÄvÄ mikroinstanci bez maksas.
PÄc eksperimentÄÅ”anas ar Microsoft Azure un Google Cloud es izvÄlÄjos pÄdÄjo, jo tas sÄka darboties ÄtrÄk.
Es Å”eit nerakstÄ«ju instrukcijas, jo Ŕī daļa ir ļoti specifiska atlasÄ«tajam pakalpojumu sniedzÄjam.
Es izmÄÄ£inÄju dažÄdas aparatÅ«ras iespÄjas,
Zemi lÄ«meÅi (koplietoti un paredzÄti) - 0.4 - 0.5 sekundes.
JaudÄ«gÄkas automaŔīnas - 0.25 - 0.3.
Nu, pat sliktÄkajÄ gadÄ«jumÄ laimests ir trÄ«skÄrÅ”s, varat mÄÄ£inÄt.
Video
MÄs palaižam vienkÄrÅ”u OpenCV video straumÄtÄju vietnÄ Raspberry, kas tiek atklÄts, izmantojot Google Cloud.
Eksperimentam tika izmantots video fails, kas savulaik tika filmÄts nejauÅ”Ä krustojumÄ.
def handle_frame(frame):
return detect.detect_draw_img(frame)
def generate():
while True:
rc, frame = vs.read()
outFrame = handle_frame(frame)
if outFrame is None:
(rc, outFrame) = cv.imencode(".jpg", frame)
yield(b'--framern' b'Content-Type: image/jpegrnrn' + bytearray(outFrame) + b'rn')
@app.route("/stream")
def video_feed():
return Response(generate(), mimetype = "multipart/x-mixed-replace; boundary=frame")
Ar detektoru mÄs iegÅ«stam ne vairÄk kÄ trÄ«s kadrus sekundÄ, viss notiek ļoti lÄni.
Ja izmantojat jaudÄ«gu iekÄrtu GCloud, varat noteikt 4-5 kadrus sekundÄ, taÄu atŔķirÄ«ba ir gandrÄ«z neredzama acÄ«m, tÄ joprojÄm ir lÄna.
MÄkonim un transporta izmaksÄm ar to nav nekÄda sakara; detektors darbojas ar parastu aparatÅ«ru un darbojas tÄdÄ ÄtrumÄ.
Neironu datora stick
Es nevarÄju pretoties un izpildÄ«ju NCS etalonu.
Detektora Ätrums bija nedaudz mazÄks par 0.1 sekundi, katrÄ ziÅÄ 2-3 reizes lielÄks nekÄ mÄkonis uz vÄjas maŔīnas, t.i., 8-9 kadri sekundÄ.
RezultÄtu atŔķirÄ«ba ir izskaidrojama ar to, ka NCS darbojÄs Mobile SSD versija 2018_01_28.
PS TurklÄt eksperimenti ir parÄdÄ«juÅ”i, ka diezgan jaudÄ«ga galda maŔīna ar I7 procesoru uzrÄda nedaudz labÄkus rezultÄtus un izrÄdÄ«jÄs, ka uz tÄs ir iespÄjams izspiest 10 kadrus sekundÄ.
Kopa
Eksperiments gÄja tÄlÄk, un es instalÄju detektoru piecos Google Kubernetes mezglos.
PaÅ”i podi bija vÄji, un katrs no tiem nevarÄja apstrÄdÄt vairÄk par 2 kadriem sekundÄ.
Bet, ja palaižat klasteru ar N mezgliem un parsÄjat kadrus N pavedienos, tad ar pietiekamu skaitu mezglu (5) varat sasniegt vÄlamos 10 kadrus sekundÄ.
def generate():
while True:
rc, frame = vs.read()
if frame is not None:
future = executor.submit(handle_frame, (frame.copy()))
Q.append(future)
keep_polling = len(Q) > 0
while(keep_polling):
top = Q[0]
if top.done():
outFrame = top.result()
Q.popleft()
if outFrame:
yield(b'--framern' b'Content-Type: image/jpegrnrn' + bytearray(outFrame) + b'rn')
keep_polling = len(Q) > 0
else:
keep_polling = len(Q) >= M
LÅ«k, kas notika:
Nedaudz mazÄk Ätri nekÄ ar NCS, bet enerÄ£iskÄk nekÄ vienÄ straumÄ.
Ieguvums, protams, nav lineÄrs - ir pÄrklÄjumi opencv attÄlu sinhronizÄcijai un dziļai kopÄÅ”anai.
SecinÄjums
KopumÄ eksperiments ļauj secinÄt, ka, ja jÅ«s mÄÄ£inÄt, jÅ«s varat tikt galÄ ar vienkÄrÅ”u mÄkoni.
TaÄu jaudÄ«ga darbvirsma vai vietÄjÄ aparatÅ«ra ļauj sasniegt labÄkus rezultÄtus un bez jebkÄdiem trikiem.
atsauces
Avots: www.habr.com