darwinharianto commited on
Commit
7b2bba1
·
1 Parent(s): 0057f36

first push

Browse files
Files changed (2) hide show
  1. app.py +137 -0
  2. requirements.txt +2 -0
app.py ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from nest2D import Point, Box, Item, nest, SVGWriter
2
+ import plotly
3
+ import numpy as np
4
+ import plotly.graph_objects as go
5
+ import cv2
6
+ import gradio as gr
7
+
8
+ def transform(point:list[float], x:float, y:float, rotation:float):
9
+ if point is None:
10
+ return None
11
+
12
+ point = np.array([point[0], point[1], 1])
13
+ matrix = np.array([[np.cos(rotation), -np.sin(rotation), x],
14
+ [np.sin(rotation), np.cos(rotation), y],
15
+ [0,0,1]])
16
+
17
+ return (matrix@point)[:2]
18
+
19
+ class BinPacking:
20
+
21
+ def __init__(self, width:int, height:int, image:np.ndarray, imageScale:float=1) -> None:
22
+ self.width = width
23
+ self.height = height
24
+ self.pgrp = None
25
+ print(image.shape)
26
+ self.image = cv2.resize(image, (int(image.shape[1]*imageScale), int(image.shape[0]*imageScale)))
27
+ if self.image.shape[2] == 4:
28
+ x,y = np.where(self.image[:,:,3]==0)
29
+ self.image[x,y] = np.array([255,255,255,0])
30
+ self.imgray = cv2.cvtColor(self.image, cv2.COLOR_BGRA2GRAY)
31
+ else:
32
+ self.imgray = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
33
+ self.imgray = cv2.bitwise_not(self.imgray)
34
+
35
+ @property
36
+ def box(self):
37
+ return Box(self.width, self.height)
38
+
39
+ def pack(self):
40
+ # make margin
41
+ imagem = cv2.dilate(self.imgray, np.ones((3,3), np.uint8), iterations=10)
42
+ _, thresh = cv2.threshold(imagem, 127, 255, 0)
43
+
44
+ contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
45
+ contourList = []
46
+ for contour in contours:
47
+ contourList.extend(contour)
48
+
49
+ hull = cv2.convexHull(np.array(contourList).reshape(-1,2))
50
+ hull = np.append(hull, [hull[0]], axis=0).reshape(-1,2)
51
+ item = Item(
52
+ [
53
+ Point(point[0], point[1])
54
+ for point in np.flip(hull, 0)
55
+ ]
56
+ )
57
+
58
+ max_item = int(self.width*self.height/item.area)
59
+ self.pgrp = nest([item,]*max_item, self.box)
60
+
61
+ return self
62
+
63
+ def visualize(self):
64
+ if self.pgrp == None:
65
+ return None
66
+
67
+ _, thresh = cv2.threshold(self.imgray, 127, 255, 0)
68
+ contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
69
+ transformedPoints = []
70
+ for item in self.pgrp[0]:
71
+ for contour in contours:
72
+ for point in contour:
73
+ transformedPoints.append(transform(point[0], item.translation.x, item.translation.y, item.rotation))
74
+ transformedPoints.append([None,None])
75
+ transformedPoints.append([None,None])
76
+
77
+ fig = go.Figure()
78
+ fig.add_trace(go.Scatter(
79
+ x=[0, self.width, self.width, 0, 0],
80
+ y=[0, 0, self.height, self.height, 0],
81
+ fill="toself",
82
+ mode="lines",
83
+ textposition="bottom right",
84
+ ))
85
+ fig.add_trace(go.Scatter(
86
+ x=[point[0] for point in transformedPoints],
87
+ y=[point[1] for point in transformedPoints],
88
+ mode="lines",
89
+ textposition="bottom right",
90
+ ))
91
+ fig.update_layout(
92
+ autosize=False,
93
+ width=500,
94
+ height=500,
95
+ margin=dict(
96
+ l=50,
97
+ r=50,
98
+ b=100,
99
+ t=100,
100
+ pad=4
101
+ ),
102
+ paper_bgcolor="LightSteelBlue",
103
+ )
104
+ return fig
105
+
106
+
107
+ def process(width:int, height:int, scale:float, image: np.ndarray):
108
+
109
+ packer = BinPacking(width, height, image, scale)
110
+
111
+ packer.pack()
112
+ figure = packer.visualize()
113
+ return figure
114
+
115
+
116
+ if __name__ == "__main__":
117
+ with gr.Blocks() as demo:
118
+ gr.Markdown(
119
+ """
120
+ # Image fitting
121
+ """
122
+ )
123
+
124
+ with gr.Row():
125
+ with gr.Column():
126
+ image = gr.Image(image_mode="RGBA")
127
+ with gr.Row():
128
+ width = gr.Number(1500,precision=0)
129
+ height = gr.Number(1500,precision=0)
130
+ scale = gr.Number(1.0)
131
+ fit = gr.Button("Submit")
132
+
133
+ plot_output = gr.Plot()
134
+
135
+ fit.click(fn=process, inputs=[width, height, scale, image], outputs=plot_output)
136
+
137
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ plotly
2
+ nest2D