"src/onnx/onnx.cpp" did not exist on "40595b78c4dc0acbb89f1d70f223baa9efa42a9f"
Commit 0d97cc8c authored by Sugon_ldc's avatar Sugon_ldc
Browse files

add new model

parents
Pipeline #316 failed with stages
in 0 seconds
// https://github.com/vivkin/gason - pulled January 10, 2016
#pragma once
#include <stdint.h>
#include <stddef.h>
#include <assert.h>
enum JsonTag {
JSON_NUMBER = 0,
JSON_STRING,
JSON_ARRAY,
JSON_OBJECT,
JSON_TRUE,
JSON_FALSE,
JSON_NULL = 0xF
};
struct JsonNode;
#define JSON_VALUE_PAYLOAD_MASK 0x00007FFFFFFFFFFFULL
#define JSON_VALUE_NAN_MASK 0x7FF8000000000000ULL
#define JSON_VALUE_TAG_MASK 0xF
#define JSON_VALUE_TAG_SHIFT 47
union JsonValue {
uint64_t ival;
double fval;
JsonValue(double x)
: fval(x) {
}
JsonValue(JsonTag tag = JSON_NULL, void *payload = nullptr) {
assert((uintptr_t)payload <= JSON_VALUE_PAYLOAD_MASK);
ival = JSON_VALUE_NAN_MASK | ((uint64_t)tag << JSON_VALUE_TAG_SHIFT) | (uintptr_t)payload;
}
bool isDouble() const {
return (int64_t)ival <= (int64_t)JSON_VALUE_NAN_MASK;
}
JsonTag getTag() const {
return isDouble() ? JSON_NUMBER : JsonTag((ival >> JSON_VALUE_TAG_SHIFT) & JSON_VALUE_TAG_MASK);
}
uint64_t getPayload() const {
assert(!isDouble());
return ival & JSON_VALUE_PAYLOAD_MASK;
}
double toNumber() const {
assert(getTag() == JSON_NUMBER);
return fval;
}
char *toString() const {
assert(getTag() == JSON_STRING);
return (char *)getPayload();
}
JsonNode *toNode() const {
assert(getTag() == JSON_ARRAY || getTag() == JSON_OBJECT);
return (JsonNode *)getPayload();
}
};
struct JsonNode {
JsonValue value;
JsonNode *next;
char *key;
};
struct JsonIterator {
JsonNode *p;
void operator++() {
p = p->next;
}
bool operator!=(const JsonIterator &x) const {
return p != x.p;
}
JsonNode *operator*() const {
return p;
}
JsonNode *operator->() const {
return p;
}
};
inline JsonIterator begin(JsonValue o) {
return JsonIterator{o.toNode()};
}
inline JsonIterator end(JsonValue) {
return JsonIterator{nullptr};
}
#define JSON_ERRNO_MAP(XX) \
XX(OK, "ok") \
XX(BAD_NUMBER, "bad number") \
XX(BAD_STRING, "bad string") \
XX(BAD_IDENTIFIER, "bad identifier") \
XX(STACK_OVERFLOW, "stack overflow") \
XX(STACK_UNDERFLOW, "stack underflow") \
XX(MISMATCH_BRACKET, "mismatch bracket") \
XX(UNEXPECTED_CHARACTER, "unexpected character") \
XX(UNQUOTED_KEY, "unquoted key") \
XX(BREAKING_BAD, "breaking bad") \
XX(ALLOCATION_FAILURE, "allocation failure")
enum JsonErrno {
#define XX(no, str) JSON_##no,
JSON_ERRNO_MAP(XX)
#undef XX
};
const char *jsonStrError(int err);
class JsonAllocator {
struct Zone {
Zone *next;
size_t used;
} *head = nullptr;
public:
JsonAllocator() = default;
JsonAllocator(const JsonAllocator &) = delete;
JsonAllocator &operator=(const JsonAllocator &) = delete;
JsonAllocator(JsonAllocator &&x) : head(x.head) {
x.head = nullptr;
}
JsonAllocator &operator=(JsonAllocator &&x) {
head = x.head;
x.head = nullptr;
return *this;
}
~JsonAllocator() {
deallocate();
}
void *allocate(size_t size);
void deallocate();
};
int jsonParse(char *str, char **endptr, JsonValue *value, JsonAllocator &allocator);
/**************************************************************************
* Microsoft COCO Toolbox. version 2.0
* Data, paper, and tutorials available at: http://mscoco.org/
* Code written by Piotr Dollar and Tsung-Yi Lin, 2015.
* Licensed under the Simplified BSD License [see coco/license.txt]
**************************************************************************/
#include "maskApi.h"
#include <math.h>
#include <stdlib.h>
uint umin( uint a, uint b ) { return (a<b) ? a : b; }
uint umax( uint a, uint b ) { return (a>b) ? a : b; }
void rleInit( RLE *R, siz h, siz w, siz m, uint *cnts ) {
R->h=h; R->w=w; R->m=m; R->cnts=(m==0)?0:malloc(sizeof(uint)*m);
siz j; if(cnts) for(j=0; j<m; j++) R->cnts[j]=cnts[j];
}
void rleFree( RLE *R ) {
free(R->cnts); R->cnts=0;
}
void rlesInit( RLE **R, siz n ) {
siz i; *R = (RLE*) malloc(sizeof(RLE)*n);
for(i=0; i<n; i++) rleInit((*R)+i,0,0,0,0);
}
void rlesFree( RLE **R, siz n ) {
siz i; for(i=0; i<n; i++) rleFree((*R)+i); free(*R); *R=0;
}
void rleEncode( RLE *R, const byte *M, siz h, siz w, siz n ) {
siz i, j, k, a=w*h; uint c, *cnts; byte p;
cnts = malloc(sizeof(uint)*(a+1));
for(i=0; i<n; i++) {
const byte *T=M+a*i; k=0; p=0; c=0;
for(j=0; j<a; j++) { if(T[j]!=p) { cnts[k++]=c; c=0; p=T[j]; } c++; }
cnts[k++]=c; rleInit(R+i,h,w,k,cnts);
}
free(cnts);
}
void rleDecode( const RLE *R, byte *M, siz n ) {
siz i, j, k; for( i=0; i<n; i++ ) {
byte v=0; for( j=0; j<R[i].m; j++ ) {
for( k=0; k<R[i].cnts[j]; k++ ) *(M++)=v; v=!v; }}
}
void rleMerge( const RLE *R, RLE *M, siz n, int intersect ) {
uint *cnts, c, ca, cb, cc, ct; int v, va, vb, vp;
siz i, a, b, h=R[0].h, w=R[0].w, m=R[0].m; RLE A, B;
if(n==0) { rleInit(M,0,0,0,0); return; }
if(n==1) { rleInit(M,h,w,m,R[0].cnts); return; }
cnts = malloc(sizeof(uint)*(h*w+1));
for( a=0; a<m; a++ ) cnts[a]=R[0].cnts[a];
for( i=1; i<n; i++ ) {
B=R[i]; if(B.h!=h||B.w!=w) { h=w=m=0; break; }
rleInit(&A,h,w,m,cnts); ca=A.cnts[0]; cb=B.cnts[0];
v=va=vb=0; m=0; a=b=1; cc=0; ct=1;
while( ct>0 ) {
c=umin(ca,cb); cc+=c; ct=0;
ca-=c; if(!ca && a<A.m) { ca=A.cnts[a++]; va=!va; } ct+=ca;
cb-=c; if(!cb && b<B.m) { cb=B.cnts[b++]; vb=!vb; } ct+=cb;
vp=v; if(intersect) v=va&&vb; else v=va||vb;
if( v!=vp||ct==0 ) { cnts[m++]=cc; cc=0; }
}
rleFree(&A);
}
rleInit(M,h,w,m,cnts); free(cnts);
}
void rleArea( const RLE *R, siz n, uint *a ) {
siz i, j; for( i=0; i<n; i++ ) {
a[i]=0; for( j=1; j<R[i].m; j+=2 ) a[i]+=R[i].cnts[j]; }
}
void rleIou( RLE *dt, RLE *gt, siz m, siz n, byte *iscrowd, double *o ) {
siz g, d; BB db, gb; int crowd;
db=malloc(sizeof(double)*m*4); rleToBbox(dt,db,m);
gb=malloc(sizeof(double)*n*4); rleToBbox(gt,gb,n);
bbIou(db,gb,m,n,iscrowd,o); free(db); free(gb);
for( g=0; g<n; g++ ) for( d=0; d<m; d++ ) if(o[g*m+d]>0) {
crowd=iscrowd!=NULL && iscrowd[g];
if(dt[d].h!=gt[g].h || dt[d].w!=gt[g].w) { o[g*m+d]=-1; continue; }
siz ka, kb, a, b; uint c, ca, cb, ct, i, u; int va, vb;
ca=dt[d].cnts[0]; ka=dt[d].m; va=vb=0;
cb=gt[g].cnts[0]; kb=gt[g].m; a=b=1; i=u=0; ct=1;
while( ct>0 ) {
c=umin(ca,cb); if(va||vb) { u+=c; if(va&&vb) i+=c; } ct=0;
ca-=c; if(!ca && a<ka) { ca=dt[d].cnts[a++]; va=!va; } ct+=ca;
cb-=c; if(!cb && b<kb) { cb=gt[g].cnts[b++]; vb=!vb; } ct+=cb;
}
if(i==0) u=1; else if(crowd) rleArea(dt+d,1,&u);
o[g*m+d] = (double)i/(double)u;
}
}
void rleNms( RLE *dt, siz n, uint *keep, double thr ) {
siz i, j; double u;
for( i=0; i<n; i++ ) keep[i]=1;
for( i=0; i<n; i++ ) if(keep[i]) {
for( j=i+1; j<n; j++ ) if(keep[j]) {
rleIou(dt+i,dt+j,1,1,0,&u);
if(u>thr) keep[j]=0;
}
}
}
void bbIou( BB dt, BB gt, siz m, siz n, byte *iscrowd, double *o ) {
double h, w, i, u, ga, da; siz g, d; int crowd;
for( g=0; g<n; g++ ) {
BB G=gt+g*4; ga=G[2]*G[3]; crowd=iscrowd!=NULL && iscrowd[g];
for( d=0; d<m; d++ ) {
BB D=dt+d*4; da=D[2]*D[3]; o[g*m+d]=0;
w=fmin(D[2]+D[0],G[2]+G[0])-fmax(D[0],G[0]); if(w<=0) continue;
h=fmin(D[3]+D[1],G[3]+G[1])-fmax(D[1],G[1]); if(h<=0) continue;
i=w*h; u = crowd ? da : da+ga-i; o[g*m+d]=i/u;
}
}
}
void bbNms( BB dt, siz n, uint *keep, double thr ) {
siz i, j; double u;
for( i=0; i<n; i++ ) keep[i]=1;
for( i=0; i<n; i++ ) if(keep[i]) {
for( j=i+1; j<n; j++ ) if(keep[j]) {
bbIou(dt+i*4,dt+j*4,1,1,0,&u);
if(u>thr) keep[j]=0;
}
}
}
void rleToBbox( const RLE *R, BB bb, siz n ) {
siz i; for( i=0; i<n; i++ ) {
uint h, w, x, y, xs, ys, xe, ye, xp, cc, t; siz j, m;
h=(uint)R[i].h; w=(uint)R[i].w; m=R[i].m;
m=((siz)(m/2))*2; xs=w; ys=h; xe=ye=0; cc=0;
if(m==0) { bb[4*i+0]=bb[4*i+1]=bb[4*i+2]=bb[4*i+3]=0; continue; }
for( j=0; j<m; j++ ) {
cc+=R[i].cnts[j]; t=cc-j%2; y=t%h; x=(t-y)/h;
if(j%2==0) xp=x; else if(xp<x) { ys=0; ye=h-1; }
xs=umin(xs,x); xe=umax(xe,x); ys=umin(ys,y); ye=umax(ye,y);
}
bb[4*i+0]=xs; bb[4*i+2]=xe-xs+1;
bb[4*i+1]=ys; bb[4*i+3]=ye-ys+1;
}
}
void rleFrBbox( RLE *R, const BB bb, siz h, siz w, siz n ) {
siz i; for( i=0; i<n; i++ ) {
double xs=bb[4*i+0], xe=xs+bb[4*i+2];
double ys=bb[4*i+1], ye=ys+bb[4*i+3];
double xy[8] = {xs,ys,xs,ye,xe,ye,xe,ys};
rleFrPoly( R+i, xy, 4, h, w );
}
}
int uintCompare(const void *a, const void *b) {
uint c=*((uint*)a), d=*((uint*)b); return c>d?1:c<d?-1:0;
}
void rleFrPoly( RLE *R, const double *xy, siz k, siz h, siz w ) {
/* upsample and get discrete points densely along entire boundary */
siz j, m=0; double scale=5; int *x, *y, *u, *v; uint *a, *b;
x=malloc(sizeof(int)*(k+1)); y=malloc(sizeof(int)*(k+1));
for(j=0; j<k; j++) x[j]=(int)(scale*xy[j*2+0]+.5); x[k]=x[0];
for(j=0; j<k; j++) y[j]=(int)(scale*xy[j*2+1]+.5); y[k]=y[0];
for(j=0; j<k; j++) m+=umax(abs(x[j]-x[j+1]),abs(y[j]-y[j+1]))+1;
u=malloc(sizeof(int)*m); v=malloc(sizeof(int)*m); m=0;
for( j=0; j<k; j++ ) {
int xs=x[j], xe=x[j+1], ys=y[j], ye=y[j+1], dx, dy, t, d;
int flip; double s; dx=abs(xe-xs); dy=abs(ys-ye);
flip = (dx>=dy && xs>xe) || (dx<dy && ys>ye);
if(flip) { t=xs; xs=xe; xe=t; t=ys; ys=ye; ye=t; }
s = dx>=dy ? (double)(ye-ys)/dx : (double)(xe-xs)/dy;
if(dx>=dy) for( d=0; d<=dx; d++ ) {
t=flip?dx-d:d; u[m]=t+xs; v[m]=(int)(ys+s*t+.5); m++;
} else for( d=0; d<=dy; d++ ) {
t=flip?dy-d:d; v[m]=t+ys; u[m]=(int)(xs+s*t+.5); m++;
}
}
/* get points along y-boundary and downsample */
free(x); free(y); k=m; m=0; double xd, yd;
x=malloc(sizeof(int)*k); y=malloc(sizeof(int)*k);
for( j=1; j<k; j++ ) if(u[j]!=u[j-1]) {
xd=(double)(u[j]<u[j-1]?u[j]:u[j]-1); xd=(xd+.5)/scale-.5;
if( floor(xd)!=xd || xd<0 || xd>w-1 ) continue;
yd=(double)(v[j]<v[j-1]?v[j]:v[j-1]); yd=(yd+.5)/scale-.5;
if(yd<0) yd=0; else if(yd>h) yd=h; yd=ceil(yd);
x[m]=(int) xd; y[m]=(int) yd; m++;
}
/* compute rle encoding given y-boundary points */
k=m; a=malloc(sizeof(uint)*(k+1));
for( j=0; j<k; j++ ) a[j]=(uint)(x[j]*(int)(h)+y[j]);
a[k++]=(uint)(h*w); free(u); free(v); free(x); free(y);
qsort(a,k,sizeof(uint),uintCompare); uint p=0;
for( j=0; j<k; j++ ) { uint t=a[j]; a[j]-=p; p=t; }
b=malloc(sizeof(uint)*k); j=m=0; b[m++]=a[j++];
while(j<k) if(a[j]>0) b[m++]=a[j++]; else {
j++; if(j<k) b[m-1]+=a[j++]; }
rleInit(R,h,w,m,b); free(a); free(b);
}
char* rleToString( const RLE *R ) {
/* Similar to LEB128 but using 6 bits/char and ascii chars 48-111. */
siz i, m=R->m, p=0; long x; int more;
char *s=malloc(sizeof(char)*m*6);
for( i=0; i<m; i++ ) {
x=(long) R->cnts[i]; if(i>2) x-=(long) R->cnts[i-2]; more=1;
while( more ) {
char c=x & 0x1f; x >>= 5; more=(c & 0x10) ? x!=-1 : x!=0;
if(more) c |= 0x20; c+=48; s[p++]=c;
}
}
s[p]=0; return s;
}
void rleFrString( RLE *R, char *s, siz h, siz w ) {
siz m=0, p=0, k; long x; int more; uint *cnts;
while( s[m] ) m++; cnts=malloc(sizeof(uint)*m); m=0;
while( s[p] ) {
x=0; k=0; more=1;
while( more ) {
char c=s[p]-48; x |= (c & 0x1f) << 5*k;
more = c & 0x20; p++; k++;
if(!more && (c & 0x10)) x |= -1 << 5*k;
}
if(m>2) x+=(long) cnts[m-2]; cnts[m++]=(uint) x;
}
rleInit(R,h,w,m,cnts); free(cnts);
}
/**************************************************************************
* Microsoft COCO Toolbox. version 2.0
* Data, paper, and tutorials available at: http://mscoco.org/
* Code written by Piotr Dollar and Tsung-Yi Lin, 2015.
* Licensed under the Simplified BSD License [see coco/license.txt]
**************************************************************************/
#pragma once
typedef unsigned int uint;
typedef unsigned long siz;
typedef unsigned char byte;
typedef double* BB;
typedef struct { siz h, w, m; uint *cnts; } RLE;
/* Initialize/destroy RLE. */
void rleInit( RLE *R, siz h, siz w, siz m, uint *cnts );
void rleFree( RLE *R );
/* Initialize/destroy RLE array. */
void rlesInit( RLE **R, siz n );
void rlesFree( RLE **R, siz n );
/* Encode binary masks using RLE. */
void rleEncode( RLE *R, const byte *mask, siz h, siz w, siz n );
/* Decode binary masks encoded via RLE. */
void rleDecode( const RLE *R, byte *mask, siz n );
/* Compute union or intersection of encoded masks. */
void rleMerge( const RLE *R, RLE *M, siz n, int intersect );
/* Compute area of encoded masks. */
void rleArea( const RLE *R, siz n, uint *a );
/* Compute intersection over union between masks. */
void rleIou( RLE *dt, RLE *gt, siz m, siz n, byte *iscrowd, double *o );
/* Compute non-maximum suppression between bounding masks */
void rleNms( RLE *dt, siz n, uint *keep, double thr );
/* Compute intersection over union between bounding boxes. */
void bbIou( BB dt, BB gt, siz m, siz n, byte *iscrowd, double *o );
/* Compute non-maximum suppression between bounding boxes */
void bbNms( BB dt, siz n, uint *keep, double thr );
/* Get bounding boxes surrounding encoded masks. */
void rleToBbox( const RLE *R, BB bb, siz n );
/* Convert bounding boxes to encoded masks. */
void rleFrBbox( RLE *R, const BB bb, siz h, siz w, siz n );
/* Convert polygon to encoded mask. */
void rleFrPoly( RLE *R, const double *xy, siz k, siz h, siz w );
/* Get compressed string representation of encoded mask. */
char* rleToString( const RLE *R );
/* Convert from compressed string representation of encoded mask. */
void rleFrString( RLE *R, char *s, siz h, siz w );
__author__ = 'tsungyi'
import pycocotools._mask as _mask
# Interface for manipulating masks stored in RLE format.
#
# RLE is a simple yet efficient format for storing binary masks. RLE
# first divides a vector (or vectorized image) into a series of piecewise
# constant regions and then for each piece simply stores the length of
# that piece. For example, given M=[0 0 1 1 1 0 1] the RLE counts would
# be [2 3 1 1], or for M=[1 1 1 1 1 1 0] the counts would be [0 6 1]
# (note that the odd counts are always the numbers of zeros). Instead of
# storing the counts directly, additional compression is achieved with a
# variable bitrate representation based on a common scheme called LEB128.
#
# Compression is greatest given large piecewise constant regions.
# Specifically, the size of the RLE is proportional to the number of
# *boundaries* in M (or for an image the number of boundaries in the y
# direction). Assuming fairly simple shapes, the RLE representation is
# O(sqrt(n)) where n is number of pixels in the object. Hence space usage
# is substantially lower, especially for large simple objects (large n).
#
# Many common operations on masks can be computed directly using the RLE
# (without need for decoding). This includes computations such as area,
# union, intersection, etc. All of these operations are linear in the
# size of the RLE, in other words they are O(sqrt(n)) where n is the area
# of the object. Computing these operations on the original mask is O(n).
# Thus, using the RLE can result in substantial computational savings.
#
# The following API functions are defined:
# encode - Encode binary masks using RLE.
# decode - Decode binary masks encoded via RLE.
# merge - Compute union or intersection of encoded masks.
# iou - Compute intersection over union between masks.
# area - Compute area of encoded masks.
# toBbox - Get bounding boxes surrounding encoded masks.
# frPyObjects - Convert polygon, bbox, and uncompressed RLE to encoded RLE mask.
#
# Usage:
# Rs = encode( masks )
# masks = decode( Rs )
# R = merge( Rs, intersect=false )
# o = iou( dt, gt, iscrowd )
# a = area( Rs )
# bbs = toBbox( Rs )
# Rs = frPyObjects( [pyObjects], h, w )
#
# In the API the following formats are used:
# Rs - [dict] Run-length encoding of binary masks
# R - dict Run-length encoding of binary mask
# masks - [hxwxn] Binary mask(s) (must have type np.ndarray(dtype=uint8) in column-major order)
# iscrowd - [nx1] list of np.ndarray. 1 indicates corresponding gt image has crowd region to ignore
# bbs - [nx4] Bounding box(es) stored as [x y w h]
# poly - Polygon stored as [[x1 y1 x2 y2...],[x1 y1 ...],...] (2D list)
# dt,gt - May be either bounding boxes or encoded masks
# Both poly and bbs are 0-indexed (bbox=[0 0 1 1] encloses first pixel).
#
# Finally, a note about the intersection over union (iou) computation.
# The standard iou of a ground truth (gt) and detected (dt) object is
# iou(gt,dt) = area(intersect(gt,dt)) / area(union(gt,dt))
# For "crowd" regions, we use a modified criteria. If a gt object is
# marked as "iscrowd", we allow a dt to match any subregion of the gt.
# Choosing gt' in the crowd gt that best matches the dt can be done using
# gt'=intersect(dt,gt). Since by definition union(gt',dt)=dt, computing
# iou(gt,dt,iscrowd) = iou(gt',dt) = area(intersect(gt,dt)) / area(dt)
# For crowd gt regions we use this modified criteria above for the iou.
#
# To compile run "python setup.py build_ext --inplace"
# Please do not contact us for help with compiling.
#
# Microsoft COCO Toolbox. version 2.0
# Data, paper, and tutorials available at: http://mscoco.org/
# Code written by Piotr Dollar and Tsung-Yi Lin, 2015.
# Licensed under the Simplified BSD License [see coco/license.txt]
iou = _mask.iou
merge = _mask.merge
frPyObjects = _mask.frPyObjects
def encode(bimask):
if len(bimask.shape) == 3:
return _mask.encode(bimask)
elif len(bimask.shape) == 2:
h, w = bimask.shape
return _mask.encode(bimask.reshape((h, w, 1), order='F'))[0]
def decode(rleObjs):
if type(rleObjs) == list:
return _mask.decode(rleObjs)
else:
return _mask.decode([rleObjs])[:, :, 0]
def area(rleObjs):
if type(rleObjs) == list:
return _mask.area(rleObjs)
else:
return _mask.area([rleObjs])[0]
def toBbox(rleObjs):
if type(rleObjs) == list:
return _mask.toBbox(rleObjs)
else:
return _mask.toBbox([rleObjs])[0]
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os.path as osp
import random
from eiseg import pjpath
class ColorMap(object):
def __init__(self, color_path, shuffle=False):
self.colors = []
self.index = 0
self.usedColors = []
with open(color_path, "r") as f:
colors = f.readlines()
if shuffle:
random.shuffle(colors)
self.colors = [[int(x) for x in c.strip().split(",")] for c in colors]
def get_color(self):
color = self.colors[self.index]
self.index = (self.index + 1) % len(self)
return color
def __len__(self):
return len(self.colors)
colorMap = ColorMap(osp.join(pjpath, "config/colormap.txt"))
import yaml
import os.path as osp
import os
from eiseg import pjpath
def parse_configs(path):
if not path or not osp.exists(path):
return
with open(path, "r", encoding="utf-8") as f:
return yaml.load(f.read(), Loader=yaml.FullLoader)
def save_configs(path=None, config=None, actions=None):
if not path:
path = osp.join(pjpath, "config/config.yaml")
if not osp.exists(path):
# os.makedirs(osp.basename(path))
# windows无法使用mknod
f = open(path, "w+")
f.close()
if not config:
config = {}
if actions:
config["shortcut"] = {}
for action in actions:
config["shortcut"][action.data()] = action.shortcut().toString()
with open(path, "w", encoding="utf-8") as f:
yaml.dump(config, f)
class cfgData(object):
def __init__(self, yaml_file):
with open(yaml_file, "r", encoding="utf-8") as f:
fig_data = f.read()
self.dicts = yaml.load(fig_data)
def get(self, key):
if key in self.dicts.keys():
return self.dicts[key]
else:
raise ValueError("Not find this keyword.")
if __name__ == "__main__":
cfg = cfgData("EISeg/train/train_config.yaml")
print(cfg.get("use_vdl"))
import paddle
from functools import partial
from easydict import EasyDict as edict
from albumentations import *
from data.datasets import *
from model.losses import *
from data.transforms import *
#from isegm.engine.trainer import ISTrainer
from model.metrics import AdaptiveIoU
from data.points_sampler import MultiPointSampler
from model.initializer import XavierGluon
from model.is_hrnet_model import HRNetModel
from model.is_deeplab_model import DeeplabModel
\ No newline at end of file
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import os.path as osp
from . import colorMap
class Label:
def __init__(self, idx=None, name=None, color=None):
self.idx = idx
self.name = name
self.color = color
def __repr__(self):
return f"{self.idx} {self.name} {self.color}"
class LabelList(object):
def __init__(self, labels: dict=None):
self.labelList = []
if labels is not None:
for lab in labels:
color = lab.get("color", colorMap.get_color())
self.add(lab["id"], lab["name"], color)
def add(self, idx, name, color):
self.labelList.append(Label(idx, name, color))
def remove(self, index):
for idx, lab in enumerate(self.labelList):
if lab.idx == index:
del self.labelList[idx]
break
# del self.labelList[index]
def clear(self):
self.labelList = []
def toint(self, seq):
if isinstance(seq, list):
for i in range(len(seq)):
try:
seq[i] = int(seq[i])
except ValueError:
pass
else:
seq = int(seq)
return seq
def importLabel(self, path):
if not osp.exists(path):
return []
with open(path, "r", encoding="utf-8") as f:
labels = f.readlines()
labelList = []
for lab in labels:
lab = lab.replace("\n", "").strip(" ").split(" ")
if len(lab) != 5: # rm: and len(lab) != 2
print(f"{lab} 标签不合法")
continue
label = Label(self.toint(lab[0]), str(lab[1]), self.toint(lab[2:]))
labelList.append(label)
self.labelList = labelList
def exportLabel(self, path):
if not path or not osp.exists(osp.dirname(path)):
print("label path don't exist")
return
with open(path, "w", encoding="utf-8") as f:
for label in self.labelList:
print(label.idx, end=" ", file=f)
print(label.name, end=" ", file=f)
for idx in range(3):
print(label.color[idx], end=" ", file=f)
print(file=f)
def getLabelById(self, labelIdx):
for lab in self.labelList:
if lab.idx == labelIdx:
return lab
def __repr__(self):
return str(self.labelList)
def __getitem__(self, index):
return self.labelList[index]
def __len__(self):
return len(self.labelList)
@property
def colors(self):
cols = []
for lab in self.labelList:
cols.append(lab.color)
return cols
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os.path as osp
import re
from eiseg import pjpath
from collections import defaultdict
import json
from urllib import parse
import requests
class TransUI(object):
def __init__(self, is_trans=False):
super().__init__()
self.trans_dict = defaultdict(dict)
with open(
osp.join(pjpath, "config/zh_CN.EN"), "r",
encoding="utf-8") as f:
texts = f.readlines()
for txt in texts:
strs = txt.split("@")
self.trans_dict[strs[0].strip()] = strs[1].strip()
self.is_trans = is_trans
self.youdao_url = "http://fanyi.youdao.com/translate?&doctype=json&type=AUTO&i="
def put(self, zh_CN):
if self.is_trans == False:
return zh_CN
else:
try:
return str(self.trans_dict[zh_CN])
except:
return zh_CN
# 联网动态翻译
def tr(self, zh_CN):
try:
tr_url = self.youdao_url + parse.quote(zh_CN)
response = requests.get(tr_url)
js = json.loads(response.text)
result_EN = js["translateResult"][0][0]["tgt"]
return str(result_EN)
except:
return zh_CN
import inspect
from collections.abc import Sequence
class ComponentManager:
def __init__(self, name=None):
self._components_dict = dict()
self._name = name
def __len__(self):
return len(self._components_dict)
def __repr__(self):
name_str = self._name if self._name else self.__class__.__name__
return "{}:{}".format(name_str, list(self._components_dict.keys()))
def __getitem__(self, item):
if isinstance(item, int):
if item >= len(self):
raise KeyError(f"指定的下标 {item} 在长度为 {len(self)}{self} 中越界")
return list(self._components_dict.values())[item]
if item not in self._components_dict.keys():
raise KeyError(f"{self} 中不存在 {item}")
return self._components_dict[item]
def __iter__(self):
for val in self._components_dict.values():
yield val
def keys(self):
return list(self._components_dict.keys())
def idx(self, item):
for idx, val in enumerate(self.keys()):
if val == item:
return idx
raise KeyError(f"{item} is not in {self}")
@property
def components_dict(self):
return self._components_dict
@property
def name(self):
return self._name
def _add_single_component(self, component):
# Currently only support class or function type
if not (inspect.isclass(component) or inspect.isfunction(component)):
raise TypeError("Expect class/function type, but received {}".
format(type(component)))
# Obtain the internal name of the component
component_name = component.__name__
# Check whether the component was added already
if component_name in self._components_dict.keys():
raise KeyError("{} exists already!".format(component_name))
else:
# Take the internal name of the component as its key
self._components_dict[component_name] = component
def add_component(self, components):
# Check whether the type is a sequence
if isinstance(components, Sequence):
for component in components:
self._add_single_component(component)
else:
component = components
self._add_single_component(component)
return components
MODELS = ComponentManager("models")
ACTIONS = ComponentManager("actions")
import paddle
import numpy as np
import pickle
def get_dims_with_exclusion(dim, exclude=None):
dims = list(range(dim))
if exclude is not None:
dims.remove(exclude)
return dims
def save_checkpoint(net,
checkpoints_path,
epoch=None,
prefix="",
verbose=True,
multi_gpu=False):
if epoch is None:
checkpoint_name = "last_checkpoint.pdparams"
else:
checkpoint_name = f"{epoch:03d}.pdparams"
if prefix:
checkpoint_name = f"{prefix}_{checkpoint_name}"
if not checkpoints_path.exists():
checkpoints_path.mkdir(parents=True)
checkpoint_path = checkpoints_path / checkpoint_name
net = net.module if multi_gpu else net
# model_state = {'state_dict': net.state_dict(),'config': net.__dict__}
paddle.save(net.state_dict(), checkpoint_path)
def get_bbox_from_mask(mask):
rows = np.any(mask, axis=1)
cols = np.any(mask, axis=0)
rmin, rmax = np.where(rows)[0][[0, -1]]
cmin, cmax = np.where(cols)[0][[0, -1]]
return rmin, rmax, cmin, cmax
def expand_bbox(bbox, expand_ratio, min_crop_size=None):
rmin, rmax, cmin, cmax = bbox
rcenter = 0.5 * (rmin + rmax)
ccenter = 0.5 * (cmin + cmax)
height = expand_ratio * (rmax - rmin + 1)
width = expand_ratio * (cmax - cmin + 1)
if min_crop_size is not None:
height = max(height, min_crop_size)
width = max(width, min_crop_size)
rmin = int(round(rcenter - 0.5 * height))
rmax = int(round(rcenter + 0.5 * height))
cmin = int(round(ccenter - 0.5 * width))
cmax = int(round(ccenter + 0.5 * width))
return rmin, rmax, cmin, cmax
def clamp_bbox(bbox, rmin, rmax, cmin, cmax):
return (
max(rmin, bbox[0]),
min(rmax, bbox[1]),
max(cmin, bbox[2]),
min(cmax, bbox[3]), )
def get_bbox_iou(b1, b2):
h_iou = get_segments_iou(b1[:2], b2[:2])
w_iou = get_segments_iou(b1[2:4], b2[2:4])
return h_iou * w_iou
def get_segments_iou(s1, s2):
a, b = s1
c, d = s2
intersection = max(0, min(b, d) - max(a, c) + 1)
union = max(1e-6, max(b, d) - min(a, c) + 1)
return intersection / union
def get_labels_with_sizes(x):
obj_sizes = np.bincount(x.flatten())
labels = np.nonzero(obj_sizes)[0].tolist()
labels = [x for x in labels if x != 0]
return labels, obj_sizes[labels].tolist()
import re
# 检查中文
def check_cn(path):
zh_model = re.compile(u'[\u4e00-\u9fa5]')
return zh_model.search(path)
# 替换斜杠
def normcase(path):
return eval(repr(path).replace('\\\\', '/'))
import numpy as np
def get_color_map(N=256):
def bitget(byteval, idx):
return ((byteval & (1 << idx)) != 0)
cmap = np.zeros((N, 3), dtype=np.uint8)
for i in range(N):
r = g = b = 0
c = i
for j in range(8):
r = r | (bitget(c, 0) << 7 - j)
g = g | (bitget(c, 1) << 7 - j)
b = b | (bitget(c, 2) << 7 - j)
c = c >> 3
cmap[i] = np.array([r, g, b])
return cmap
color_map = get_color_map()
def pal_color_map():
return color_map
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from enum import Enum
import cv2
import numpy as np
import math
from .regularization import boundary_regularization
class Instructions(Enum):
No_Instruction = 0
Polygon_Instruction = 1
def get_polygon(label, sample="Dynamic", img_size=None, building=False):
results = cv2.findContours(
image=label, mode=cv2.RETR_TREE,
method=cv2.CHAIN_APPROX_TC89_KCOS) # 获取内外边界,用RETR_TREE更好表示
cv2_v = cv2.__version__.split(".")[0]
contours = results[1] if cv2_v == "3" else results[0] # 边界
hierarchys = results[2] if cv2_v == "3" else results[1] # 隶属信息
if len(contours) != 0: # 可能出现没有边界的情况
polygons = []
relas = []
img_shape = label.shape
for idx, (contour,
hierarchy) in enumerate(zip(contours, hierarchys[0])):
# print(hierarchy)
# opencv实现边界简化
epsilon = (0.005 * cv2.arcLength(contour, True)
if sample == "Dynamic" else sample)
if not isinstance(epsilon, float) and not isinstance(epsilon, int):
epsilon = 0
# print("epsilon:", epsilon)
if building is False:
# -- Douglas-Peucker算法边界简化
contour = cv2.approxPolyDP(contour, epsilon / 10, True)
else:
# -- 建筑边界简化(https://github.com/niecongchong/RS-building-regularization)
if contour.shape[0] >= 2:
contour = boundary_regularization(contour, img_shape, epsilon)
# -- 自定义(角度和距离)边界简化
out = approx_poly_DIY(contour)
# 给出关系
rela = (
idx, # own
hierarchy[-1] if hierarchy[-1] != -1 else None, ) # parent
polygon = []
for p in out:
polygon.append(p[0])
polygons.append(polygon) # 边界
relas.append(rela) # 关系
for i in range(len(relas)):
if relas[i][1] != None: # 有父圈
for j in range(len(relas)):
if relas[j][0] == relas[i][1]: # i的父圈就是j(i是j的子圈)
if polygons[i] is not None and polygons[j] is not None:
min_i, min_o = __find_min_point(polygons[i],
polygons[j])
# 改变顺序
polygons[i] = __change_list(polygons[i], min_i)
polygons[j] = __change_list(polygons[j], min_o)
# 连接
if min_i != -1 and len(polygons[i]) > 0:
polygons[j].extend(polygons[i]) # 连接内圈
polygons[i] = None
polygons = list(filter(None, polygons)) # 清除加到外圈的内圈多边形
if img_size is not None:
polygons = check_size_minmax(polygons, img_size)
return polygons
else:
print("没有标签范围,无法生成边界")
return None
def __change_list(polygons, idx):
if idx == -1:
return polygons
s_p = polygons[:idx]
polygons = polygons[idx:]
polygons.extend(s_p)
polygons.append(polygons[0]) # 闭合圈
return polygons
def __find_min_point(i_list, o_list):
min_dis = 1e7
idx_i = -1
idx_o = -1
for i in range(len(i_list)):
for o in range(len(o_list)):
dis = math.sqrt((i_list[i][0] - o_list[o][0])**2 + (i_list[i][
1] - o_list[o][1])**2)
if dis <= min_dis:
min_dis = dis
idx_i = i
idx_o = o
return idx_i, idx_o
# 根据三点坐标计算夹角
def __cal_ang(p1, p2, p3):
eps = 1e-12
a = math.sqrt((p2[0] - p3[0]) * (p2[0] - p3[0]) + (p2[1] - p3[1]) * (p2[1] -
p3[1]))
b = math.sqrt((p1[0] - p3[0]) * (p1[0] - p3[0]) + (p1[1] - p3[1]) * (p1[1] -
p3[1]))
c = math.sqrt((p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] -
p2[1]))
ang = math.degrees(math.acos(
(b**2 - a**2 - c**2) / (-2 * a * c + eps))) # p2对应
return ang
# 计算两点距离
def __cal_dist(p1, p2):
return math.sqrt((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2)
# 边界点简化
def approx_poly_DIY(contour, min_dist=10, ang_err=5):
# print(contour.shape) # N, 1, 2
cs = [contour[i][0] for i in range(contour.shape[0])]
## 1. 先删除两个相近点与前后两个点角度接近的点
i = 0
while i < len(cs):
try:
j = (i + 1) if (i != len(cs) - 1) else 0
if __cal_dist(cs[i], cs[j]) < min_dist:
last = (i - 1) if (i != 0) else (len(cs) - 1)
next = (j + 1) if (j != len(cs) - 1) else 0
ang_i = __cal_ang(cs[last], cs[i], cs[next])
ang_j = __cal_ang(cs[last], cs[j], cs[next])
# print(ang_i, ang_j) # 角度值为-180到+180
if abs(ang_i - ang_j) < ang_err:
# 删除距离两点小的
dist_i = __cal_dist(cs[last], cs[i]) + __cal_dist(cs[i],
cs[next])
dist_j = __cal_dist(cs[last], cs[j]) + __cal_dist(cs[j],
cs[next])
if dist_j < dist_i:
del cs[j]
else:
del cs[i]
else:
i += 1
else:
i += 1
except:
i += 1
## 2. 再删除夹角接近180度的点
i = 0
while i < len(cs):
try:
last = (i - 1) if (i != 0) else (len(cs) - 1)
next = (i + 1) if (i != len(cs) - 1) else 0
ang_i = __cal_ang(cs[last], cs[i], cs[next])
if abs(ang_i) > (180 - ang_err):
del cs[i]
else:
i += 1
except:
# i += 1
del cs[i]
res = np.array(cs).reshape([-1, 1, 2])
return res
def check_size_minmax(polygons, img_size):
h_max, w_max = img_size
for ps in polygons:
for j in range(len(ps)):
x, y = ps[j]
if x < 0:
x = 0
elif x > w_max:
x = w_max
if y < 0:
y = 0
elif y > h_max:
y = h_max
ps[j] = np.array([x, y])
return polygons
from math import sqrt
import os.path as osp
import numpy as np
from eiseg import pjpath
from qtpy import QtCore
from qtpy import QtGui
from qtpy import QtWidgets
from .config import parse_configs
shortcuts = parse_configs(osp.join(pjpath, "config/config.yaml"))["shortcut"]
here = osp.dirname(osp.abspath(__file__))
def newIcon(icon):
if isinstance(icon, list) or isinstance(icon, tuple):
pixmap = QtGui.QPixmap(100, 100)
c = icon
pixmap.fill(QtGui.QColor(c[0], c[1], c[2]))
return QtGui.QIcon(pixmap)
icons_dir = osp.join(here, "../resource")
return QtGui.QIcon(osp.join(":/", icons_dir, f"{icon}.png"))
def newButton(text, icon=None, slot=None):
b = QtWidgets.QPushButton(text)
if icon is not None:
b.setIcon(newIcon(icon))
if slot is not None:
b.clicked.connect(slot)
return b
def newAction(
parent,
text,
slot=None,
shortcutName=None,
icon=None,
tip=None,
checkable=False,
enabled=True,
checked=False, ):
"""Create a new action and assign callbacks, shortcuts, etc."""
a = QtWidgets.QAction(text, parent)
a.setData(shortcutName)
# a = QtWidgets.QAction("", parent)
if icon is not None:
a.setIconText(text.replace(" ", "\n"))
a.setIcon(newIcon(icon))
shortcut = shortcuts.get(shortcutName, None)
if shortcut is not None:
if isinstance(shortcut, (list, tuple)):
a.setShortcuts(shortcut)
else:
a.setShortcut(shortcut)
if tip is not None:
a.setToolTip(tip)
a.setStatusTip(tip)
if slot is not None:
a.triggered.connect(slot)
if checkable:
a.setCheckable(True)
a.setEnabled(enabled)
a.setChecked(checked)
return a
def addActions(widget, actions):
for action in actions:
if action is None:
widget.addSeparator()
elif isinstance(action, QtWidgets.QMenu):
widget.addMenu(action)
else:
widget.addAction(action)
def labelValidator():
return QtGui.QRegExpValidator(QtCore.QRegExp(r"^[^ \t].+"), None)
class struct(object):
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
def __len__(self):
return len(self.__dict__)
def append(self, action):
if isinstance(action, QtWidgets.QAction):
self.__dict__.update({action.data(): action})
def __iter__(self):
return list(self.__dict__.values()).__iter__()
def __getitem__(self, idx):
return list(self.__dict__.values())[idx]
def get(self, name):
return self.__dict__[name]
def fmtShortcut(text):
mod, key = text.split("+", 1)
return "<b>%s</b>+<b>%s</b>" % (mod, key)
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
This code is based on https://github.com/niecongchong/RS-building-regularization
Ths copyright of niecongchong/RS-building-regularization is as follows:
Apache License [see LICENSE for details]
"""
from .rs_regularization import boundary_regularization
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
This code is based on https://github.com/niecongchong/RS-building-regularization
Ths copyright of niecongchong/RS-building-regularization is as follows:
Apache License [see LICENSE for details]
"""
import numpy as np
# 线生成函数
def line(p1, p2):
A = (p1[1] - p2[1])
B = (p2[0] - p1[0])
C = (p1[0] * p2[1] - p2[0] * p1[1])
return A, B, -C
# 计算两条直线之间的交点
def intersection(L1, L2):
D = L1[0] * L2[1] - L1[1] * L2[0]
Dx = L1[2] * L2[1] - L1[1] * L2[2]
Dy = L1[0] * L2[2] - L1[2] * L2[0]
if D != 0:
x = Dx / D
y = Dy / D
return x, y
else:
return False
# 计算两个平行线之间的距离
def par_line_dist(L1, L2):
A1, B1, C1 = L1
A2, B2, C2 = L2
new_A1 = 1
new_B1 = B1 / A1
new_C1 = C1 / A1
new_A2 = 1
new_B2 = B2 / A2
new_C2 = C2 / A2
dist = (np.abs(new_C1 - new_C2)) / (np.sqrt(new_A2**2 + new_B2**2))
return dist
# 计算点在直线的投影位置
def point_in_line(m, n, x1, y1, x2, y2):
eps = 1e-12
x = (m * (x2 - x1) * (x2 - x1) + n * (y2 - y1) * (x2 - x1) +
(x1 * y2 - x2 * y1) * (y2 - y1)) / (
(x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1))
y = (m * (x2 - x1) * (y2 - y1) + n * (y2 - y1) * (y2 - y1) +
(x2 * y1 - x1 * y2) * (x2 - x1)) / (
(x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1))
return (x, y)
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
This code is based on https://github.com/niecongchong/RS-building-regularization
Ths copyright of niecongchong/RS-building-regularization is as follows:
Apache License [see LICENSE for details]
"""
import numpy as np
import math
# 计算两点距离
def cal_dist(point_1, point_2):
dist = np.sqrt(np.sum(np.power((point_1 - point_2), 2)))
return dist
# 计算两条线的夹角
def cal_ang(point_1, point_2, point_3):
def _cal_pp(p_1, p_2):
return math.sqrt((p_1[0] - p_2[0]) * (p_1[0] - p_2[0]) + (p_1[1] - p_2[
1]) * (p_1[1] - p_2[1]))
a = _cal_pp(point_2, point_3)
b = _cal_pp(point_1, point_3)
c = _cal_pp(point_1, point_2)
B = math.degrees(math.acos((b**2 - a**2 - c**2) / (-2 * a * c)))
return B
# 计算线条的方位角
def cal_azimuth(point_0, point_1):
x1, y1 = point_0
x2, y2 = point_1
if x1 < x2:
if y1 < y2:
ang = math.atan((y2 - y1) / (x2 - x1))
ang = ang * 180 / math.pi
return ang
elif y1 > y2:
ang = math.atan((y1 - y2) / (x2 - x1))
ang = ang * 180 / math.pi
return 90 + (90 - ang)
elif y1 == y2:
return 0
elif x1 > x2:
if y1 < y2:
ang = math.atan((y2 - y1) / (x1 - x2))
ang = ang * 180 / math.pi
return 90 + (90 - ang)
elif y1 > y2:
ang = math.atan((y1 - y2) / (x1 - x2))
ang = ang * 180 / math.pi
return ang
elif y1 == y2:
return 0
elif x1 == x2:
return 90
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
This code is based on https://github.com/niecongchong/RS-building-regularization
Ths copyright of niecongchong/RS-building-regularization is as follows:
Apache License [see LICENSE for details]
"""
"""
rdp
~~~
Pure Python implementation of the Ramer-Douglas-Peucker algorithm.
:copyright: (c) 2014 Fabian Hirschmann <fabian@hirschmann.email>
:license: MIT, see LICENSE.txt for more details.
"""
import numpy as np
def pldist(x0, x1, x2):
"""
Calculates the distance from the point ``x0`` to the line given
by the points ``x1`` and ``x2``.
:param x0: a point
:type x0: a 2x1 numpy array
:param x1: a point of the line
:type x1: 2x1 numpy array
:param x2: another point of the line
:type x2: 2x1 numpy array
"""
x0, x1, x2 = x0[:2], x1[:2], x2[:2] # discard timestamp
if x1[0] == x2[0]:
return np.abs(x0[0] - x1[0])
return np.divide(
np.linalg.norm(np.linalg.det([x2 - x1, x1 - x0])),
np.linalg.norm(x2 - x1))
def _rdp(M, epsilon, dist):
"""
Simplifies a given array of points.
:param M: an array
:type M: Nx2 numpy array
:param epsilon: epsilon in the rdp algorithm
:type epsilon: float
:param dist: distance function
:type dist: function with signature ``f(x1, x2, x3)``
"""
dmax = 0.0
index = -1
for i in range(1, M.shape[0]):
d = dist(M[i], M[0], M[-1])
if d > dmax:
index = i
dmax = d
if dmax > epsilon:
r1 = _rdp(M[:index + 1], epsilon, dist)
r2 = _rdp(M[index:], epsilon, dist)
return np.vstack((r1[:-1], r2))
else:
return np.vstack((M[0], M[-1]))
def _rdp_nn(seq, epsilon, dist):
"""
Simplifies a given array of points.
:param seq: a series of points
:type seq: sequence of 2-tuples
:param epsilon: epsilon in the rdp algorithm
:type epsilon: float
:param dist: distance function
:type dist: function with signature ``f(x1, x2, x3)``
"""
return _rdp(np.array(seq), epsilon, dist).tolist()
def rdp(M, epsilon=0, dist=pldist):
"""
Simplifies a given array of points.
:param M: a series of points
:type M: either a Nx2 numpy array or sequence of 2-tuples
:param epsilon: epsilon in the rdp algorithm
:type epsilon: float
:param dist: distance function
:type dist: function with signature ``f(x1, x2, x3)``
"""
if "numpy" in str(type(M)):
return _rdp(M, epsilon, dist)
return _rdp_nn(M, epsilon, dist)
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
This code is based on https://github.com/niecongchong/RS-building-regularization
Ths copyright of niecongchong/RS-building-regularization is as follows:
Apache License [see LICENSE for details]
"""
import math
# 顺时针旋转
def Nrotation_angle_get_coor_coordinates(point, center, angle):
src_x, src_y = point
center_x, center_y = center
radian = math.radians(angle)
dest_x = (src_x - center_x) * math.cos(radian) + \
(src_y - center_y) * math.sin(radian) + center_x
dest_y = (src_y - center_y) * math.cos(radian) - \
(src_x - center_x) * math.sin(radian) + center_y
# return (int(dest_x), int(dest_y))
return (dest_x, dest_y)
# 逆时针旋转
def Srotation_angle_get_coor_coordinates(point, center, angle):
src_x, src_y = point
center_x, center_y = center
radian = math.radians(angle)
dest_x = (src_x - center_x) * math.cos(radian) - \
(src_y - center_y) * math.sin(radian) + center_x
dest_y = (src_x - center_x) * math.sin(radian) + \
(src_y - center_y) * math.cos(radian) + center_y
# return [int(dest_x), int(dest_y)]
return (dest_x, dest_y)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment