原型图自动生成json
原型图自动生成json 配置数据
使用百度的EasyDL 自定义模型api和ocr 服务接口实现了UI图自动生成组件信息如下:
1
2
3
4
5
6
7
8
9
[{ label: '付款时间', placehoder: '221-05-22021-05-2', formType: 'input' },
{ label: '类目分组', placehoder: '请选择类目分组', formType: 'select' },
{ label: '站点', placehoder: '请输入站点', formType: 'select' },
{ label: '组长', placehoder: '请选择组长', formType: 'select' },
{ label: '运营专员', placehoder: '请选择运营专员', formType: 'select' },
{ label: '显示已处理', placehoder: '否', formType: 'select' },
{ label: '显示二次销售', placehoder: '否', formType: 'select' },
{ label: '订单状态', placehoder: '全部', formType: 'select' }]
为了更加快速识别,所以前端用了截图功能,需要识别的部分图片上传到服务,然后由百度的两个服务分别识别组件类型和识别文字。然后通过坐标把两个数据拼合下,就得到了以上的数据结构。
截图部分react代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import React from 'react'
import Cropper from 'react-cropper'
import 'cropperjs/dist/cropper.css'
import {Button} from 'antd'
export default class Crop extends React.Component {
constructor() {
super();
this.cropImage = this.cropImage.bind(this);
this.state={
src:'',
file:''
}
}
cropImage() {
if (this.cropper.getCroppedCanvas() === 'null') {
return false
}
let url = `/homepage_images`
// 拿到文件名
let filename = this.state.file.name
let base64= this.cropper.getCroppedCanvas().toDataURL()
console.log(base64)
//message.info("正在上传图片")
// TODO: 这里可以尝试修改上传图片的尺寸
/* this.cropper.getCroppedCanvas().toBlob(async blob => {
// 创造提交表单数据对象
const formData = new FormData()
// 添加要上传的文件
formData.append('file', blob, filename)
// 提示开始上传
this.setState({submitting: true})
// 上传图片
const resp = await http.post(url, formData)
// 拿到服务器返回的数据
this.props.onUploadedFile(resp.data.data)
// 提示上传完毕
this.setState({submitting: false})
// 关闭弹窗
this.props.onClose()
})*/
}
handleFileChange = (e) => {
const fileReader = new FileReader()
const file = e.target.files[0]
if (file) {
if (file.size <= 5*1024*1024) {
this.setState({file: file})
fileReader.onload = (e) => {
const dataURL = e.target.result
this.setState({src: dataURL})
}
fileReader.readAsDataURL(file)
} else {
message.error("文件过大")
}
}
e.target.value = ''
}
onCropperInit=cropper => { this.cropper = cropper }
render() {
return (
<div>
<div style=>
<Cropper
src={this.state.src}
onInitialized={this.onCropperInit.bind(this)}
style=
guides={false}
preview='.cropper-preview'
/>
</div>
<div>
<Button type="primary" size="large" onClick={this.cropImage} style=>
确认裁剪
</Button>
</div>
<label className="add-img-btn">
<span>添加图片</span>
<input
type="file"
accept="image/jpeg,image/jpg,image/png"
className="base-upload-input"
onChange={this.handleFileChange}
/>
</label>
<div className="cropper-preview"></div>
</div>
);
}
}
node server demo代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
var AipOcrClient = require("baidu-aip-sdk").ocr;
var request = require('request');
// 设置APPID/AK/SK
var APP_ID = "22361431";
var API_KEY = "A6Ra6d6qIULkpXRCQUe0B7DA";
var SECRET_KEY = "okG1mHYGbQ60ZwpQGofhUzEeURwU5xte";
// 新建一个对象,建议只保存一个对象调用服务接口
var client = new AipOcrClient(APP_ID, API_KEY, SECRET_KEY);
function httprequest(url,data,callback){
request({
url: url,
method: "POST",
json: true,
headers: {
"content-type": "application/json",
},
body: data
}, function(error, response, body) {
if (!error && response.statusCode == 200) {
callback(body) // 请求成功的处理逻辑
}
});
};
//https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=wwrNWhrGs8zWpMyE5Z4AeQCK&client_secret=dGQGHpApWEeRsyiQGixqbDG2v3VrXy6z&
var fs = require('fs');
var image = fs.readFileSync("0.png").toString("base64");
// 如果有可选参数
var options = {};
options["language_type"] = "CHN_ENG";
options["detect_direction"] = "true";
options["detect_language"] = "true";
options["probability"] = "true";
function rectangleCol(x1,y1,w1,h1,x2,y2,w2,h2){
var maxX,maxY,minX,minY;
maxX = x1+w1 >= x2+w2 ? x1+w1 : x2+w2;
maxY = y1+h1 >= y2+h2 ? y1+h1 : y2+h2;
minX = x1 <= x2 ? x1 : x2;
minY = y1 <= y2 ? y1 : y2;
if(maxX - minX <= w1+w2 && maxY - minY <= h1+h2){
return true;
}else{
return false;
}
}
let url='https://aip.baidubce.com/rpc/2.0/ai_custom/v1/detection/componentsdj?access_token=24.edc89ca7db7d4ee6eefa236facdcd220.2592000.1624608499.282335-23388316'
httprequest( url,{"image":image,"threshold":0.4},(data)=>{
var b=data.results
console.log(JSON.stringify(b))
// 调用通用文字识别, 图片参数为本地图片
client.accurate(image).then(function(result) {
//var r=JSON.stringify(result)
var ww=[]
var r=result.words_result
r.forEach(element => {
if (element.location.top>100&&element.location.top<200){
ww.push(element)
}
});
console.log(JSON.stringify(ww));
var r=[]
ww.forEach(function(e){
var l=e.location
b.forEach(function(p){
var c=p.location
var go=rectangleCol(l.left,l.top,l.width,l.height,c.left,c.top,c.width,c.height)
if (go){
r.push({label:e.words.split(":")[0],placehoder:e.words.split(":")[1],formType:p.name})
}
})
})
}).catch(function(err) {
// 如果发生网络错误
console.log(err);
});
});
获取token的地址: https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=wwrNWhrGs8zWpMyE5Z4AeQCK&client_secret=dGQGHpApWEeRsyiQGixqbDG2v3VrXy6z&
——————————————————————————————— 2021.10.21 更新 使用第三方api 虽然方便,但是有次数限制。
新的方案是自己搭建ocr 和图片检测服务。
使用tensorflow 给我们的强大功能,python 的格式转为js 格式,然后用纯js 代码加载,推理模型,集成到nodejs服务中。
google colab 还是非常强大的,虽然他现在白嫖有时间限制。
数据集
使用的是阿里前端智能委员会的开源的已经标注的数据集。 使用自己的数据集进行finetune
问题
-
阿里的数据集是xml 的,需要把他转成json coco 格式,因为使用的预训练模型是coco 的有点绕大致流程是: xml2json —> json转coco 格式—> 转tfrecord 格式文件—> 使用object detection 进行训练—> 使用自己的数据集进行fewshot训练—>cpkt 格式模型转成 .pb 模型 —> pb模型转成js 格式 —>本地js加载模型并推理—> 嵌入的nodejs 服务中
-
json 转coco json 代码是搬砖的,有点坑,修改了下
ocr
使用开源的不是很准,暂时还是用百度的
位置聚类与排序
- 使用sklearn 聚类函数进行 组件与文字的合并,然后按照位置进行排序
表数据生成文档说明
- https://github.com/harvardnlp/boxscore-data 数据集
- https://github.com/ratishsp/data2text-entity-py 数据生成文本