mirror of
https://github.com/tencentmusic/cube-studio.git
synced 2024-11-27 05:33:10 +08:00
添加darknet yolo 目标识别
This commit is contained in:
parent
d40d21c605
commit
6cef0c5704
39
images/web/target-detection/Dockerfile
Normal file
39
images/web/target-detection/Dockerfile
Normal file
@ -0,0 +1,39 @@
|
||||
# docker build -t ai.tencentmusic.com/tme-public/target-detection .
|
||||
|
||||
FROM ubuntu:18.04
|
||||
|
||||
RUN apt update
|
||||
|
||||
# 安装运维工具
|
||||
RUN apt install -y --force-yes --no-install-recommends vim apt-transport-https gnupg2 ca-certificates-java rsync jq wget git dnsutils iputils-ping net-tools curl mysql-client locales zip
|
||||
|
||||
# 安装python
|
||||
RUN apt install -y python3.6-dev python3-pip libsasl2-dev libpq-dev \
|
||||
&& ln -s /usr/bin/python3 /usr/bin/python \
|
||||
&& ln -s /usr/bin/pip3 /usr/bin/pip \
|
||||
&& pip install --upgrade pip
|
||||
|
||||
|
||||
# 安装中文
|
||||
RUN apt install -y --force-yes --no-install-recommends locales ttf-wqy-microhei ttf-wqy-zenhei xfonts-wqy && locale-gen zh_CN && locale-gen zh_CN.utf8
|
||||
ENV LANG zh_CN.UTF-8
|
||||
ENV LC_ALL zh_CN.UTF-8
|
||||
ENV LANGUAGE zh_CN.UTF-8
|
||||
|
||||
# 便捷操作
|
||||
RUN echo "alias ll='ls -alF'" >> /root/.bashrc && \
|
||||
echo "alias la='ls -A'" >> /root/.bashrc && \
|
||||
echo "alias vi='vim'" >> /root/.bashrc && \
|
||||
/bin/bash -c "source /root/.bashrc"
|
||||
|
||||
RUN apt install -y libgl1-mesa-glx
|
||||
RUN pip install flask werkzeug requests tornado
|
||||
RUN pip install Pillow pysnooper opencv-python
|
||||
|
||||
RUN pip3 install https://github.com/danielgatis/darknetpy/raw/master/dist/darknetpy-4.1-cp36-cp36m-linux_x86_64.whl
|
||||
WORKDIR /app
|
||||
#RUN wget https://pengluan-76009.sz.gfp.tencent-cloud.com/github/yolov3.zip && unzip yolov3.zip
|
||||
COPY . /app/
|
||||
ENTRYPOINT ["python", "server-web.py"]
|
||||
# docker run --name darknet --privileged -it --rm -v $PWD:/app -p 8080:8080 --entrypoint='' ai.tencentmusic.com/tme-public/target-detection bash
|
||||
|
113
images/web/target-detection/server-web.py
Executable file
113
images/web/target-detection/server-web.py
Executable file
@ -0,0 +1,113 @@
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
import traceback
|
||||
import argparse
|
||||
import base64
|
||||
import logging
|
||||
import time,datetime
|
||||
import json
|
||||
import requests
|
||||
from flask import redirect
|
||||
import os
|
||||
from os.path import splitext, basename
|
||||
import time
|
||||
import numpy as np
|
||||
import datetime
|
||||
import logging
|
||||
import flask
|
||||
import werkzeug
|
||||
import optparse
|
||||
import cv2
|
||||
from flask import jsonify,request
|
||||
from PIL import Image,ImageFont
|
||||
from PIL import ImageDraw
|
||||
import urllib
|
||||
from darknetpy.detector import Detector
|
||||
|
||||
import pysnooper
|
||||
from flask import Flask
|
||||
|
||||
app = Flask(__name__,
|
||||
static_url_path='/static',
|
||||
static_folder='static',
|
||||
template_folder='templates')
|
||||
|
||||
UPLOAD_FOLDER = "UPLOAD_FOLDER"
|
||||
myfont = ImageFont.truetype('/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc', 20)
|
||||
YOLO_BASE_DIR = os.getenv('YOLO_BASE_DIR','yolo')
|
||||
|
||||
class ImageDetector(object):
|
||||
def __init__(self):
|
||||
self.detector = Detector(YOLO_BASE_DIR+'/coco.data',YOLO_BASE_DIR+'/yolov3.cfg',YOLO_BASE_DIR+'/yolov3.weights')
|
||||
|
||||
# @pysnooper.snoop()
|
||||
def classify_image(self, image_path):
|
||||
print("Classfy : ", image_path)
|
||||
res = self.detector.detect(image_path)
|
||||
print(res)
|
||||
|
||||
img = Image.open(image_path)
|
||||
dr = ImageDraw.Draw(img)
|
||||
for data in res:
|
||||
class_name = data['class']
|
||||
x, y, w, h = data['left'],data['top'],data['right'] - data['left'],data['bottom'] - data['top']
|
||||
# 画矩形框
|
||||
dr.rectangle((x, y, x + w, y + h), outline=(46, 254, 46),width=3)
|
||||
|
||||
# 写文字
|
||||
# 设置字体和大小
|
||||
# myfont = ImageFont.truetype("static/glyphicons-halflings-regular.ttf", 100)
|
||||
|
||||
dr.text((data['left'],data['top']),class_name, font=myfont, fill = 'red')
|
||||
out_image_path = image_path[:image_path.rfind('.')] + '_deect' + image_path[image_path.rfind('.'):]
|
||||
img.save(out_image_path)
|
||||
return out_image_path
|
||||
|
||||
image_detector = ImageDetector()
|
||||
|
||||
|
||||
@app.route('/api/v1.0/model',methods=['GET','POST'])
|
||||
# @pysnooper.snoop()
|
||||
def classify_rest():
|
||||
try:
|
||||
data = request.json
|
||||
image_decode = base64.b64decode(data['image_data'])
|
||||
image_path = os.path.join(UPLOAD_FOLDER, str(datetime.datetime.now()) + ".jpg")
|
||||
nparr = np.fromstring(image_decode, np.uint8)
|
||||
# 从nparr中读取数据,并把数据转换(解码)成图像格式
|
||||
img_np = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
|
||||
cv2.imwrite(image_path, img_np)
|
||||
|
||||
logging.info('Saving to %s.', image_path)
|
||||
|
||||
out_image_path = image_detector.classify_image(image_path)
|
||||
file = open(out_image_path, 'rb')
|
||||
base64_str = base64.b64encode(file.read()).decode('utf-8')
|
||||
os.remove(out_image_path)
|
||||
os.remove(image_path)
|
||||
return jsonify({
|
||||
"status": 0,
|
||||
"result": {
|
||||
data.get('image_id','image_id'):base64_str
|
||||
},
|
||||
"message":""
|
||||
})
|
||||
|
||||
except Exception as err:
|
||||
logging.info('Uploaded image open error: %s', err)
|
||||
return jsonify(val = 'Cannot open uploaded image.')
|
||||
|
||||
|
||||
|
||||
|
||||
@app.route('/')
|
||||
def hello():
|
||||
return redirect('/static/index.html')
|
||||
|
||||
if __name__=='__main__':
|
||||
if not os.path.exists(UPLOAD_FOLDER):
|
||||
os.makedirs(UPLOAD_FOLDER)
|
||||
app.run(host='0.0.0.0',debug=True,port='8080')
|
||||
|
3
images/web/target-detection/static/README.md
Executable file
3
images/web/target-detection/static/README.md
Executable file
@ -0,0 +1,3 @@
|
||||
#image-container
|
||||
###图片管理
|
||||
![输入图片说明](http://git.oschina.net/chapsticks/image-container/raw/master/11.png?dir=0&filepath=11.png&oid=15bbf9e08a77667c1d9c31fc8ee407de3b985d6e&sha=951b770dc8b2854be0d5c60667103a870dd53f9c "在这里输入图片标题")
|
415
images/web/target-detection/static/index.html
Executable file
415
images/web/target-detection/static/index.html
Executable file
@ -0,0 +1,415 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>image dashboard</title>
|
||||
<link href="nprogress.css" rel="stylesheet" />
|
||||
<style>
|
||||
*{margin:0;padding:0;}
|
||||
/*top menu class*/
|
||||
.menu{
|
||||
width:100%;
|
||||
line-height:90px;
|
||||
-webkit-box-shadow:0 0 15px #bbb!important;
|
||||
-moz-box-shadow:0 0 15px #bbb!important;
|
||||
box-shadow:0 0 15px #bbb!important;
|
||||
margin-bottom: 15px;
|
||||
text-align: center;
|
||||
}
|
||||
input[type=text], input[type=password] {
|
||||
font-size: 13px;
|
||||
min-height: 32px;
|
||||
margin: 0;
|
||||
padding: 7px 8px;
|
||||
outline: none;
|
||||
color: #333;
|
||||
background-color: #fff;
|
||||
background-repeat: no-repeat;
|
||||
background-position: right center;
|
||||
border: 1px solid #d2d2d2;
|
||||
border-radius: 3px;
|
||||
box-shadow: inset 0 1px 2px rgba(0,0,0,0.075);
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
transition: all 0.15s ease-in;
|
||||
-webkit-transition: all 0.15s ease-in 0;
|
||||
vertical-align: middle;
|
||||
}
|
||||
#search input[type=text] {
|
||||
font-size: 18px;
|
||||
width: 500px;
|
||||
}
|
||||
.button {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
padding: 8px 15px;
|
||||
font-size: 13px;
|
||||
color: #555;
|
||||
font-weight: bold;
|
||||
white-space: nowrap;
|
||||
background-color: #eaeaea;
|
||||
background-image: -moz-linear-gradient(#fafafa, #eaeaea);
|
||||
background-image: -webkit-linear-gradient(#fafafa, #eaeaea);
|
||||
background-image: linear-gradient(#fafafa, #eaeaea);
|
||||
background-repeat: repeat-x;
|
||||
border-radius: 3px;
|
||||
border: 1px solid #ddd;
|
||||
border-bottom-color: #c5c5c5;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,.05);
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
#search .button {
|
||||
padding: 10px;
|
||||
width: 90px;
|
||||
}
|
||||
.del-btn{
|
||||
background-image: -moz-linear-gradient(#d9534f, #d43f3a);
|
||||
background-image: -webkit-linear-gradient(#d9534f, #d43f3a);
|
||||
background-image: linear-gradient(#d9534f, #d43f3a);
|
||||
color:#fff;
|
||||
border-bottom-color:#ccc;
|
||||
}
|
||||
.pass-btn{
|
||||
background-image: -moz-linear-gradient(#5cb85c, #4cae4c);
|
||||
background-image: -webkit-linear-gradient(#5cb85c, #4cae4c);
|
||||
background-image: linear-gradient(#5cb85c, #4cae4c);
|
||||
color:#fff;
|
||||
border-bottom-color:#ccc;
|
||||
}
|
||||
/*img container class*/
|
||||
.row{
|
||||
width:198%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.row > .img-block{
|
||||
float:left;
|
||||
width:10%;
|
||||
margin: 0 auto 15px auto;
|
||||
}
|
||||
.row > .img-block > .thumbnail{
|
||||
padding:10px 0;
|
||||
width:92%;
|
||||
height:430px;
|
||||
-webkit-box-shadow:0 0 10px #ddd;
|
||||
-moz-box-shadow:0 0 10px #ddd;
|
||||
box-shadow:0 0 10px #ddd;
|
||||
border:1px solid #fff;
|
||||
border-top-width: 2px;
|
||||
border-bottom-width: 2px;
|
||||
|
||||
line-height:350px;
|
||||
overflow:hidden;
|
||||
position:relative;
|
||||
text-align: center;
|
||||
}
|
||||
.row > .img-block > .thumbnail > img{
|
||||
/*max-width:100%;*/
|
||||
max-height:350px;
|
||||
margin:0 auto;
|
||||
border-radius: 8px;
|
||||
|
||||
position:relative;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
|
||||
}
|
||||
.row > .img-block > .thumbnail > p {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
text-align: center;
|
||||
line-height: 1;
|
||||
width: 100%;
|
||||
}
|
||||
.img-hover > .thumbnail{
|
||||
-webkit-box-shadow:0 0 10px #7a0!important;
|
||||
-moz-box-shadow:0 0 10px #7a0!important;
|
||||
box-shadow:0 0 10px #7a0!important;
|
||||
}
|
||||
.img-checked{
|
||||
border-color:mediumvioletred!important;
|
||||
}
|
||||
.ml100{margin-left:100px;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="load_file" hidden >
|
||||
<form id="file_upload_form" action="" method="post" enctype="multipart/form-data">
|
||||
<input id="file_pic" multiple="multiple" type="file" name="image" onchange="open_img(this)">
|
||||
<input id="image_id" type="number" name="image_id" value="2">
|
||||
<input type="submit" id="safety_submiit">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="menu">
|
||||
<div id="search">
|
||||
<!--style="display:none;"-->
|
||||
<input type="text" id="key" placeholder="输入网址" value="">
|
||||
<input class="button" type="button" id="btn-load" value="本地上传" onclick="javascript:document.getElementById('file_pic').click();">
|
||||
<input class="button ml100 pass-btn" type="button" id="btn-pass" value="检测">
|
||||
</div>
|
||||
<div id="models">
|
||||
<label><input type="checkbox" id="object-det" name="models" value="object-det" style="margin-left: 5em"> 物品检测</label>
|
||||
<label><input type="checkbox" id="animal-recognition" name="models" value="animal-recognition" style="margin-left: 5em"> 目标识别</label>
|
||||
<label><input type="checkbox" id="image-classification" name="models" value="image-classification" style="margin-left: 5em"> 图像分类</label>
|
||||
<label><input type="checkbox" id="image-seg" name="models" value="image-seg" style="margin-left: 5em"> 图像分割</label>
|
||||
<label><input type="checkbox" id="feast-extract" name="models" value="feast-extract" style="margin-left: 5em"> 特征提取</label>
|
||||
<label><input type="checkbox" id="video-tracking" name="models" value="image-tracking" style="margin-left: 5em"> 视频跟踪</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row" id="container"></div>
|
||||
|
||||
<script type="text/javascript" src="jquery.js"></script>
|
||||
<script type="text/javascript" src="nprogress.js"></script>
|
||||
<script>
|
||||
|
||||
var host = location.host;
|
||||
console.log(host);
|
||||
backend_server = "http://"+host+'/api/v1.0/model';
|
||||
|
||||
var cn = 'img-block';
|
||||
var ic = 'img-checked'; //图片被选中时的样式
|
||||
var imgManger = {
|
||||
//data为图片列表。本地图片列表
|
||||
render: function(data){
|
||||
var html = '';
|
||||
//每张图片显示类型为thumbnail。显示内容为图片,名称和id
|
||||
for (var i=0; i<data.length; i++){
|
||||
html += '<div class="img-block">'+
|
||||
' <div class="thumbnail" dataid="'+data[i].id+'">'+
|
||||
' <img src="'+data[i].img+'" alt="...">'+
|
||||
' <p font-size="9">检测结果: ***</p>'+
|
||||
' </div>'+
|
||||
'</div>';
|
||||
};
|
||||
document.getElementById("container").innerHTML = html;
|
||||
},
|
||||
|
||||
getImgs: function(){
|
||||
var ids = [];
|
||||
var ckd = document.getElementsByClassName(ic);
|
||||
for (var i=0; i<ckd.length; i++){
|
||||
ids.push(ckd[i].attributes.dataid.value); //将选中的图片的id记录到列表
|
||||
};
|
||||
return ids;
|
||||
},
|
||||
//初始化就是为显示的图片添加鼠标事件
|
||||
init: function(){
|
||||
var self = this;
|
||||
var imgObjs = document.getElementsByClassName(cn);
|
||||
for (var i = 0; i < imgObjs.length; i++) {
|
||||
imgObjs[i].onclick = self.imgClick;
|
||||
imgObjs[i].onmouseenter = self.imgHover;
|
||||
imgObjs[i].onmouseleave = self.imgOut;
|
||||
};
|
||||
},
|
||||
//图片点击事件
|
||||
imgClick: function(){
|
||||
var tb = this.getElementsByClassName('thumbnail')[0];
|
||||
|
||||
if (tb.className.indexOf(ic) == -1){
|
||||
tb.className += ' '+ic;
|
||||
}else{
|
||||
var classes = tb.className.split(' ');
|
||||
for (var i=0; i<classes.length; i++){
|
||||
if (classes[i]==ic){
|
||||
delete classes[i];
|
||||
};
|
||||
};
|
||||
tb.className = classes.join(' ');
|
||||
};
|
||||
},
|
||||
//鼠标经过事件
|
||||
imgHover: function(){
|
||||
var ih = 'img-hover';
|
||||
if (this.className.indexOf(ih) == -1){
|
||||
this.className += ' '+ih;
|
||||
};
|
||||
},
|
||||
//鼠标移出事件
|
||||
imgOut: function(){
|
||||
var ih = 'img-hover';
|
||||
if (this.className.indexOf(ih) > -1){
|
||||
this.className = cn;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// 在线图片
|
||||
allimages = [
|
||||
// {
|
||||
// 'img':'images/001.jpg',
|
||||
// 'id':1
|
||||
// }
|
||||
];
|
||||
//本地图片
|
||||
alllocalimg=[
|
||||
// {
|
||||
// 'image_id':'3',
|
||||
// 'image':file
|
||||
// }
|
||||
];
|
||||
|
||||
function open_img(dom){
|
||||
local_path= $(dom).val();
|
||||
console.log(local_path)
|
||||
}
|
||||
|
||||
image_load_type=0; //默认爬虫获取图片
|
||||
|
||||
//选择图片,马上预览
|
||||
function open_img(obj) {
|
||||
alllocalimg=[]; //清空之前的数据
|
||||
image_load_type=1;
|
||||
document.getElementById("container").innerHTML="";
|
||||
var fl=obj.files.length;
|
||||
for(let i=0;i<fl;i++){
|
||||
let file=obj.files[i];
|
||||
|
||||
var reader = new FileReader();
|
||||
|
||||
//读取文件过程方法
|
||||
|
||||
reader.onloadstart = function (e) {
|
||||
console.log("开始读取....");
|
||||
}
|
||||
reader.onprogress = function (e) {
|
||||
console.log("正在读取中....");
|
||||
}
|
||||
reader.onabort = function (e) {
|
||||
console.log("中断读取....");
|
||||
}
|
||||
reader.onerror = function (e) {
|
||||
console.log("读取异常....");
|
||||
}
|
||||
reader.onload = function (e) {
|
||||
console.log("成功读取....");
|
||||
|
||||
html = '<div class="img-block">'+
|
||||
' <div class="thumbnail" dataid="'+i+'">'+
|
||||
' <img src="'+e.target.result+'" alt="...">'+
|
||||
' <p font-size="9" style="height: 50px">检测结果:**</p>'+
|
||||
' </div>'+
|
||||
'</div>';
|
||||
base64_str=String(e.target.result).replace(/data:.*;base64,/,'') //replace('data:image/jpeg;base64,','').replace('data:image/png;base64,','').replace('data:;base64,','');
|
||||
// console.log(base64_str)
|
||||
alllocalimg.push({'image_id':i,'image':file,'image_data':base64_str});
|
||||
document.getElementById("container").innerHTML =document.getElementById("container").innerHTML+ html;
|
||||
}
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
allcolor=['#00ff00','#8cbe06','#fffc00','#ffba00','#ff6000','#ff0000']
|
||||
$(function(){
|
||||
var imgM = imgManger;
|
||||
//imgM.init()
|
||||
|
||||
//图片检测
|
||||
$('#btn-pass').click(function(){
|
||||
if(image_load_type==0)
|
||||
image_det_from_url();
|
||||
else
|
||||
image_det_from_pic();
|
||||
});
|
||||
//本地图片检测
|
||||
function image_det_from_pic()
|
||||
{
|
||||
console.log("图片检测");
|
||||
if (alllocalimg.length==0){
|
||||
alert('请至少包含一个图片!');
|
||||
return false;
|
||||
}
|
||||
NProgress.start(); //进度条启动
|
||||
|
||||
console.log('图片个数'+alllocalimg.length);
|
||||
for(let i=0;i<alllocalimg.length;i++)
|
||||
{
|
||||
send_pic(i); //从鉴别第一张开始
|
||||
// send_pic(0); //从鉴别第一张开始
|
||||
}
|
||||
|
||||
}
|
||||
//单次发送一张图片
|
||||
function send_pic(iii) {
|
||||
local_img=alllocalimg[iii];
|
||||
console.log(local_img);
|
||||
|
||||
var models = [];
|
||||
$("[name = models]:checkbox").each(function () {
|
||||
if ($(this).is(":checked")) {
|
||||
models.push($(this).attr("value"));
|
||||
}
|
||||
});
|
||||
console.log(models);
|
||||
|
||||
// var formdata=new FormData();
|
||||
// formdata.append('image_id',local_img['image_id']);
|
||||
// let image_id=local_img['image_id'];
|
||||
// formdata.append('image_data',local_img['image_data']);
|
||||
//
|
||||
// formdata.append('models',models);
|
||||
|
||||
|
||||
var formdata={};
|
||||
formdata['image_id']=local_img['image_id'];
|
||||
let image_id=local_img['image_id'];
|
||||
formdata['image_data']=local_img['image_data'];
|
||||
|
||||
// formdata['models']=JSON.stringify(models);
|
||||
formdata['models']=models;
|
||||
console.log(formdata);
|
||||
|
||||
|
||||
|
||||
$.ajax({
|
||||
type: "POST", //post方式
|
||||
url: backend_server, //请求网址
|
||||
data: JSON.stringify(formdata), //数据内容
|
||||
dataType: 'json',
|
||||
crossDomain: true,
|
||||
cache:false,
|
||||
// processData:true, //关闭序列化
|
||||
contentType:'application/json',
|
||||
success: function(back){
|
||||
// console.log(JSON.stringify(back));
|
||||
if(back['status']==0) //每张图片的处理状态值
|
||||
{
|
||||
result = back['result']; //当前图片的处理结果。
|
||||
console.log(JSON.stringify(back));
|
||||
div_dom=$("div[dataid='"+image_id+"']");
|
||||
img_dom=div_dom.children('img')[0];
|
||||
img_dom.setAttribute('src','data:.*;base64,'+result[image_id]);
|
||||
div_dom.children('p').html('检测成功')
|
||||
|
||||
}else {
|
||||
div_dom=$("div[dataid='"+image_id+"']");
|
||||
div_dom.children('p').html('检测失败')
|
||||
}
|
||||
|
||||
},
|
||||
complete: function(){
|
||||
NProgress.done(); // 设置滚动条完成
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
9472
images/web/target-detection/static/jquery.js
vendored
Executable file
9472
images/web/target-detection/static/jquery.js
vendored
Executable file
File diff suppressed because it is too large
Load Diff
74
images/web/target-detection/static/nprogress.css
Executable file
74
images/web/target-detection/static/nprogress.css
Executable file
@ -0,0 +1,74 @@
|
||||
/* Make clicks pass-through */
|
||||
#nprogress {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#nprogress .bar {
|
||||
background: #b92c28;
|
||||
|
||||
position: fixed;
|
||||
z-index: 1031;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
}
|
||||
|
||||
/* Fancy blur effect */
|
||||
#nprogress .peg {
|
||||
display: block;
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
width: 100px;
|
||||
height: 100%;
|
||||
box-shadow: 0 0 10px #b92c28, 0 0 5px #b92c28;
|
||||
opacity: 1.0;
|
||||
|
||||
-webkit-transform: rotate(3deg) translate(0px, -4px);
|
||||
-ms-transform: rotate(3deg) translate(0px, -4px);
|
||||
transform: rotate(3deg) translate(0px, -4px);
|
||||
}
|
||||
|
||||
/* Remove these to get rid of the spinner */
|
||||
#nprogress .spinner {
|
||||
display: block;
|
||||
position: fixed;
|
||||
z-index: 1031;
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
}
|
||||
|
||||
#nprogress .spinner-icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
box-sizing: border-box;
|
||||
|
||||
border: solid 2px transparent;
|
||||
border-top-color: #b92c28;
|
||||
border-left-color: #b92c28;
|
||||
border-radius: 50%;
|
||||
|
||||
-webkit-animation: nprogress-spinner 400ms linear infinite;
|
||||
animation: nprogress-spinner 400ms linear infinite;
|
||||
}
|
||||
|
||||
.nprogress-custom-parent {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nprogress-custom-parent #nprogress .spinner,
|
||||
.nprogress-custom-parent #nprogress .bar {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
@-webkit-keyframes nprogress-spinner {
|
||||
0% { -webkit-transform: rotate(0deg); }
|
||||
100% { -webkit-transform: rotate(360deg); }
|
||||
}
|
||||
@keyframes nprogress-spinner {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
491
images/web/target-detection/static/nprogress.js
Executable file
491
images/web/target-detection/static/nprogress.js
Executable file
@ -0,0 +1,491 @@
|
||||
/* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress
|
||||
* @license MIT */
|
||||
|
||||
;(function(root, factory) {
|
||||
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
module.exports = factory();
|
||||
} else {
|
||||
root.NProgress = factory();
|
||||
}
|
||||
|
||||
})(this, function() {
|
||||
var NProgress = {};
|
||||
|
||||
NProgress.version = '0.2.0';
|
||||
|
||||
var Settings = NProgress.settings = {
|
||||
minimum: 0.08,
|
||||
easing: 'linear',
|
||||
positionUsing: '',
|
||||
speed: 350,
|
||||
trickle: true,
|
||||
trickleSpeed: 250,
|
||||
showSpinner: true,
|
||||
barSelector: '[role="bar"]',
|
||||
spinnerSelector: '[role="spinner"]',
|
||||
parent: 'body',
|
||||
template: '<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates configuration.
|
||||
*
|
||||
* NProgress.configure({
|
||||
* minimum: 0.1
|
||||
* });
|
||||
*/
|
||||
NProgress.configure = function(options) {
|
||||
var key, value;
|
||||
for (key in options) {
|
||||
value = options[key];
|
||||
if (value !== undefined && options.hasOwnProperty(key)) Settings[key] = value;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Last number.
|
||||
*/
|
||||
|
||||
NProgress.status = null;
|
||||
|
||||
/**
|
||||
* Sets the progress bar status, where `n` is a number from `0.0` to `1.0`.
|
||||
*
|
||||
* NProgress.set(0.4);
|
||||
* NProgress.set(1.0);
|
||||
*/
|
||||
|
||||
NProgress.set = function(n) {
|
||||
var started = NProgress.isStarted();
|
||||
|
||||
n = clamp(n, Settings.minimum, 1);
|
||||
NProgress.status = (n === 1 ? null : n);
|
||||
|
||||
var progress = NProgress.render(!started),
|
||||
bar = progress.querySelector(Settings.barSelector),
|
||||
speed = Settings.speed,
|
||||
ease = Settings.easing;
|
||||
|
||||
progress.offsetWidth; /* Repaint */
|
||||
|
||||
queue(function(next) {
|
||||
// Set positionUsing if it hasn't already been set
|
||||
if (Settings.positionUsing === '') Settings.positionUsing = NProgress.getPositioningCSS();
|
||||
|
||||
// Add transition
|
||||
css(bar, barPositionCSS(n, speed, ease));
|
||||
|
||||
if (n === 1) {
|
||||
// Fade out
|
||||
css(progress, {
|
||||
transition: 'none',
|
||||
opacity: 1
|
||||
});
|
||||
progress.offsetWidth; /* Repaint */
|
||||
|
||||
setTimeout(function() {
|
||||
css(progress, {
|
||||
transition: 'all ' + speed + 'ms linear',
|
||||
opacity: 0
|
||||
});
|
||||
setTimeout(function() {
|
||||
NProgress.remove();
|
||||
next();
|
||||
}, speed);
|
||||
}, speed);
|
||||
} else {
|
||||
setTimeout(next, speed);
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
NProgress.isStarted = function() {
|
||||
return typeof NProgress.status === 'number';
|
||||
};
|
||||
|
||||
/**
|
||||
* Shows the progress bar.
|
||||
* This is the same as setting the status to 0%, except that it doesn't go backwards.
|
||||
*
|
||||
* NProgress.start();
|
||||
*
|
||||
*/
|
||||
NProgress.start = function() {
|
||||
if (!NProgress.status) NProgress.set(0);
|
||||
|
||||
var work = function() {
|
||||
setTimeout(function() {
|
||||
if (!NProgress.status) return;
|
||||
NProgress.trickle();
|
||||
work();
|
||||
}, Settings.trickleSpeed);
|
||||
};
|
||||
|
||||
if (Settings.trickle) work();
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hides the progress bar.
|
||||
* This is the *sort of* the same as setting the status to 100%, with the
|
||||
* difference being `done()` makes some placebo effect of some realistic motion.
|
||||
*
|
||||
* NProgress.done();
|
||||
*
|
||||
* If `true` is passed, it will show the progress bar even if its hidden.
|
||||
*
|
||||
* NProgress.done(true);
|
||||
*/
|
||||
|
||||
NProgress.done = function(force) {
|
||||
if (!force && !NProgress.status) return this;
|
||||
|
||||
return NProgress.inc(0.3 + 0.5 * Math.random()).set(1);
|
||||
};
|
||||
|
||||
/**
|
||||
* Increments by a random amount.
|
||||
*/
|
||||
|
||||
NProgress.inc = function(amount) {
|
||||
var n = NProgress.status;
|
||||
|
||||
if (!n) {
|
||||
return NProgress.start();
|
||||
} else if(n > 1) {
|
||||
return;
|
||||
} else {
|
||||
if (typeof amount !== 'number') {
|
||||
if (n >= 0 && n < 0.25) {
|
||||
// Start out between 3 - 6% increments
|
||||
amount = (Math.random() * (5 - 3 + 1) + 3) / 100;
|
||||
} else if (n >= 0.25 && n < 0.65) {
|
||||
// increment between 0 - 3%
|
||||
amount = (Math.random() * 3) / 100;
|
||||
} else if (n >= 0.65 && n < 0.9) {
|
||||
// increment between 0 - 2%
|
||||
amount = (Math.random() * 2) / 100;
|
||||
} else if (n >= 0.9 && n < 0.99) {
|
||||
// finally, increment it .5 %
|
||||
amount = 0.005;
|
||||
} else {
|
||||
// after 99%, don't increment:
|
||||
amount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
n = clamp(n + amount, 0, 0.994);
|
||||
return NProgress.set(n);
|
||||
}
|
||||
};
|
||||
|
||||
NProgress.trickle = function() {
|
||||
return NProgress.inc();
|
||||
};
|
||||
|
||||
/**
|
||||
* Waits for all supplied jQuery promises and
|
||||
* increases the progress as the promises resolve.
|
||||
*
|
||||
* @param $promise jQUery Promise
|
||||
*/
|
||||
(function() {
|
||||
var initial = 0, current = 0;
|
||||
|
||||
NProgress.promise = function($promise) {
|
||||
if (!$promise || $promise.state() === "resolved") {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (current === 0) {
|
||||
NProgress.start();
|
||||
}
|
||||
|
||||
initial++;
|
||||
current++;
|
||||
|
||||
$promise.always(function() {
|
||||
current--;
|
||||
if (current === 0) {
|
||||
initial = 0;
|
||||
NProgress.done();
|
||||
} else {
|
||||
NProgress.set((initial - current) / initial);
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
/**
|
||||
* (Internal) renders the progress bar markup based on the `template`
|
||||
* setting.
|
||||
*/
|
||||
|
||||
NProgress.render = function(fromStart) {
|
||||
if (NProgress.isRendered()) return document.getElementById('nprogress');
|
||||
|
||||
addClass(document.documentElement, 'nprogress-busy');
|
||||
|
||||
var progress = document.createElement('div');
|
||||
progress.id = 'nprogress';
|
||||
progress.innerHTML = Settings.template;
|
||||
|
||||
var bar = progress.querySelector(Settings.barSelector),
|
||||
perc = fromStart ? '-100' : toBarPerc(NProgress.status || 0),
|
||||
parent = document.querySelector(Settings.parent),
|
||||
spinner;
|
||||
|
||||
css(bar, {
|
||||
transition: 'all 0 linear',
|
||||
transform: 'translate3d(' + perc + '%,0,0)'
|
||||
});
|
||||
|
||||
if (!Settings.showSpinner) {
|
||||
spinner = progress.querySelector(Settings.spinnerSelector);
|
||||
spinner && removeElement(spinner);
|
||||
}
|
||||
|
||||
if (parent != document.body) {
|
||||
addClass(parent, 'nprogress-custom-parent');
|
||||
}
|
||||
|
||||
parent.appendChild(progress);
|
||||
return progress;
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the element. Opposite of render().
|
||||
*/
|
||||
|
||||
NProgress.remove = function() {
|
||||
removeClass(document.documentElement, 'nprogress-busy');
|
||||
removeClass(document.querySelector(Settings.parent), 'nprogress-custom-parent');
|
||||
var progress = document.getElementById('nprogress');
|
||||
progress && removeElement(progress);
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the progress bar is rendered.
|
||||
*/
|
||||
|
||||
NProgress.isRendered = function() {
|
||||
return !!document.getElementById('nprogress');
|
||||
};
|
||||
|
||||
/**
|
||||
* Determine which positioning CSS rule to use.
|
||||
*/
|
||||
|
||||
NProgress.getPositioningCSS = function() {
|
||||
// Sniff on document.body.style
|
||||
var bodyStyle = document.body.style;
|
||||
|
||||
// Sniff prefixes
|
||||
var vendorPrefix = ('WebkitTransform' in bodyStyle) ? 'Webkit' :
|
||||
('MozTransform' in bodyStyle) ? 'Moz' :
|
||||
('msTransform' in bodyStyle) ? 'ms' :
|
||||
('OTransform' in bodyStyle) ? 'O' : '';
|
||||
|
||||
if (vendorPrefix + 'Perspective' in bodyStyle) {
|
||||
// Modern browsers with 3D support, e.g. Webkit, IE10
|
||||
return 'translate3d';
|
||||
} else if (vendorPrefix + 'Transform' in bodyStyle) {
|
||||
// Browsers without 3D support, e.g. IE9
|
||||
return 'translate';
|
||||
} else {
|
||||
// Browsers without translate() support, e.g. IE7-8
|
||||
return 'margin';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
function clamp(n, min, max) {
|
||||
if (n < min) return min;
|
||||
if (n > max) return max;
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Internal) converts a percentage (`0..1`) to a bar translateX
|
||||
* percentage (`-100%..0%`).
|
||||
*/
|
||||
|
||||
function toBarPerc(n) {
|
||||
return (-1 + n) * 100;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* (Internal) returns the correct CSS for changing the bar's
|
||||
* position given an n percentage, and speed and ease from Settings
|
||||
*/
|
||||
|
||||
function barPositionCSS(n, speed, ease) {
|
||||
var barCSS;
|
||||
|
||||
if (Settings.positionUsing === 'translate3d') {
|
||||
barCSS = { transform: 'translate3d('+toBarPerc(n)+'%,0,0)' };
|
||||
} else if (Settings.positionUsing === 'translate') {
|
||||
barCSS = { transform: 'translate('+toBarPerc(n)+'%,0)' };
|
||||
} else {
|
||||
barCSS = { 'margin-left': toBarPerc(n)+'%' };
|
||||
}
|
||||
|
||||
barCSS.transition = 'all '+speed+'ms '+ease;
|
||||
|
||||
return barCSS;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Internal) Queues a function to be executed.
|
||||
*/
|
||||
|
||||
var queue = (function() {
|
||||
var pending = [];
|
||||
|
||||
function next() {
|
||||
var fn = pending.shift();
|
||||
if (fn) {
|
||||
fn(next);
|
||||
}
|
||||
}
|
||||
|
||||
return function(fn) {
|
||||
pending.push(fn);
|
||||
if (pending.length == 1) next();
|
||||
};
|
||||
})();
|
||||
|
||||
/**
|
||||
* (Internal) Applies css properties to an element, similar to the jQuery
|
||||
* css method.
|
||||
*
|
||||
* While this helper does assist with vendor prefixed property names, it
|
||||
* does not perform any manipulation of values prior to setting styles.
|
||||
*/
|
||||
|
||||
var css = (function() {
|
||||
var cssPrefixes = [ 'Webkit', 'O', 'Moz', 'ms' ],
|
||||
cssProps = {};
|
||||
|
||||
function camelCase(string) {
|
||||
return string.replace(/^-ms-/, 'ms-').replace(/-([\da-z])/gi, function(match, letter) {
|
||||
return letter.toUpperCase();
|
||||
});
|
||||
}
|
||||
|
||||
function getVendorProp(name) {
|
||||
var style = document.body.style;
|
||||
if (name in style) return name;
|
||||
|
||||
var i = cssPrefixes.length,
|
||||
capName = name.charAt(0).toUpperCase() + name.slice(1),
|
||||
vendorName;
|
||||
while (i--) {
|
||||
vendorName = cssPrefixes[i] + capName;
|
||||
if (vendorName in style) return vendorName;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
function getStyleProp(name) {
|
||||
name = camelCase(name);
|
||||
return cssProps[name] || (cssProps[name] = getVendorProp(name));
|
||||
}
|
||||
|
||||
function applyCss(element, prop, value) {
|
||||
prop = getStyleProp(prop);
|
||||
element.style[prop] = value;
|
||||
}
|
||||
|
||||
return function(element, properties) {
|
||||
var args = arguments,
|
||||
prop,
|
||||
value;
|
||||
|
||||
if (args.length == 2) {
|
||||
for (prop in properties) {
|
||||
value = properties[prop];
|
||||
if (value !== undefined && properties.hasOwnProperty(prop)) applyCss(element, prop, value);
|
||||
}
|
||||
} else {
|
||||
applyCss(element, args[1], args[2]);
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
/**
|
||||
* (Internal) Determines if an element or space separated list of class names contains a class name.
|
||||
*/
|
||||
|
||||
function hasClass(element, name) {
|
||||
var list = typeof element == 'string' ? element : classList(element);
|
||||
return list.indexOf(' ' + name + ' ') >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Internal) Adds a class to an element.
|
||||
*/
|
||||
|
||||
function addClass(element, name) {
|
||||
var oldList = classList(element),
|
||||
newList = oldList + name;
|
||||
|
||||
if (hasClass(oldList, name)) return;
|
||||
|
||||
// Trim the opening space.
|
||||
element.className = newList.substring(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* (Internal) Removes a class from an element.
|
||||
*/
|
||||
|
||||
function removeClass(element, name) {
|
||||
var oldList = classList(element),
|
||||
newList;
|
||||
|
||||
if (!hasClass(element, name)) return;
|
||||
|
||||
// Replace the class name.
|
||||
newList = oldList.replace(' ' + name + ' ', ' ');
|
||||
|
||||
// Trim the opening and closing spaces.
|
||||
element.className = newList.substring(1, newList.length - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* (Internal) Gets a space separated list of the class names on the element.
|
||||
* The list is wrapped with a single space on each end to facilitate finding
|
||||
* matches within the list.
|
||||
*/
|
||||
|
||||
function classList(element) {
|
||||
return (' ' + (element && element.className || '') + ' ').replace(/\s+/gi, ' ');
|
||||
}
|
||||
|
||||
/**
|
||||
* (Internal) Removes an element from the DOM.
|
||||
*/
|
||||
|
||||
function removeElement(element) {
|
||||
element && element.parentNode && element.parentNode.removeChild(element);
|
||||
}
|
||||
|
||||
return NProgress;
|
||||
});
|
18
job-template/job/object_detection_on_darknet/Dockerfile
Normal file
18
job-template/job/object_detection_on_darknet/Dockerfile
Normal file
@ -0,0 +1,18 @@
|
||||
FROM ubuntu:18.04
|
||||
WORKDIR /app
|
||||
RUN apt update && apt install -y gcc make git g++ wget zip
|
||||
RUN git clone https://github.com/pjreddie/darknet.git
|
||||
RUN cd darknet && sed -i 's@OPENMP=0@OPENMP=1@g' Makefile && make
|
||||
COPY setup_args.py /app
|
||||
COPY launcher.sh /app
|
||||
RUN wget https://pengluan-76009.sz.gfp.tencent-cloud.com/github/yolov3.weights
|
||||
|
||||
RUN wget https://pengluan-76009.sz.gfp.tencent-cloud.com/github/coco_data_sample.zip
|
||||
RUN unzip coco_data_sample.zip && cd coco_data_sample && bash reset_list.sh
|
||||
|
||||
RUN apt install -y python3.6-dev python3-pip libsasl2-dev libpq-dev \
|
||||
&& ln -s /usr/bin/python3 /usr/bin/python \
|
||||
&& ln -s /usr/bin/pip3 /usr/bin/pip
|
||||
|
||||
RUN chmod 777 launcher.sh
|
||||
ENTRYPOINT ["./launcher.sh"]
|
7
job-template/job/object_detection_on_darknet/build.sh
Normal file
7
job-template/job/object_detection_on_darknet/build.sh
Normal file
@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -ex
|
||||
|
||||
docker build --network=host -t ai.tencentmusic.com/tme-public/object_detection_on_darknet:v1 -f Dockerfile .
|
||||
docker push ai.tencentmusic.com/tme-public/object_detection_on_darknet:v1
|
||||
|
30
job-template/job/object_detection_on_darknet/common.py
Normal file
30
job-template/job/object_detection_on_darknet/common.py
Normal file
@ -0,0 +1,30 @@
|
||||
import subprocess
|
||||
import fcntl
|
||||
import os,sys
|
||||
import time
|
||||
|
||||
import logging
|
||||
BASE_LOGGING_CONF = '[%(levelname)s] [%(asctime)s] %(message)s'
|
||||
logging.basicConfig(level=logging.INFO,format=BASE_LOGGING_CONF)
|
||||
|
||||
def nonBlockRead(output):
|
||||
fd = output.fileno()
|
||||
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
|
||||
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
|
||||
try:
|
||||
return output.readline()
|
||||
except:
|
||||
return ''
|
||||
|
||||
class HiddenPrints:
|
||||
def __enter__(self):
|
||||
self._original_stdout = sys.stdout
|
||||
self._original_stderr = sys.stderr
|
||||
sys.stdout = open(os.devnull, 'w')
|
||||
sys.stderr = open(os.devnull, 'w')
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
sys.stdout.close()
|
||||
sys.stderr.close()
|
||||
sys.stdout = self._original_stdout
|
||||
sys.stderr = self._original_stderr
|
24
job-template/job/object_detection_on_darknet/launcher.sh
Normal file
24
job-template/job/object_detection_on_darknet/launcher.sh
Normal file
@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Setup getopt.
|
||||
long_opts="train_cfg:,data_cfg:,weights:"
|
||||
getopt_cmd=$(getopt -o da: --long "$long_opts" \
|
||||
-n $(basename $0) -- "$@") || \
|
||||
{ echo -e "\nERROR: Getopt failed. Extra args\n"; exit 1;}
|
||||
|
||||
eval set -- "$getopt_cmd"
|
||||
while true; do
|
||||
case "$1" in
|
||||
-t|--train_cfg) echo "train_cfg is $2" && train_cfg=$2;;
|
||||
-d|--data_cfg) echo "data_cfg is $2" && data_cfg=$2;;
|
||||
-w|--weights) echo "weights is $2" && weights=$2;;
|
||||
--) shift; break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
|
||||
python3 setup_args.py --train_cfg "$train_cfg" --data_cfg "$data_cfg" --weights "$weights"
|
||||
|
||||
/app/darknet/darknet detector train /app/darknet/cfg/data.cfg /app/darknet/cfg/train.cfg $weights 2>&1 | tee /mnt/uthermai/tmp/darknet/t.log
|
42
job-template/job/object_detection_on_darknet/setup_args.py
Normal file
42
job-template/job/object_detection_on_darknet/setup_args.py
Normal file
@ -0,0 +1,42 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import os,sys
|
||||
base_dir = os.path.split(os.path.realpath(__file__))[0]
|
||||
sys.path.append(base_dir)
|
||||
sys.path.append(os.path.realpath(__file__))
|
||||
|
||||
import logging
|
||||
BASE_LOGGING_CONF = '[%(levelname)s] [%(asctime)s] %(message)s'
|
||||
logging.basicConfig(level=logging.INFO,format=BASE_LOGGING_CONF)
|
||||
|
||||
import argparse
|
||||
import datetime
|
||||
import json
|
||||
import time
|
||||
import uuid
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
if __name__ == "__main__":
|
||||
arg_parser = argparse.ArgumentParser("obj launcher")
|
||||
# # XGBClassifier XGBRegressor
|
||||
arg_parser.add_argument('--train_cfg', type=str, help="模型参数配置、训练配置", default='')
|
||||
arg_parser.add_argument('--data_cfg', type=str, help="训练数据配置", default='')
|
||||
arg_parser.add_argument('--weights', type=str, help="权重文件", default='')
|
||||
|
||||
args = arg_parser.parse_args()
|
||||
logging.info("{} args: {}".format(__file__, args))
|
||||
|
||||
train_cfg = args.train_cfg
|
||||
data_cfg = args.data_cfg
|
||||
|
||||
with open('/app/darknet/cfg/train.cfg','w') as f_train_cfg:
|
||||
f_train_cfg.write(train_cfg)
|
||||
with open('/app/darknet/cfg/data.cfg','w') as f_data_cfg:
|
||||
f_data_cfg.write(data_cfg)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user