Skip to content

Commit 9104606

Browse files
committed
2.0
1 parent 4b9bafa commit 9104606

11 files changed

+812
-1184
lines changed

3D Build.ipynb

Lines changed: 0 additions & 546 deletions
This file was deleted.

3D_Build.py

Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
#!/usr/bin/env python
2+
# coding: utf-8
3+
4+
# In[ ]:
5+
6+
7+
import copy
8+
import json
9+
import os
10+
import shutil
11+
import cv2
12+
import time
13+
import numpy as np
14+
from matplotlib import pyplot as plt
15+
from IPython.display import Image
16+
import import_ipynb
17+
from rotate_translate import node
18+
from parent_child_tree import createtree
19+
from multipleoperation import *
20+
from subprocess import run
21+
import open3d as o3d
22+
import time
23+
from pyntcloud import PyntCloud
24+
25+
26+
# Below Code generates 2 Contours for a given shape. One 'Outer Contour' and other 'Inner Contour' for a 2 shape .
27+
#
28+
29+
# In[ ]:
30+
31+
32+
print("Please enter the image view file with extension")
33+
s=input()
34+
image=cv2.imread(s)
35+
imgray=cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
36+
ret, thresh = cv2.threshold(imgray,127,255,0,cv2.THRESH_BINARY_INV)
37+
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_NONE)
38+
hierarchy,contours = zip(*sorted(zip(hierarchy[0],contours),key = lambda x: cv2.contourArea(x[1]),reverse=True))
39+
print ("no, of contours = " + str(len(contours)-1))
40+
cv2.drawContours(image, contours, 1, (0, 255, 0), 2)
41+
cv2.drawContours(image, contours, 2, (0, 0 , 255), 2)
42+
cv2.imshow('IMAGE', image)
43+
cv2.imshow('Image Gray', imgray)
44+
cv2.waitKey(0)
45+
46+
47+
# In[ ]:
48+
49+
50+
print("Please enter the image view file with extension")
51+
s=input()
52+
image=cv2.imread(s)
53+
imgray=cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
54+
ret, thresh = cv2.threshold(imgray,127,255,0,cv2.THRESH_BINARY_INV)
55+
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_NONE)
56+
hierarchy,contours = zip(*sorted(zip(hierarchy[0],contours),key = lambda x: cv2.contourArea(x[1]),reverse=True))
57+
58+
59+
# Below Function 'detect()' will determine the shape of a given 2D image on the basis of number of edges in the given Shape .
60+
61+
# Allowed Shapes for a 2d Image are : Triangle , Square , Rectangle , Pentagon , Hexagon , Circle
62+
#
63+
64+
# In[ ]:
65+
66+
67+
def detect(c):
68+
perimeter = cv2.arcLength(c, True)
69+
approx = cv2.approxPolyDP(c, 0.02 * perimeter , True)
70+
if len(approx) == 3:
71+
shape = "triangle"
72+
elif len(approx) == 4:
73+
(x, y, w, h) = cv2.boundingRect(approx)
74+
ar = w / float(h)
75+
if (ar >= 0.999 and ar <= 1.001):
76+
shape = "square"
77+
else:
78+
shape = "rectangle"
79+
elif len(approx) == 5:
80+
shape = "pentagon"
81+
elif len(approx) == 6:
82+
shape = "hexagon"
83+
else:
84+
shape = "circle"
85+
return shape
86+
87+
88+
# In[ ]:
89+
90+
91+
d=detect(contours[1])
92+
print(d)
93+
94+
95+
# Below 'Dimensioning()' function stores the image temprory amd gives Image imformation like its 'Shape' and 'Ratio'
96+
97+
# In[ ]:
98+
99+
100+
def Dimensioning(userId,view,image):
101+
os.makedirs('static/temp', exist_ok=True)
102+
img = cv2.imread(image,cv2.IMREAD_UNCHANGED)
103+
ratio = 0
104+
shape = "unidentified"
105+
try:
106+
w,h,_=img.shape
107+
drawSize = int(h/300)
108+
imgrey = cv2.cvtColor(img.copy(),cv2.COLOR_BGR2GRAY)
109+
ret, thresh = cv2.threshold(imgrey,127,255,cv2.THRESH_BINARY_INV)
110+
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_SIMPLE)
111+
hierarchy,contours = zip(*sorted(zip(hierarchy[0],contours),key = lambda x: cv2.contourArea(x[1]),reverse=True))
112+
for i,c in enumerate(contours):
113+
if(hierarchy[i][3] != -1 or (hierarchy[i][3] == -1 and hierarchy[i][2] == -1) ):
114+
M = cv2.moments(c)
115+
if(M["m00"] !=0):
116+
cX = int(M["m10"] / M["m00"])
117+
cY = int(M["m01"] / M["m00"])
118+
rect = cv2.minAreaRect(c)
119+
box = cv2.boxPoints(rect)
120+
box = np.int0(box)
121+
x,y,w,h = cv2.boundingRect(c)
122+
shape, cylinder_type = detect(c)
123+
if(shape == "unidentified"):
124+
continue
125+
if(shape=="triangle" or shape=="pentagon" or shape=="hexagon"):
126+
img = cv2.drawContours(img, [box], 0, (0,0, 255), drawSize)
127+
if(shape=="circle"):
128+
img = cv2.rectangle(img,(x,y),(x+w,y+h),(0, 0, 255),drawSize)
129+
cv2.line(img, (x,y), (x+w,y), (0,255, 0), 2)
130+
ratio = 1/w
131+
else:
132+
cv2.line(img, tuple(box[0]), tuple(box[1]), (0,255, 0), 2)
133+
ratio = 1.0/rect[1][1]
134+
break
135+
folder = 'static/temp/' + userId
136+
os.makedirs(folder, exist_ok=True)
137+
try:
138+
os.remove(folder + '/' + view + '.jpg')
139+
except: pass
140+
path_file = (folder + '/' + view + '.jpg')
141+
small = cv2.resize(img, (0,0), fx=0.5, fy=0.5)
142+
cv2.imwrite(path_file,small)
143+
ratio = str(ratio)
144+
data={'image': path_file,'shape': shape,'ratio': ratio}
145+
display(Image(filename = path_file))
146+
return data
147+
except:
148+
print(view + "image not found")
149+
150+
151+
# In[ ]:
152+
153+
154+
def Convert(userId, front_image, side_image, top_image, fratio, sratio, tratio):
155+
start = time.time()
156+
os.makedirs('static/'+userId, exist_ok=True)
157+
img_front = cv2.imread(front_image,cv2.IMREAD_UNCHANGED)
158+
img_side = cv2.imread(side_image,cv2.IMREAD_UNCHANGED)
159+
img_top = cv2.imread(top_image,cv2.IMREAD_UNCHANGED)
160+
fratio = float(fratio)
161+
sratio = float(sratio)
162+
tratio = float(tratio)
163+
filePath = "static/temp/"+userId
164+
try:
165+
shutil.rmtree(filePath)
166+
except OSError as e:
167+
print ("Error: %s - %s." % (e.filename, e.strerror))
168+
primitive = []
169+
object_front = valid_contours(img_front,"front",fratio)
170+
re_arrange(object_front,"front")
171+
object_side = valid_contours(img_side,"side",sratio)
172+
re_arrange(object_side,"side")
173+
object_top = valid_contours(img_top,"top",tratio)
174+
re_arrange(object_top,"top")
175+
minApprox = 0.05
176+
primitive = combining(object_front,object_side,object_top,minApprox)
177+
final = []
178+
for set in primitive:
179+
for shape in set:
180+
final.append(shape[0])
181+
try:
182+
os.remove('static/' + userId + "/" + userId + '.scad')
183+
except: pass
184+
path_file = ('static/' + userId + "/" + userId + '.scad')
185+
if(len(final) == 0):
186+
path_file = 'static/error.txt'
187+
f = open(path_file, "w")
188+
f.write("Cannot determine the 3d geometry, check your files again!")
189+
f.close()
190+
createtree(final,path_file)
191+
end = time.time()
192+
print("Total time taken to convert:",end-start)
193+
return path_file
194+
195+
196+
# In[ ]:
197+
198+
199+
userId="1"
200+
front_image = "TestBench/"+userId+"/front.jpg"
201+
side_image = "TestBench/"+userId+"/side.jpg"
202+
top_image = "TestBench/"+userId+"/top.jpg"
203+
front_image
204+
205+
206+
# In[ ]:
207+
208+
209+
d1 = Dimensioning(userId,"front",front_image)
210+
d1
211+
212+
213+
# In[ ]:
214+
215+
216+
d2 = Dimensioning(userId,"side",side_image)
217+
d2
218+
219+
220+
# In[ ]:
221+
222+
223+
d3 = Dimensioning(userId,"top",top_image)
224+
d3
225+
226+
227+
# In[ ]:
228+
229+
230+
fratio = float(d1["ratio"]) * 2
231+
sratio = float(d2["ratio"]) * 2
232+
tratio = float(d3["ratio"]) * 2
233+
234+
235+
# Convert Function joins the multiple 2D images with their respective Ratio to insert them in a tree to form a 3D model from it .
236+
# If the given shape consist of more than one shape (complex object in Image object) Than we will sub divide it to individual shapes and store them in tree as Parent and Child .
237+
238+
# In[ ]:
239+
240+
241+
Convert(userId,front_image, side_image, top_image,fratio, sratio, tratio)
242+
243+
244+
# Point Cloud Representation of the generated Scad File
245+
#
246+
247+
# In[ ]:
248+
249+
250+
print("please wait generating 3D view...")
251+
start = time.time()
252+
scad_filename = "static/" + userId + '/' + userId + ".1.scad"
253+
stl_filename = "static/" + userId + '/' + userId + ".stl"
254+
pcd_filename = "static/" + userId + '/' + userId + ".pcd"
255+
if(os.path.isfile(scad_filename)):
256+
run("openscad.exe -o " + stl_filename + " " + scad_filename)
257+
if(os.path.isfile(stl_filename)):
258+
print("stl file generated at " + stl_filename)
259+
mesh = o3d.io.read_triangle_mesh(stl_filename)
260+
pointcloud = mesh.sample_points_poisson_disk(100000)
261+
o3d.io.write_point_cloud(pcd_filename, pointcloud)
262+
model = PyntCloud.from_file(pcd_filename)
263+
print("pcd file generated at " + pcd_filename)
264+
model.plot()
265+
end = time.time()
266+
print("Total time taken to convert from stl to point cloud:",end-start)
267+
else:
268+
print("file not found")
269+
else:
270+
print("scad file not found")
271+
File renamed without changes.
File renamed without changes.

top.png renamed to Images/top.png

File renamed without changes.

Rotate_Translate.ipynb

Lines changed: 0 additions & 109 deletions
This file was deleted.

0 commit comments

Comments
 (0)