Step7
This commit is contained in:
Родитель
9569541191
Коммит
12b5275475
|
@ -0,0 +1,5 @@
|
|||
CONTAINER_REGISTRY_URL=<ACR Login Server>
|
||||
CONTAINER_REGISTRY_USERNAME=<ACR User Name>
|
||||
CONTAINER_REGISTRY_PASSWORD=<ACR Password>
|
||||
CONTAINER_MODULE_VERSION=step7-8
|
||||
CONTAINER_VIDEO_SOURCE=<URL to Video>
|
|
@ -1,330 +0,0 @@
|
|||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
**/Properties/launchSettings.json
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
|
||||
# CodeRush
|
||||
.cr/
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "YoloModule Remote Debug (Python)",
|
||||
"type": "python",
|
||||
"request": "attach",
|
||||
"port": 5678,
|
||||
"host": "localhost",
|
||||
"logToFile": true,
|
||||
"redirectOutput": true,
|
||||
"pathMappings": [
|
||||
{
|
||||
"localRoot": "${workspaceFolder}/modules/YoloModule",
|
||||
"remoteRoot": "/app"
|
||||
}
|
||||
],
|
||||
"windows": {
|
||||
"pathMappings": [
|
||||
{
|
||||
"localRoot": "${workspaceFolder}\\modules\\YoloModule",
|
||||
"remoteRoot": "/app"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
{
|
||||
"$schema-template": "1.0.0",
|
||||
"modulesContent": {
|
||||
"$edgeAgent": {
|
||||
"properties.desired": {
|
||||
"schemaVersion": "1.0",
|
||||
"runtime": {
|
||||
"type": "docker",
|
||||
"settings": {
|
||||
"minDockerVersion": "v1.25",
|
||||
"loggingOptions": "",
|
||||
"registryCredentials": {
|
||||
"bootcampfy19acr": {
|
||||
"username": "$CONTAINER_REGISTRY_USERNAME",
|
||||
"password": "$CONTAINER_REGISTRY_PASSWORD",
|
||||
"address": "$CONTAINER_REGISTRY_URL"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"systemModules": {
|
||||
"edgeAgent": {
|
||||
"type": "docker",
|
||||
"settings": {
|
||||
"image": "mcr.microsoft.com/azureiotedge-agent:1.0",
|
||||
"createOptions": {}
|
||||
}
|
||||
},
|
||||
"edgeHub": {
|
||||
"type": "docker",
|
||||
"status": "running",
|
||||
"restartPolicy": "always",
|
||||
"settings": {
|
||||
"image": "mcr.microsoft.com/azureiotedge-hub:1.0",
|
||||
"createOptions": {
|
||||
"HostConfig": {
|
||||
"PortBindings": {
|
||||
"5671/tcp": [
|
||||
{
|
||||
"HostPort": "5671"
|
||||
}
|
||||
],
|
||||
"8883/tcp": [
|
||||
{
|
||||
"HostPort": "8883"
|
||||
}
|
||||
],
|
||||
"443/tcp": [
|
||||
{
|
||||
"HostPort": "443"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": {
|
||||
"YoloModule": {
|
||||
"version": "1.0",
|
||||
"type": "docker",
|
||||
"status": "running",
|
||||
"restartPolicy": "always",
|
||||
"settings": {
|
||||
"image": "${MODULES.YoloModule}",
|
||||
"createOptions": "{\"Env\":[\"VIDEO_PATH=$CONTAINER_VIDEO_SOURCE\", \"VIDEO_WIDTH=0\", \"VIDEO_HEIGHT=0\", \"FONT_SCALE=0.8\"], \"HostConfig\":{\"PortBindings\":{\"80/tcp\":[{\"HostPort\":\"80\"}]}}}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"$edgeHub": {
|
||||
"properties.desired": {
|
||||
"schemaVersion": "1.0",
|
||||
"routes": {
|
||||
},
|
||||
"storeAndForwardConfiguration": {
|
||||
"timeToLiveSecs": 7200
|
||||
}
|
||||
}
|
||||
},
|
||||
"YoloModule" : {
|
||||
"properties.desired": {
|
||||
"ConfidenceLevel" : "0.3",
|
||||
"VerboseMode" : 0,
|
||||
"Inference" : 1,
|
||||
"VideoSource" : ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# celery beat schedule file
|
||||
celerybeat-schedule
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
|
@ -0,0 +1,20 @@
|
|||
FROM ubuntu:xenial
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends libcurl4-openssl-dev python-pip libboost-python-dev libgtk2.0-dev && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY /build/requirements.txt ./
|
||||
RUN pip install --upgrade pip
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
RUN pip install tornado==4.5.3 trollius && \
|
||||
pip install -U youtube-dl
|
||||
|
||||
ADD /app/ .
|
||||
|
||||
# Expose the port
|
||||
EXPOSE 80
|
||||
|
||||
ENTRYPOINT [ "python", "-u", "./main.py" ]
|
|
@ -0,0 +1,61 @@
|
|||
# Base on work from https://github.com/Bronkoknorb/PyImageStream
|
||||
import trollius as asyncio
|
||||
import tornado.ioloop
|
||||
import tornado.web
|
||||
import tornado.websocket
|
||||
import threading
|
||||
import base64
|
||||
import os
|
||||
|
||||
class ImageStreamHandler(tornado.websocket.WebSocketHandler):
|
||||
|
||||
def initialize(self, videoCapture):
|
||||
self.clients = []
|
||||
self.videoCapture = videoCapture
|
||||
|
||||
def check_origin(self, origin):
|
||||
return True
|
||||
|
||||
def open(self):
|
||||
self.clients.append(self)
|
||||
print("Image Server Connection::opened")
|
||||
|
||||
def on_message(self, msg):
|
||||
if msg == 'next':
|
||||
frame = self.videoCapture.get_display_frame()
|
||||
if frame != None:
|
||||
encoded = base64.b64encode(frame)
|
||||
self.write_message(encoded, binary=False)
|
||||
|
||||
def on_close(self):
|
||||
self.clients.remove(self)
|
||||
print("Image Server Connection::closed")
|
||||
|
||||
class ImageServer(threading.Thread):
|
||||
|
||||
def __init__(self, port, videoCapture):
|
||||
threading.Thread.__init__(self)
|
||||
self.setDaemon(True)
|
||||
self.port = port
|
||||
self.videoCapture = videoCapture
|
||||
|
||||
def run(self):
|
||||
print ('ImageServer::run() : Started Image Server')
|
||||
try:
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop( loop )
|
||||
|
||||
indexPath = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'templates')
|
||||
app = tornado.web.Application([
|
||||
(r"/stream", ImageStreamHandler, {'videoCapture': self.videoCapture}),
|
||||
(r"/(.*)", tornado.web.StaticFileHandler, {'path': indexPath, 'default_filename': 'index.html'})
|
||||
])
|
||||
app.listen(self.port)
|
||||
print ('ImageServer::Started.')
|
||||
|
||||
tornado.ioloop.IOLoop.instance().start()
|
||||
except Exception as e:
|
||||
print('ImageServer::exited run loop. Exception - '+ str(e))
|
||||
|
||||
def close(self):
|
||||
print ('ImageServer::close()')
|
|
@ -0,0 +1,324 @@
|
|||
#To make python 2 and python 3 compatible code
|
||||
from __future__ import division
|
||||
from __future__ import absolute_import
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
import requests
|
||||
import time
|
||||
import json
|
||||
import os
|
||||
|
||||
import ImageServer
|
||||
from ImageServer import ImageServer
|
||||
import VideoStream
|
||||
from VideoStream import VideoStream
|
||||
'''***********************************************************
|
||||
Step-10 : Uncomment Start
|
||||
***********************************************************'''
|
||||
# import YoloInference
|
||||
# from YoloInference import YoloInference
|
||||
'''***********************************************************
|
||||
Step-10 : Uncomment End
|
||||
***********************************************************'''
|
||||
|
||||
class VideoCapture(object):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
videoPath = "",
|
||||
verbose = True,
|
||||
videoW = 0,
|
||||
videoH = 0,
|
||||
fontScale = 1.0,
|
||||
inference = True,
|
||||
confidenceLevel = 0.5):
|
||||
|
||||
self.videoPath = videoPath
|
||||
self.verbose = verbose
|
||||
self.videoW = videoW
|
||||
self.videoH = videoH
|
||||
self.inference = inference
|
||||
self.confidenceLevel = confidenceLevel
|
||||
self.useStream = False
|
||||
self.useMovieFile = False
|
||||
self.frameCount = 0
|
||||
self.vStream = None
|
||||
self.vCapture = None
|
||||
self.displayFrame = None
|
||||
self.fontScale = float(fontScale)
|
||||
self.captureInProgress = False
|
||||
|
||||
print("VideoCapture::__init__()")
|
||||
print("OpenCV Version : %s" % (cv2.__version__))
|
||||
print("===============================================================")
|
||||
print("Initialising Video Capture with the following parameters: ")
|
||||
print(" - Video path : " + self.videoPath)
|
||||
print(" - Video width : " + str(self.videoW))
|
||||
print(" - Video height : " + str(self.videoH))
|
||||
print(" - Font Scale : " + str(self.fontScale))
|
||||
print(" - Inference? : " + str(self.inference))
|
||||
print(" - ConficenceLevel : " + str(self.confidenceLevel))
|
||||
print("")
|
||||
|
||||
self.imageServer = ImageServer(80, self)
|
||||
self.imageServer.start()
|
||||
'''***********************************************************
|
||||
Step-10 : Uncomment Start
|
||||
***********************************************************'''
|
||||
# self.yoloInference = YoloInference(self.verbose, self.fontScale)
|
||||
'''***********************************************************
|
||||
Step-10 : Uncomment End
|
||||
***********************************************************'''
|
||||
|
||||
def __IsCaptureDev(self, videoPath):
|
||||
try:
|
||||
return '/dev/video' in videoPath.lower()
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
def __IsRtsp(self, videoPath):
|
||||
try:
|
||||
return 'rtsp:' in videoPath.lower()
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
def __IsYoutube(self, videoPath):
|
||||
try:
|
||||
return 'www.youtube.com' in videoPath.lower()
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
def __enter__(self):
|
||||
|
||||
if self.verbose:
|
||||
print("videoCapture::__enter__()")
|
||||
|
||||
self.setVideoSource(self.videoPath)
|
||||
|
||||
return self
|
||||
|
||||
def setVideoSource(self, newVideoPath):
|
||||
|
||||
if self.captureInProgress:
|
||||
self.captureInProgress = False
|
||||
time.sleep(1.0)
|
||||
if self.vCapture:
|
||||
self.vCapture.release()
|
||||
self.vCapture = None
|
||||
elif self.vStream:
|
||||
self.vStream.stop()
|
||||
self.vStream = None
|
||||
|
||||
if self.__IsRtsp(newVideoPath):
|
||||
print("\r\n===> RTSP Video Source")
|
||||
|
||||
self.useStream = True
|
||||
self.useMovieFile = False
|
||||
self.videoPath = newVideoPath
|
||||
|
||||
if self.vStream:
|
||||
self.vStream.start()
|
||||
self.vStream = None
|
||||
|
||||
if self.vCapture:
|
||||
self.vCapture.release()
|
||||
self.vCapture = None
|
||||
|
||||
self.vStream = VideoStream(newVideoPath).start()
|
||||
# Needed to load at least one frame into the VideoStream class
|
||||
time.sleep(1.0)
|
||||
self.captureInProgress = True
|
||||
|
||||
elif self.__IsYoutube(newVideoPath):
|
||||
print("\r\n===> YouTube Video Source")
|
||||
self.useStream = False
|
||||
self.useMovieFile = True
|
||||
# This is video file
|
||||
self.downloadVideo(newVideoPath)
|
||||
self.videoPath = newVideoPath
|
||||
if self.vCapture.isOpened():
|
||||
self.captureInProgress = True
|
||||
else:
|
||||
print("===========================\r\nWARNING : Failed to Open Video Source\r\n===========================\r\n")
|
||||
|
||||
elif self.__IsCaptureDev(newVideoPath):
|
||||
print("===> Webcam Video Source")
|
||||
if self.vStream:
|
||||
self.vStream.start()
|
||||
self.vStream = None
|
||||
|
||||
if self.vCapture:
|
||||
self.vCapture.release()
|
||||
self.vCapture = None
|
||||
|
||||
self.videoPath = newVideoPath
|
||||
self.useMovieFile = False
|
||||
self.useStream = False
|
||||
self.vCapture = cv2.VideoCapture(newVideoPath)
|
||||
if self.vCapture.isOpened():
|
||||
self.captureInProgress = True
|
||||
else:
|
||||
print("===========================\r\nWARNING : Failed to Open Video Source\r\n===========================\r\n")
|
||||
else:
|
||||
print("===========================\r\nWARNING : No Video Source\r\n===========================\r\n")
|
||||
self.useStream = False
|
||||
self.useYouTube = False
|
||||
self.vCapture = None
|
||||
self.vStream = None
|
||||
return self
|
||||
|
||||
def downloadVideo(self, videoUrl):
|
||||
if self.captureInProgress:
|
||||
bRestartCapture = True
|
||||
time.sleep(1.0)
|
||||
if self.vCapture:
|
||||
print("Relase vCapture")
|
||||
self.vCapture.release()
|
||||
self.vCapture = None
|
||||
else:
|
||||
bRestartCapture = False
|
||||
|
||||
if os.path.isfile('/app/video.mp4'):
|
||||
os.remove("/app/video.mp4")
|
||||
|
||||
print("Start downloading video")
|
||||
os.system("youtube-dl -o /app/video.mp4 -f mp4 " + videoUrl)
|
||||
print("Download Complete")
|
||||
self.vCapture = cv2.VideoCapture("/app/video.mp4")
|
||||
time.sleep(1.0)
|
||||
self.frameCount = int(self.vCapture.get(cv2.CAP_PROP_FRAME_COUNT))
|
||||
|
||||
if bRestartCapture:
|
||||
self.captureInProgress = True
|
||||
|
||||
def get_display_frame(self):
|
||||
return self.displayFrame
|
||||
|
||||
def start(self):
|
||||
while True:
|
||||
if self.captureInProgress:
|
||||
self.__Run__()
|
||||
|
||||
if not self.captureInProgress:
|
||||
time.sleep(1.0)
|
||||
|
||||
def __Run__(self):
|
||||
|
||||
print("===============================================================")
|
||||
print("videoCapture::__Run__()")
|
||||
print(" - Stream : " + str(self.useStream))
|
||||
print(" - useMovieFile : " + str(self.useMovieFile))
|
||||
|
||||
cameraH = 0
|
||||
cameraW = 0
|
||||
frameH = 0
|
||||
frameW = 0
|
||||
|
||||
if self.useStream and self.vStream:
|
||||
cameraH = int(self.vStream.stream.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
||||
cameraW = int(self.vStream.stream.get(cv2.CAP_PROP_FRAME_WIDTH))
|
||||
elif self.useStream == False and self.vCapture:
|
||||
cameraH = int(self.vCapture.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
||||
cameraW = int(self.vCapture.get(cv2.CAP_PROP_FRAME_WIDTH))
|
||||
else:
|
||||
print("Error : No Video Source")
|
||||
return
|
||||
|
||||
if self.videoW != 0 and self.videoH != 0 and self.videoH != cameraH and self.videoW != cameraW:
|
||||
needResizeFrame = True
|
||||
frameH = self.videoH
|
||||
frameW = self.videoW
|
||||
else:
|
||||
needResizeFrame = False
|
||||
frameH = cameraH
|
||||
frameW = cameraW
|
||||
|
||||
if needResizeFrame:
|
||||
print("Original frame size : " + str(cameraW) + "x" + str(cameraH))
|
||||
print(" New frame size : " + str(frameW) + "x" + str(frameH))
|
||||
print(" Resize : " + str(needResizeFrame))
|
||||
else:
|
||||
print("Camera frame size : " + str(cameraW) + "x" + str(cameraH))
|
||||
print(" frame size : " + str(frameW) + "x" + str(frameH))
|
||||
|
||||
# Check camera's FPS
|
||||
if self.useStream:
|
||||
cameraFPS = int(self.vStream.stream.get(cv2.CAP_PROP_FPS))
|
||||
else:
|
||||
cameraFPS = int(self.vCapture.get(cv2.CAP_PROP_FPS))
|
||||
|
||||
if cameraFPS == 0:
|
||||
print("Error : Could not get FPS")
|
||||
return
|
||||
|
||||
print("Frame rate (FPS) : " + str(cameraFPS))
|
||||
|
||||
currentFPS = cameraFPS
|
||||
perFrameTimeInMs = 1000 / cameraFPS
|
||||
|
||||
while True:
|
||||
|
||||
# Get current time before we capture a frame
|
||||
tFrameStart = time.time()
|
||||
|
||||
if not self.captureInProgress:
|
||||
break
|
||||
|
||||
if self.useMovieFile:
|
||||
currentFrame = int(self.vCapture.get(cv2.CAP_PROP_POS_FRAMES))
|
||||
if currentFrame >= self.frameCount:
|
||||
self.vCapture.set(cv2.CAP_PROP_POS_FRAMES, 0)
|
||||
|
||||
try:
|
||||
# Read a frame
|
||||
if self.useStream:
|
||||
frame = self.vStream.read()
|
||||
else:
|
||||
frame = self.vCapture.read()[1]
|
||||
except:
|
||||
print("ERROR : Exception during capturing")
|
||||
|
||||
# Rezie frame if flagged
|
||||
if needResizeFrame:
|
||||
frame = cv2.resize(frame, (self.videoW, self.videoH))
|
||||
|
||||
# Run Object Detection
|
||||
'''***********************************************************
|
||||
Step-10 : Uncomment Start
|
||||
***********************************************************'''
|
||||
# if self.inference:
|
||||
# self.yoloInference.runInference(frame, frameW, frameH, self.confidenceLevel, self.verbose)
|
||||
'''***********************************************************
|
||||
Step-10 : Uncomment Start
|
||||
***********************************************************'''
|
||||
|
||||
# Calculate FPS
|
||||
timeElapsedInMs = (time.time() - tFrameStart) * 1000
|
||||
currentFPS = 1000.0 / timeElapsedInMs
|
||||
|
||||
if (currentFPS > cameraFPS):
|
||||
# Cannot go faster than Camera's FPS
|
||||
currentFPS = cameraFPS
|
||||
|
||||
# Add FPS Text to the frame
|
||||
cv2.putText( frame, "FPS " + str(round(currentFPS, 1)), (10, int(30 * self.fontScale)), cv2.FONT_HERSHEY_SIMPLEX, self.fontScale, (0,0,255), 2)
|
||||
|
||||
self.displayFrame = cv2.imencode( '.jpg', frame )[1].tobytes()
|
||||
|
||||
timeElapsedInMs = (time.time() - tFrameStart) * 1000
|
||||
|
||||
if (1000 / cameraFPS) > timeElapsedInMs:
|
||||
# This is faster than image source (e.g. camera) can feed.
|
||||
waitTimeBetweenFrames = perFrameTimeInMs - timeElapsedInMs
|
||||
#if self.verbose:
|
||||
#print(" Wait time between frames :" + str(int(waitTimeBetweenFrames)))
|
||||
time.sleep(waitTimeBetweenFrames/1000.0)
|
||||
|
||||
def __exit__(self, exception_type, exception_value, traceback):
|
||||
|
||||
if self.vCapture:
|
||||
self.vCapture.release()
|
||||
|
||||
self.imageServer.close()
|
||||
cv2.destroyAllWindows()
|
|
@ -0,0 +1,71 @@
|
|||
#To make python 2 and python 3 compatible code
|
||||
from __future__ import absolute_import
|
||||
|
||||
from threading import Thread
|
||||
import sys
|
||||
if sys.version_info[0] < 3:#e.g python version <3
|
||||
import cv2
|
||||
else:
|
||||
import cv2
|
||||
from cv2 import cv2
|
||||
# pylint: disable=E1101
|
||||
# pylint: disable=E0401
|
||||
# Disabling linting that is not supported by Pylint for C extensions such as OpenCV. See issue https://github.com/PyCQA/pylint/issues/1955
|
||||
|
||||
|
||||
# import the Queue class from Python 3
|
||||
if sys.version_info >= (3, 0):
|
||||
from queue import Queue
|
||||
# otherwise, import the Queue class for Python 2.7
|
||||
else:
|
||||
from Queue import Queue
|
||||
|
||||
#This class reads all the video frames in a separate thread and always has the keeps only the latest frame in its queue to be grabbed by another thread
|
||||
class VideoStream(object):
|
||||
def __init__(self, path, queueSize=3):
|
||||
print("===============================================================\r\nVideoStream::__init__()")
|
||||
self.stream = cv2.VideoCapture(path)
|
||||
self.stopped = False
|
||||
self.Q = Queue(maxsize=queueSize)
|
||||
|
||||
def start(self):
|
||||
# start a thread to read frames from the video stream
|
||||
t = Thread(target=self.update, args=())
|
||||
t.daemon = True
|
||||
t.start()
|
||||
return self
|
||||
|
||||
def update(self):
|
||||
try:
|
||||
while True:
|
||||
if self.stopped:
|
||||
return
|
||||
|
||||
if not self.Q.full():
|
||||
(grabbed, frame) = self.stream.read()
|
||||
|
||||
# if the `grabbed` boolean is `False`, then we have
|
||||
# reached the end of the video file
|
||||
if not grabbed:
|
||||
self.stop()
|
||||
return
|
||||
|
||||
self.Q.put(frame)
|
||||
|
||||
#Clean the queue to keep only the latest frame
|
||||
while self.Q.qsize() > 1:
|
||||
self.Q.get()
|
||||
except Exception as e:
|
||||
print("got error: "+str(e))
|
||||
|
||||
def read(self):
|
||||
return self.Q.get()
|
||||
|
||||
def more(self):
|
||||
return self.Q.qsize() > 0
|
||||
|
||||
def stop(self):
|
||||
self.stopped = True
|
||||
|
||||
def __exit__(self, exception_type, exception_value, traceback):
|
||||
self.stream.release()
|
|
@ -0,0 +1,185 @@
|
|||
# Copyright (c) Microsoft. All rights reserved.
|
||||
# Licensed under the MIT license. See LICENSE file in the project root for
|
||||
# full license information.
|
||||
|
||||
import os
|
||||
import random
|
||||
import sys
|
||||
import time
|
||||
import json
|
||||
|
||||
import iothub_client
|
||||
# pylint: disable=E0611
|
||||
# Disabling linting that is not supported by Pylint for C extensions such as iothub_client. See issue https://github.com/PyCQA/pylint/issues/1955
|
||||
from iothub_client import (IoTHubModuleClient, IoTHubClientError, IoTHubError,
|
||||
IoTHubMessage, IoTHubMessageDispositionResult,
|
||||
IoTHubTransportProvider)
|
||||
|
||||
import VideoCapture
|
||||
from VideoCapture import VideoCapture
|
||||
|
||||
def send_to_Hub_callback(strMessage):
|
||||
message = IoTHubMessage(bytearray(strMessage, 'utf8'))
|
||||
print("\r\nsend_to_Hub_callback()")
|
||||
print(" - message : %s" & message)
|
||||
hubManager.send_event_to_output("output1", message, 0)
|
||||
|
||||
# Callback received when the message that we're forwarding is processed.
|
||||
def send_confirmation_callback(message, result, user_context):
|
||||
print("\r\nsend_confirmation_callback()")
|
||||
print(" - result : %s" % result)
|
||||
|
||||
def device_twin_callback(update_state, payload, user_context):
|
||||
global hubManager
|
||||
global videoCapture
|
||||
|
||||
if (("%s"%(update_state)) == "PARTIAL"):
|
||||
jsonData = json.loads(payload)
|
||||
else:
|
||||
jsonData = json.loads(payload).get('desired')
|
||||
|
||||
print("\r\ndevice_twin_callback()")
|
||||
print(" - status : %s" % update_state )
|
||||
print(" - payload : \r\n%s" % json.dumps(jsonData, indent=4))
|
||||
|
||||
if "ConfidenceLevel" in jsonData:
|
||||
print(" - ConfidenceLevel : " + str(jsonData['ConfidenceLevel']))
|
||||
videoCapture.confidenceLevel = float(jsonData['ConfidenceLevel'])
|
||||
|
||||
if "VerboseMode" in jsonData:
|
||||
print(" - Verbose : " + str(jsonData['VerboseMode']))
|
||||
if jsonData['VerboseMode'] == 0:
|
||||
videoCapture.verbose = False
|
||||
else:
|
||||
videoCapture.verbose = True
|
||||
|
||||
if "Inference" in jsonData:
|
||||
print(" - Inference : " + str(jsonData['Inference']))
|
||||
if jsonData['Inference'] == 0:
|
||||
videoCapture.inference = False
|
||||
else:
|
||||
videoCapture.inference = True
|
||||
|
||||
if "VideoSource" in jsonData:
|
||||
strUrl = str(jsonData['VideoSource'])
|
||||
print(" - VideoSource : " + strUrl)
|
||||
if strUrl.lower() != videoCapture.videoPath.lower() and strUrl != "":
|
||||
videoCapture.setVideoSource(strUrl)
|
||||
|
||||
device_twin_send_reported(hubManager)
|
||||
|
||||
def device_twin_send_reported(hubManager):
|
||||
global videoCapture
|
||||
|
||||
jsonTemplate = "{\"ConfidenceLevel\": \"%s\",\"VerboseMode\": %d,\"Inference\": %d, \"VideoSource\":\"%s\"}"
|
||||
|
||||
strUrl = videoCapture.videoPath
|
||||
|
||||
jsonData = jsonTemplate % (
|
||||
str(videoCapture.confidenceLevel),
|
||||
videoCapture.verbose,
|
||||
videoCapture.inference,
|
||||
strUrl)
|
||||
|
||||
print("\r\ndevice_twin_send_reported()")
|
||||
print(" - payload : \r\n%s" % json.dumps(jsonData, indent=4))
|
||||
|
||||
hubManager.send_reported_state(jsonData, len(jsonData), 1002)
|
||||
|
||||
def send_reported_state_callback(status_code, user_context):
|
||||
print("\r\nsend_reported_state_callback()")
|
||||
print(" - status_code : [%d]" % (status_code) )
|
||||
|
||||
class HubManager(object):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
messageTimeout,
|
||||
protocol,
|
||||
verbose):
|
||||
|
||||
# Communicate with the Edge Hub
|
||||
|
||||
self.messageTimeout = messageTimeout
|
||||
self.client_protocol = protocol
|
||||
self.client = IoTHubModuleClient()
|
||||
self.client.create_from_environment(protocol)
|
||||
self.client.set_option("messageTimeout", self.messageTimeout)
|
||||
self.client.set_option("product_info","edge-yolo-capture")
|
||||
if verbose:
|
||||
self.client.set_option("logtrace", 1)#enables MQTT logging
|
||||
|
||||
self.client.set_module_twin_callback(
|
||||
device_twin_callback, None)
|
||||
|
||||
def send_reported_state(self, reported_state, size, user_context):
|
||||
self.client.send_reported_state(
|
||||
reported_state, size,
|
||||
send_reported_state_callback, user_context)
|
||||
|
||||
def send_event_to_output(self, outputQueueName, event, send_context):
|
||||
self.client.send_event_async(outputQueueName, event, send_confirmation_callback, send_context)
|
||||
|
||||
def main(
|
||||
videoPath ="",
|
||||
verbose = False,
|
||||
videoWidth = 0,
|
||||
videoHeight = 0,
|
||||
fontScale = 1.0,
|
||||
inference = False,
|
||||
confidenceLevel = 0.8
|
||||
):
|
||||
|
||||
global hubManager
|
||||
global videoCapture
|
||||
|
||||
try:
|
||||
print("\nPython %s\n" % sys.version )
|
||||
print("Yolo Capture Azure IoT Edge Module. Press Ctrl-C to exit." )
|
||||
|
||||
with VideoCapture(videoPath,
|
||||
verbose,
|
||||
videoWidth,
|
||||
videoHeight,
|
||||
fontScale,
|
||||
inference,
|
||||
confidenceLevel) as videoCapture:
|
||||
|
||||
try:
|
||||
hubManager = HubManager(10000, IoTHubTransportProvider.MQTT, False)
|
||||
except IoTHubError as iothub_error:
|
||||
print("Unexpected error %s from IoTHub" % iothub_error )
|
||||
return
|
||||
|
||||
videoCapture.start()
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("Camera capture module stopped" )
|
||||
|
||||
|
||||
def __convertStringToBool(env):
|
||||
if env in ['True', 'TRUE', '1', 'y', 'YES', 'Y', 'Yes']:
|
||||
return True
|
||||
elif env in ['False', 'FALSE', '0', 'n', 'NO', 'N', 'No']:
|
||||
return False
|
||||
else:
|
||||
raise ValueError('Could not convert string to bool.')
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
VIDEO_PATH = os.environ['VIDEO_PATH']
|
||||
VERBOSE = __convertStringToBool(os.getenv('VERBOSE', 'False'))
|
||||
VIDEO_WIDTH = int(os.getenv('VIDEO_WIDTH', 0))
|
||||
VIDEO_HEIGHT = int(os.getenv('VIDEO_HEIGHT',0))
|
||||
FONT_SCALE = os.getenv('FONT_SCALE', 1)
|
||||
INFERENCE = __convertStringToBool(os.getenv('INFERENCE', 'False'))
|
||||
CONFIDENCE_LEVEL = float(os.getenv('CONFIDENCE_LEVEL', "0.8"))
|
||||
|
||||
except ValueError as error:
|
||||
print(error )
|
||||
sys.exit(1)
|
||||
|
||||
main(VIDEO_PATH, VERBOSE, VIDEO_WIDTH, VIDEO_HEIGHT, FONT_SCALE, INFERENCE, CONFIDENCE_LEVEL)
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Video Stream</title>
|
||||
<meta http-equiv="content-type" charset="utf-8">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<img id="currentImage" style="border:2px solid teal">
|
||||
<script>
|
||||
var img = document.getElementById("currentImage");
|
||||
url = document.URL.replace('http','ws')
|
||||
var ws = new WebSocket(url + "stream");
|
||||
|
||||
ws.onopen = function() {
|
||||
console.log("connection was established");
|
||||
ws.send("next");
|
||||
};
|
||||
|
||||
ws.onmessage = function(msg) {
|
||||
img.src = 'data:image/png;base64, ' + msg.data;
|
||||
};
|
||||
|
||||
img.onload = function() {
|
||||
ws.send("next");
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,80 @@
|
|||
person
|
||||
bicycle
|
||||
car
|
||||
motorbike
|
||||
aeroplane
|
||||
bus
|
||||
train
|
||||
truck
|
||||
boat
|
||||
traffic light
|
||||
fire hydrant
|
||||
stop sign
|
||||
parking meter
|
||||
bench
|
||||
bird
|
||||
cat
|
||||
dog
|
||||
horse
|
||||
sheep
|
||||
cow
|
||||
elephant
|
||||
bear
|
||||
zebra
|
||||
giraffe
|
||||
backpack
|
||||
umbrella
|
||||
handbag
|
||||
tie
|
||||
suitcase
|
||||
frisbee
|
||||
skis
|
||||
snowboard
|
||||
sports ball
|
||||
kite
|
||||
baseball bat
|
||||
baseball glove
|
||||
skateboard
|
||||
surfboard
|
||||
tennis racket
|
||||
bottle
|
||||
wine glass
|
||||
cup
|
||||
fork
|
||||
knife
|
||||
spoon
|
||||
bowl
|
||||
banana
|
||||
apple
|
||||
sandwich
|
||||
orange
|
||||
broccoli
|
||||
carrot
|
||||
hot dog
|
||||
pizza
|
||||
donut
|
||||
cake
|
||||
chair
|
||||
sofa
|
||||
pottedplant
|
||||
bed
|
||||
diningtable
|
||||
toilet
|
||||
tvmonitor
|
||||
laptop
|
||||
mouse
|
||||
remote
|
||||
keyboard
|
||||
cell phone
|
||||
microwave
|
||||
oven
|
||||
toaster
|
||||
sink
|
||||
refrigerator
|
||||
book
|
||||
clock
|
||||
vase
|
||||
scissors
|
||||
teddy bear
|
||||
hair drier
|
||||
toothbrush
|
|
@ -0,0 +1,182 @@
|
|||
[net]
|
||||
# Testing
|
||||
batch=1
|
||||
subdivisions=1
|
||||
# Training
|
||||
# batch=64
|
||||
# subdivisions=2
|
||||
width=416
|
||||
height=416
|
||||
channels=3
|
||||
momentum=0.9
|
||||
decay=0.0005
|
||||
angle=0
|
||||
saturation = 1.5
|
||||
exposure = 1.5
|
||||
hue=.1
|
||||
|
||||
learning_rate=0.001
|
||||
burn_in=1000
|
||||
max_batches = 500200
|
||||
policy=steps
|
||||
steps=400000,450000
|
||||
scales=.1,.1
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=16
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[maxpool]
|
||||
size=2
|
||||
stride=2
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=32
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[maxpool]
|
||||
size=2
|
||||
stride=2
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=64
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[maxpool]
|
||||
size=2
|
||||
stride=2
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=128
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[maxpool]
|
||||
size=2
|
||||
stride=2
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=256
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[maxpool]
|
||||
size=2
|
||||
stride=2
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=512
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[maxpool]
|
||||
size=2
|
||||
stride=1
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=1024
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
###########
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=256
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=512
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
filters=255
|
||||
activation=linear
|
||||
|
||||
|
||||
|
||||
[yolo]
|
||||
mask = 3,4,5
|
||||
anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
|
||||
classes=80
|
||||
num=6
|
||||
jitter=.3
|
||||
ignore_thresh = .7
|
||||
truth_thresh = 1
|
||||
random=1
|
||||
|
||||
[route]
|
||||
layers = -4
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=128
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[upsample]
|
||||
stride=2
|
||||
|
||||
[route]
|
||||
layers = -1, 8
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=256
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
filters=255
|
||||
activation=linear
|
||||
|
||||
[yolo]
|
||||
mask = 0,1,2
|
||||
anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
|
||||
classes=80
|
||||
num=6
|
||||
jitter=.3
|
||||
ignore_thresh = .7
|
||||
truth_thresh = 1
|
||||
random=1
|
Двоичный файл не отображается.
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"$schema-version": "0.0.1",
|
||||
"description": "",
|
||||
"image": {
|
||||
"repository": "$CONTAINER_REGISTRY_URL/yolomodule",
|
||||
"tag": {
|
||||
"version": "$CONTAINER_MODULE_VERSION",
|
||||
"platforms": {
|
||||
"amd64": "./Dockerfile.amd64"
|
||||
}
|
||||
},
|
||||
"buildOptions": []
|
||||
},
|
||||
"language": "python"
|
||||
}
|
Загрузка…
Ссылка в новой задаче