添加darknet yolo 目标识别

This commit is contained in:
pengluan 2022-06-04 17:35:11 +08:00
parent d40d21c605
commit 6cef0c5704
12 changed files with 10728 additions and 0 deletions

View 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

View 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')

View 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 "在这里输入图片标题")

View 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

File diff suppressed because it is too large Load Diff

View 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); }
}

View 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;
});

View 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"]

View 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

View 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

View 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

View 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)