ืคึผืจืึธืืึธื
ื ืืืืืขื ืืื ืืืฆื ืกืขืจืงืืึทืืืืืื ืืืืฃ ืื ืืื ืืขืจื ืขื ืืืึธืก ืืืืึทืื ืืื ืืขืกืืึท ืก ืึทืืืึธืคึผืืืึธื ืืขื ืืขื ืืืขื.
ืืื ืืึธืื ืฉืืื ืืืฉืื ื ืคึฟืึทืจ ืึท ืืึทื ื ืฆืืึทื ืฆื ืืจืึธืืงืึทืกื ืืืืืขื ืขื ืจืืืฉื ืืื ืึท ืืืืขืงืืขืจ, ืืื ืืื ืคืึทืงืืืฉ ืฆืืื.
ืื ืคึผืจืึธืืืขื ืืื ืึทื ืืื ืืืืื ืฆื ืืจืึธืืงืึทืกื ืืืืืขื ืคึฟืื Raspberry, ืืื ืื ืคืึธืจืฉืืขืืื ื ืคืื ืื ื ืขืืจืึทื ื ืขืฅ ืืขืืขืงืืึธืจ ืืืืฃ ืขืก ืืึธืื ืคืื ืฆื ืืืื ืืขืืืืื.
ืื ืืขื ื ืขืืจืึทื ืงืึธืืคึผืืืืขืจ ืฉืืขืงื
ืืื ืืืืจืืื ืคืึทืจืฉืืืขื ืข ืกืึทืืืฉืึทื ื.
ะ
ืืึธืืฉ Intel ืืื ืงืึทื ืืืขืจืืขืจื ืคึฟืึทืจ ืืืืคึผื ืคืจืึทืืขืืืึธืจืงืก, ืขืก ืืขื ืขื ืึท ื ืืืขืจ ืคืื ืคึผืืืคืึธืื.
ืคึฟืึทืจ ืืืึทืฉืคึผืื, ืื ืคึฟืึธืจืืึทื ืคืื ืื ืคืืจืืื ืื ื ืขืฅ ืงืขื ืืืื ืื ืงืึทืืคึผืึทืืึทืืึทื, ืืื ืืืื ืขืก ืืื ืงืึทืืคึผืึทืืึทืืึทื, ืขืืืขืืข ืืืึทืขืจืก ืงืขื ื ืืฉื ืืืื ืืขืฉืืืฆื ืืืืฃ ืื ืืืื, ืืื ืืืื ืืื ืืขื ืขื ืืขืฉืืืฆื, ืขืจืจืึธืจืก ืงืขื ืคึผืึทืกืืจื ืืขืฉืึทืก ืื ืงืึทื ืืืขืจืืฉืึทื ืคึผืจืึธืฆืขืก, ืืื ืึท ืจืขืืืืืึทื ืคืื ืืืึธืก ืืืจ ืืึทืงืืืขื ืขืืืขืืข ืืึธืื ืข ืืืื ืืื ืืขืจ ืจืขืืืืืึทื.
ืืื ืึทืืืขืืืื, ืืืื ืืืจ ืืืืื ืึท ืึทืจืืืืจืึทืจืืฉ ื ืขืืจืึทื ื ืขืฅ, ืขืก ืงืขื ื ืืฉื ืึทืจืืขืื ืืื NCS. ืืขืจืืืขืจ, ืืื ืืึทืฉืืึธืกื ืฆื ืคึผืจืืืืจื ืฆื ืกืึธืืืืข ืื ืคึผืจืึธืืืขื ืืื ืื ืืขืจืกื ืืืืืืกืคึผืจืขื ืืื ืฆืืืจืืืืขื ืืืฉืืจืื.
ืืืึธืืงื
ืื ืงืืึธืจ ืืื ืืขืจ ืืึธื ืื ืืขืจ ืืจืืจื ืฆื ืึท ืืืืข ืืึทืื ืืืึทืจื ืืืืืื ื ืืื ืฆื ืืืื ืฆื ืื ืืืึธืืงื.
ืืจืืื-ืืขืืืื ืึธืคึผืฆืืขืก - ืืืื ืืืืื ืืืืคื ืืืืื.
ืืืข ืื ืืืืื:
... ืืื ืฆืขื ืืืืงืขืจ ืืืืื ืืงืขืจ ืืึทืงืึทื ืืข.
ืืฉืืืื ื ืฆืืืืฉื ืืขื ืคืึทืจืฉืืืื ืงืืึทื ืืื ื ืืฉื ืืจืื ื.
ืืื ืืื ืืึทืฉืืึธืกื ื ืืฉื ืฆื ืงืืืึทืื, ืึธืืขืจ ืฆื ืืึทื ืืืืงืืขื ืื ืืื ืึทืื ืืจืืขืื ืกืืขืืข ืืืืฃ OpenCV ืืื ืืึธืงืงืขืจ ืืื ืืืืคื ืขืก ืืื ืื ืืืึธืืงื.
ืื ืืืึทืืข ืคืื โโืืขื ืฆืืืึทื ื ืืื ืืืืืืงืืึทื ืืื ืงืึธื ืืจืึธื - ืืืจ ืงืขื ืขื ืืืืฉื ืื ื ืขืืจืึทื ื ืขืฅ, ืืึธืกืืื ื, ืกืขืจืืืขืจ - ืืื ืึทืืืขืืืื, ืงืืื ืงืึทืคึผืจืื.
ืกืขืจืืืืจืขืจ
ืืื ืก ืึธื ืืืืื ืืื ืึท ืืืืข ืคึผืจืึธืืืึทืืืืคึผ.
ืืจืึทืืืฉืึทื ืึทืื ืืื ื ืืฆื Flask ืคึฟืึทืจ REST API, OpenCV ืืื MobileSSD ื ืขืฅ.
ืืื ืืึธืื ืืื ืกืืึทืืืจื ืื ืงืจืึทื ื ืืืขืจืกืืขืก ืืืืฃ ืืึธืงืงืขืจ, ืืื ืืืกืงืึทืืืขืจื ืึทื OpenCV 4.1.2 ืงืขื ื ืืฉื ืึทืจืืขืื ืืื Mobile SSD v1_coco_2018_01_28, ืืื ืืื ืืึธืื ืฆื ืจืึธืืื ืฆืืจืืง ืฆื ืื ืคึผืจืึธืืืขื 11/06_2017.
ืืื ืื ืึธื ืืืื ืคืื ืื ืืื ืกื, ืืืจ ืืึธืื ืื ืงืืึทืก ื ืขืืขื ืืื ื ืขืฅ:
def init():
tf_labels.initLabels(dnn_conf.DNN_LABELS_PATH)
return cv.dnn.readNetFromTensorflow(dnn_conf.DNN_PATH, dnn_conf.DNN_TXT_PATH)
ืืืืฃ ืึท ืืืืข ืืึธืงืงืขืจ (ืืืืฃ ืึท ื ืืฉื ืืืืขืจ ืืื ื ืืึทืคึผืืึทืคึผ) ืขืก ื ืขืื 0.3 ืกืขืงืื ืืขืก, ืืืืฃ Raspberry - 3.5.
ืืืืืจ ืื ืืืืื ืืขื ืืฉืืื:
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()
ืืึธืงืงืขืจ - 0.2 ืกืขืง, Raspberry - 1.7.
ืืืขื ืื ืืขื ืกืึธืจ ืืืกืืึทืืขืจื ืืื ืืืื ืขืืืืืง ืืืฉืกืึธื:
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
ืืืืืืขืจ
ืึทื ืึธืืืขืจื ืึทืืืื ืึธืคึผืฆืืข, ืืื ืืืึธืก ืืขืจ ืึทืจืืขื ืืื ืฉืืคืืื ืฆื ืื ืกืขืจืืืขืจ: ืขืก ืืื ืงืจืืืื ืื ืืขืคึฟืื ืขื ืึทืืืืฉืขืงืฅ ืืื ืงืขืจื ืื ืคืึทืจืืืง ืืืื.
ืืขืจ ืึธืคึผืฆืืข ืืื ืืื ืืืขื ืืืจ ืืึธื ื ืืฉื ืืืขืื ืฆื ืฉืืขืคึผื opencv ืฆื ืื ืกืขืจืืืขืจ.
ืืึธืงืขืจ
ืืืจ ืงืืืึทืื ืื ืืืื.
ืืขืจ ืงืึธื ืืื ืงืึธืืื ืืื ืึทืจืืึทื ืืขืฉืืงื ืืืืฃ
ืืื ืึท ืคึผืืึทืืคืึธืจืืข, ืืืจ ืืืขืื ื ืขืืขื ืื ืืขืืืข ืืขืืืึทื ืกืืจืขืืฉ ืืื ืืืืฃ Raspberry - ืืืจ ืืืขืื ื ืืฉื ืึธืคึผื ืืืื ืคืื ืื ืคึผืจืึธืืืขื ืืขืง ืกืืึทืง.
ืืืจ ืืึทืจืคึฟื ืฆื ืื ืกืืึทืืืจื ืงืึธืืืข, ืคึผืจืึธืืึธืืืฃ, ืจืืงืืืขืก, opencv_python, ืืจืืคืงืืคืืข ืืึธืืื ืกืกื, ืกืขืจืืืขืจ ืงืึธื ืคึฟืื Github ืืื ืึธื ืืืืื ืืขื ืกืขืจืืืขืจ.
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"]
ืคึผืจืึธืกื
ืืจืืืกืืขืื ืฆื Docker Hub
ืืึธืงืงืขืจ ืจืขืืืกืืจืื ืืึทืืืึทืคึผืืืืื ื ืืื ืึท ืืืืงืืึทื ื ืื ืืืืื ืืงืขืจ ืืื ืืืึธืืงื ืืขืืขืงืืึธืจืก.
ืึผืื ื ืืฉื ืฆื ืึทืจื, ืืืขืื ืืืจ ืงืึธื ืกืขืจืืืึทืืืื ืืืจืืืืื
- ืจืขืืืกืืจืืจื
- ืฆืืืื ืืจืืื:
ืืึธืงืงืขืจ ืืึธืืื - ืืื ืก ืงืืืขื ืึทืจืืืฃ ืืื ืึท ืืื ืื ืืคืึทื ื ืึธืืขื:
docker tag opencv-detect tprlab/opencv-detect-ssd - ืฆืืคึฟืขืืืงืขืจ ืื ืืืื ืฆื ืื ืกืขืจืืืขืจ:
ืืึธืงืงืขืจ ืฉืืืคึผื tprlab/opencv-detect-ssd
ืืืจ ืงืึทืืขืจ ืืื ืื ืืืึธืืงื
ืื ืืจืืจื ืคืื ืืื ืฆื ืืืืคื ืืขื ืงืึทื ืืืื ืขืจ ืืื ืืืื ืืึทื ืฅ ืืจืืื.
ืึทืืข ืื ืืจืืืก ืคึผืืืึทืขืจืก (ืืืื, ืืืืงืจืึธืกืึธืคึฟื, ืึทืืึทืืึธื) ืคืึธืจืฉืืึธืื ืึท ืืืงืจืึธ ืืืึทืฉืคึผืื ืคึฟืึทืจ ืคืจืื ืคึฟืึทืจ ืื ืขืจืฉืืขืจ ืืึธืจ.
ื ืึธื ืขืงืกืคึผืขืจืืืขื ืืื ื ืืื Microsoft Azure ืืื Google Cloud, ืืื ืืขืืขืฆื ืืืืฃ ืื ืืขื ืขืจ ืืืืึทื ืขืก ืืื ืืขืืืขื ืคืึทืกืืขืจ.
ืืื ืืื ื ืืฉื ืืขืฉืจืืื ืืื ืกืืจืืงืฆืืขืก ืืึธ, ืืืืึทื ืืขืจ ืืืื ืืื ืืืืขืจ ืกืคึผืขืฆืืคืืฉ ืคึฟืึทืจ ืื ืืืืกืืขืงืืืื ืฉืคึผืืึทืืขืจ.
ืืื ืืขืคืจืืืื ืคืึทืจืฉืืืขื ืข ืืึทืื ืืืึทืจื ืึธืคึผืฆืืขืก,
ื ืืืขืจืืง ืืขืืืขืืก (ืฉืขืจื ืืื ืืขืืึทืงืืืืึทื) - 0.4 - 0.5 ืกืขืงืื ืืขืก.
ืืขืจ ืฉืืึทืจืง ืงืึทืจืก - 0.25 - 0.3.
ื ื, ืืคืืื ืืื ืื ืขืจืืกื ืคืึทื, ืื ืืืื ืื ืื ืืขื ืขื ืืจืื ืืึธื, ืืืจ ืงืขื ืขื ืคึผืจืืืืจื.
ืืืืืขื
ืืืจ ืงืึทืืขืจ ืึท ืคึผืฉืื OpenCV ืืืืืขื ืกืืจืืืขืจ ืืืืฃ Raspberry, ืืืืขืงืืื ื ืืืจื Google ืงืืึธืื.
ืคึฟืึทืจ ืืขืจ ืขืงืกืคึผืขืจืืืขื ื, ืึท ืืืืืขื ืืขืงืข ืืื ืืขื ืืฆื ืืืึธืก ืืื ืืขืืืขื ืึทืืึธื ืคืืืื ืืื ืึท ืืจืึทืค - ืื ืืขืจืกืขืงืฉืึทื.
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")
ืืื ืื ืืขืืขืงืืึธืจ ืืืจ ืืึทืงืืืขื ื ืืฉื ืืขืจ ืืื ืืจืื ืจืึธืืขื ืคึผืขืจ ืกืขืงืื ืืข, ืึทืืฅ ืืืื ืืืืขืจ ืคึผืึทืืขืืขื.
ืืืื ืืืจ ื ืขืืขื ืึท ืฉืืึทืจืง ืืึทืฉืื ืืื GCloud, ืืืจ ืงืขื ืขื ืืขืืขืงื 4-5 ืจืึธืืขื ืคึผืขืจ ืกืขืงืื ืืข, ืึธืืขืจ ืื ืืืืืง ืืื ืึผืืขื ืืืืขืืง ืคึฟืึทืจ ืื ืืืื, ืขืก ืืื ื ืึธื ืคึผืึทืืขืืขื.
ืื ืืืึธืืงื ืืื ืืจืึทื ืกืคึผืขืจืืืืฉืึทื ืงืึธืก ืืึธืื ืืึธืจื ืืฉื ืฆื ืืึธื ืืื ืืื; ืืขืจ ืืขืืขืงืืึธืจ ืืืืคื ืืืืฃ ืจืขืืืืขืจ ืืึทืื ืืืึทืจื ืืื ืึทืจืืขื ืืื ืืขืจ ืืืืงืืึทื.
ื ืขืืจืึทื ืงืึธืืคึผืืืืขืจ ืฉืืขืงื
ืืื ืงืขื ื ืืฉื ืึทื ืืงืขืื ืฉืืขืื ืืื ืืื ืืืืคื ืื ืืขื ืืฉืืึทืจืง ืืืืฃ NCS.
ืื ืืืืงืืึทื ืคืื ืื ืืขืืขืงืืึธืจ ืืื ืืขืืืขื ืึท ืืืกื ืกืืึธืืขืจ ืืื 0.1 ืกืขืงืื ืืขืก, ืืื ืงืืื ืคืึทื 2-3 ืืื ืคืึทืกืืขืจ ืืื ืื ืืืึธืืงื ืืืืฃ ืึท ืฉืืืึทื ืืึทืฉืื, ื"ื 8-9 ืจืึธืืขื ืคึผืขืจ ืกืขืงืื ืืข.
ืืขืจ ืืืืืง ืืื ืจืขืืืืืึทืื ืืื ืืขืจืงืืขืจื ืืืจื ืื ืคืึทืงื ืึทื NCS ืืื ืคืืืกื ืืืง ืืึธืืื ืกืกื ืืืขืจืกืืข 2018_01_28.
ืคึผ.ืก. ืืื ืึทืืืฉืึทื, ืืงืกืคึผืขืจืึทืืึทื ืฅ ืืึธืื ืืขืืืืื ืึทื ืึท ืืึทื ืฅ ืฉืืึทืจืง ืืขืกืงืืึทืคึผ ืืึทืฉืื ืืื ืึท I7 ืคึผืจืึทืกืขืกืขืจ ืืืืืื ืึท ืืืกื ืืขืกืขืจ ืจืขืืืืืึทืื ืืื ืขืก ืืื ืืขืืืขื ืืขืืืขื ืฆื ืงืืืขืืฉื 10 ืจืึธืืขื ืคึผืขืจ ืกืขืงืื ืืข.
ืงื ืืื
ืืขืจ ืขืงืกืคึผืขืจืืืขื ื ืืื ืืขืืืขื ืืืืึทืืขืจ ืืื ืืื ืืื ืกืืึทืืืจื ืื ืืืืขืงืืขืจ ืืืืฃ ืคืื ืฃ ื ืึธืืื ืืื Google Kubernetes.
ืื ืคึผืึธืืก ืืื ืืขื ืขื ืฉืืืึทื ืืื ืืขืืขืจ ืคืื ืืื ืงืขื ื ืืฉื ืคึผืจืึธืฆืขืก ืืขืจ ืืื 2 ืจืึธืืขื ืคึผืขืจ ืกืขืงืื ืืข.
ืึธืืขืจ ืืืื ืืืจ ืืืืคื ืึท ืงื ืืื ืืื N ื ืึธืืื ืืื ืคึผืึทืจืก ืจืึธืืขื ืืื N ืคึฟืขืืขื, ืืื ืึท ืืขื ืื ื ืืืขืจ ืคืื ื ืึธืืื (5) ืืืจ ืงืขื ืขื ืืขืจืืจืืืื ืื ืืขืืืืื 10 ืจืึธืืขื ืคึผืขืจ ืกืขืงืื ืืข.
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
ืืึธ ืก ืืืึธืก ืืขืืจืืคื:
ื ืืืกื ืืืืื ืืงืขืจ ืฉื ืขื ืืื ืืื NCS, ืึธืืขืจ ืืขืจ ืงืจืึทืคืืืง ืืื ืืื ืืืื ืืืึทื.
ืืขืจ ืืขืืืื ืก, ืคืื ืงืืจืก, ืืื ื ืืฉื ืืื ืขืึทืจ - ืขืก ืืขื ืขื ืึธืืืืขืจืืืื ืคึฟืึทืจ ืกืื ืืงืจืึทื ืึทืืืืฉืึทื ืืื ืืืฃ ืงืึทืคึผืืื ื ืคืื ืึธืคึผืขื ืงืื ืืืืืขืจ.
ืกืึธืฃ
ืงืืืืขืืืืง, ืืขืจ ืขืงืกืคึผืขืจืืืขื ื ืึทืืึทืื ืืื ืื ืฆื ืคืึทืจืขื ืืืงื ืึทื ืืืื ืืืจ ืคึผืจืืืืจื, ืืืจ ืงืขื ืขื ืืึทืงืืืขื ืึทืืืขืง ืืื ืึท ืคึผืฉืื ืืืึธืืงื.
ืึธืืขืจ ืึท ืฉืืึทืจืง ืืขืกืงืืึทืคึผ ืึธืืขืจ ืืืืข ืืึทืื ืืืึทืจื ืึทืืึทืื ืืืจ ืฆื ืืขืจืืจืืืื ืืขืกืขืจ ืจืขืืืืืึทืื, ืืื ืึธื ืงืืื ืืจืืงืก.
ืจืขืคึฟืขืจืขื ืฆื
ืงืึธื ืืืืฃ Github Docker ืืืื ืืืืฃ DockerHub ืืืืืขื ืกืขืจืืืขืจ ืืืืฃ OpenCV & Python
ืืงืืจ: www.habr.com