Skip to content

Commit aadbd6d

Browse files
author
yxdragon
committed
myvi update
1 parent c4eefb8 commit aadbd6d

File tree

3 files changed

+67
-12
lines changed

3 files changed

+67
-12
lines changed

imagepy/core/myvi/canvas3d.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ def __init__(self, parent, manager=None):
2424
self.Bind(wx.EVT_PAINT, self.OnPaint)
2525
self.Bind(wx.EVT_LEFT_DOWN, self.OnMouseDown)
2626
self.Bind(wx.EVT_LEFT_UP, self.OnMouseUp)
27+
self.Bind(wx.EVT_RIGHT_DOWN, self.OnMouseDown)
28+
self.Bind(wx.EVT_RIGHT_UP, self.OnMouseUp)
2729
self.Bind(wx.EVT_MOTION, self.OnMouseMotion)
2830
self.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel)
2931
self.lastx, self.lasty = None, None
@@ -73,12 +75,24 @@ def OnMouseMotion(self, evt):
7375
x, y = evt.GetPosition()
7476
dx, dy = x-self.lastx, y-self.lasty
7577
self.lastx, self.lasty = x, y
76-
#self.manager.h -= dx/200
7778
angx = self.manager.angx - dx/200
7879
angy = self.manager.angy + dy/200
79-
#print('ang', angx, angy)
8080
self.manager.set_pers(angx=angx, angy=angy)
8181
self.Refresh(False)
82+
if evt.Dragging() and evt.RightIsDown():
83+
light = self.manager.light
84+
x, y = evt.GetPosition()
85+
dx, dy = x-self.lastx, y-self.lasty
86+
self.lastx, self.lasty = x, y
87+
angx, angy = dx/200, dy/200
88+
vx, vy, vz = self.manager.light
89+
ay = math.asin(vz/math.sqrt(vx**2+vy**2+vz**2))-angy
90+
xx = math.cos(angx)*vx - math.sin(angx)*vy
91+
yy = math.sin(angx)*vx + math.cos(angx)*vy
92+
ay = max(min(math.pi/2-1e-4, ay), -math.pi/2+1e-4)
93+
zz, k = math.sin(ay), math.cos(ay)/math.sqrt(vx**2+vy**2)
94+
self.manager.set_light((xx*k, yy*k, zz))
95+
self.Refresh(False)
8296

8397
def save_bitmap(self, path):
8498
context = wx.ClientDC( self )
@@ -142,6 +156,14 @@ def __init__( self, parent, manager=None):
142156
#pan = wx.Panel(self.toolbar, size=(50, 50))
143157
self.btn_color = wx.ColourPickerCtrl( self.toolbar, wx.ID_ANY, wx.Colour( 128, 128, 128 ), wx.DefaultPosition, [(33, 38), (-1, -1)][platform.system() in ['Windows', 'Linux']], wx.CLRP_DEFAULT_STYLE )
144158
tsizer.Add( self.btn_color, 0, wx.ALIGN_CENTER|wx.ALL|(0, wx.EXPAND)[platform.system() in ['Windows', 'Linux']], 0 )
159+
tsizer.Add(wx.StaticLine( self.toolbar, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_VERTICAL), 0, wx.ALL|wx.EXPAND, 2 )
160+
self.cho_light = wx.Choice( self.toolbar, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, ['force light', 'normal light', 'weak light', 'off light'], 0 )
161+
self.cho_light.SetSelection( 1 )
162+
tsizer.Add( self.cho_light, 0, wx.ALIGN_CENTER|wx.ALL, 1 )
163+
self.cho_bg = wx.Choice( self.toolbar, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, ['force scatter', 'normal scatter', 'weak scatter', 'off scatter'], 0 )
164+
self.cho_bg.SetSelection( 1 )
165+
tsizer.Add( self.cho_bg, 0, wx.ALIGN_CENTER|wx.ALL, 1 )
166+
145167
self.toolbar.SetSizer( tsizer )
146168
tsizer.Layout()
147169

@@ -199,6 +221,8 @@ def __init__( self, parent, manager=None):
199221

200222
self.cho_obj.Bind( wx.EVT_CHOICE, self.on_select )
201223
self.cho_mode.Bind( wx.EVT_CHOICE, self.on_mode )
224+
self.cho_light.Bind( wx.EVT_CHOICE, self.on_light )
225+
self.cho_bg.Bind( wx.EVT_CHOICE, self.on_bg )
202226
self.chk_visible.Bind( wx.EVT_CHECKBOX, self.on_visible)
203227
self.sli_blend.Bind( wx.EVT_SCROLL, self.on_blend )
204228
self.col_color.Bind( wx.EVT_COLOURPICKER_CHANGED, self.on_color )
@@ -229,6 +253,16 @@ def on_bgcolor(self, event):
229253
self.canvas.manager.set_background(c)
230254
self.canvas.Refresh(False)
231255

256+
def on_bg(self, event):
257+
scatter = 3 - self.cho_bg.GetSelection()
258+
self.canvas.manager.set_bright_scatter(scatter=scatter/3)
259+
self.canvas.Refresh(False)
260+
261+
def on_light(self, event):
262+
bright = 3 - self.cho_light.GetSelection()
263+
self.canvas.manager.set_bright_scatter(bright=bright/3)
264+
self.canvas.Refresh(False)
265+
232266
def on_save(self, evt):
233267
dic = {'open':wx.FD_OPEN, 'save':wx.FD_SAVE}
234268
filt = 'PNG files (*.png)|*.png'

imagepy/core/myvi/manager.py

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,15 @@ def set_style(self, mode=None, blend=None, color=None, visible=None):
8585
self.vbo.write(self.buf.tobytes())
8686
self.color = color if isinstance(color, tuple) else (0,0,0)
8787

88-
def draw(self, mvp):
88+
def draw(self, mvp, light, bright, scatter):
8989
if not self.visible: return
9090
self.ctx.line_width = self.width
9191
mvp = np.dot(*mvp)
9292
self.prog['Mvp'].write(mvp.astype(np.float32).tobytes())
9393
self.prog['blend'].value = self.blend
94-
94+
self.prog['scatter'].value = scatter
95+
self.prog['light'].value = tuple(light)
96+
self.prog['bright'].value = bright
9597
self.vao.render({'mesh':moderngl.TRIANGLES, 'grid':moderngl.LINES}[self.mode])
9698

9799
class MarkText:
@@ -114,7 +116,7 @@ def set_style(self, mode=None, blend=None, color=None, visible=None):
114116
if not visible is None: self.visible = visible
115117
if not color is None: self.color = color
116118

117-
def draw(self, mvp):
119+
def draw(self, mvp, light, bright, scatter):
118120
if not self.visible: return
119121
self.ctx.line_width = 2
120122
self.prog['mv'].write(mvp[0].astype(np.float32).tobytes())
@@ -129,6 +131,8 @@ def __init__(self):
129131
self.ratio, self.dial = 1.0, 1.0
130132
self.pers, self.center = True, (0,0,0)
131133
self.background = 0.4, 0.4, 0.4
134+
self.light = (1,0,0)
135+
self.bright, self.scatter = 0.66, 0.66
132136
self.objs = {}
133137
self.ctx = None
134138

@@ -151,13 +155,15 @@ def on_ctx(self):
151155
''',
152156
fragment_shader='''
153157
#version 330
154-
uniform vec3 light = vec3(1,1,0.8);
155-
uniform float blend = 0.1;
158+
uniform vec3 light;
159+
uniform float blend;
160+
uniform float scatter;
161+
uniform float bright;
156162
in vec3 f_norm;
157163
in vec3 f_color;
158164
out vec4 color;
159165
void main() {
160-
float d = clamp((dot(light, f_norm)+1)*0.5, 0, 1);
166+
float d = clamp(dot(light, f_norm)*bright+scatter, 0, 1);
161167
color = vec4(f_color*d, blend);
162168
}
163169
'''
@@ -215,7 +221,7 @@ def draw(self):
215221
self.ctx.enable(moderngl.DEPTH_TEST)
216222
#self.ctx.enable(ModernGL.CULL_FACE)
217223
self.ctx.enable(moderngl.BLEND)
218-
for i in self.objs.values(): i.draw(self.mvp)
224+
for i in self.objs.values(): i.draw(self.mvp, self.light, self.bright, self.scatter)
219225

220226
def count_box(self):
221227
minb = np.array([i.box[0] for i in self.objs.values() if not i.box is None]).min(axis=0)
@@ -237,8 +243,13 @@ def set_viewport(self, x, y, width, height):
237243
self.ctx.viewport = (x, y, width, height)
238244
self.ratio = width*1.0/height
239245

240-
def set_background(self, rgb):
241-
self.background = rgb
246+
def set_background(self, rgb): self.background = rgb
247+
248+
def set_light(self, light): self.light = light
249+
250+
def set_bright_scatter(self, bright=None, scatter=None):
251+
if not bright is None: self.bright = bright
252+
if not scatter is None: self.scatter = scatter
242253

243254
def reset(self, fovy=45, angx=0, angy=0):
244255
self.fovy, self.angx, self.angy = fovy, angx, angy

imagepy/menus/Kit3D/Analysis 3D/regionprops3d_plgs.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
import numpy as np
33
from imagepy.core.engine import Simple, Filter
44
from scipy.ndimage import label, generate_binary_structure
5+
from skimage.measure import marching_cubes_lewiner, mesh_surface_area
6+
from skimage.segmentation import find_boundaries
57
from skimage.measure import regionprops
68
from numpy.linalg import norm
79
import pandas as pd
@@ -27,12 +29,13 @@ class RegionCounter(Simple):
2729
note = ['8-bit', '16-bit', 'stack3d']
2830

2931
para = {'con':'8-connect', 'center':True, 'extent':False, 'vol':True,
30-
'ed':False, 'holes':False, 'fa':False, 'cov':False}
32+
'ed':False, 'holes':False, 'fa':False, 'cov':False, 'surf':True}
3133

3234
view = [(list, 'con', ['4-connect', '8-connect'], str, 'conection', 'pix'),
3335
('lab', None, '========= indecate ========='),
3436
(bool, 'center', 'center'),
3537
(bool, 'vol', 'volume'),
38+
(bool, 'surf', 'surface area'),
3639
(bool, 'extent', 'extent'),
3740
(bool, 'ed', 'equivalent diameter'),
3841
(bool, 'cov', 'eigen values')]
@@ -43,6 +46,7 @@ def run(self, ips, imgs, para = None):
4346

4447
titles = ['ID']
4548
if para['center']:titles.extend(['Center-X','Center-Y','Center-Z'])
49+
if para['surf']:titles.append('Surface')
4650
if para['vol']:titles.append('Volume')
4751
if para['extent']:titles.extend(['Min-Z','Min-Y','Min-X','Max-Z','Max-Y','Max-X'])
4852
if para['ed']:titles.extend(['Diameter'])
@@ -60,6 +64,12 @@ def run(self, ips, imgs, para = None):
6064
dt.append([round(i.centroid[1]*k,1) for i in ls])
6165
dt.append([round(i.centroid[0]*k,1) for i in ls])
6266
dt.append([round(i.centroid[2]*k,1) for i in ls])
67+
if para['surf']:
68+
buf[find_boundaries(buf, mode='outer')] = 0
69+
vts, fs, ns, cs = marching_cubes_lewiner(buf, level=0)
70+
lst = [[] for i in range(n+1)]
71+
for i in fs: lst[int(cs[i[0]])].append(i)
72+
dt.append([0 if len(i)==0 else mesh_surface_area(vts, np.array(i))*k**2 for i in lst][1:])
6373
if para['vol']:
6474
dt.append([i.area*k**3 for i in ls])
6575
if para['extent']:

0 commit comments

Comments
 (0)