1+ # -*- coding: utf-8 -*-
2+ """
3+ Created on Wed Oct 19 17:35:09 2016
4+
5+ @author: yxl
6+ """
7+ import wx
8+ from imagepy .core .engine import Tool ,Filter
9+ import numpy as np
10+ from imagepy .core .manager import ColorManager
11+ from imagepy .core .roi import lineroi
12+ from imagepy .core .mark import GeometryMark
13+ from skimage .graph import route_through_array
14+ import scipy .ndimage as ndimg
15+ def route_through (ips , snap ,poins ,para ):
16+ para ['max' ]= True
17+ para ['lcost' ]= 2
18+ img = snap .astype ('float32' )
19+ if para ['max' ]: img *= - 1
20+ np .add (img , para ['lcost' ]- img .min (), casting = 'unsafe' , out = img )
21+ minv , maxv = ips .range
22+ routes = []
23+ for line in poins :
24+ pts = np .array (list (zip (line [:- 1 ], line [1 :])))
25+ for p0 , p1 in pts [:,:,::- 1 ].astype (int ):
26+ indices , weight = route_through_array (img , p0 , p1 )
27+ routes .append (indices )
28+ return routes
29+
30+ class Plugin (Tool ):
31+ title = 'Route Toolk'
32+ note = ['auto_snap' ,'8-bit' , '16-bit' ,'int' , 'float' ,'2int' , 'preview' ]
33+ para = {'fully connected' :True , 'lcost' :0 , 'max' :False , 'geometric' :True , 'type' :'ROI' }
34+ view = [(float , 'lcost' , (0 , 1e5 ), 3 , 'step' , 'cost' ),
35+ (bool , 'max' , 'max cost' ),
36+ (bool , 'fully connected' , 'fully connected' ),
37+ (bool , 'geometric' , 'geometric' ),
38+ (list , 'type' , ['white line' , 'ROI' ], str , 'output' , '' )]
39+ def __init__ (self ):
40+ self .curobj = None
41+ self .doing = 'Nothing'
42+ #初始化线条缓存
43+ # self.helper = AnchorLine()
44+ self .odx ,self .ody = 0 , 0
45+ self .cursor = wx .CURSOR_CROSS
46+ self .buf = []
47+
48+ def mouse_down (self , ips , x , y , btn , ** key ):
49+ # print(key['canvas'].scale)
50+ lim = 5.0 / key ['canvas' ].scale
51+ if btn == 2 :
52+ if key ['ctrl' ]:
53+ if len (self .buf )> 1 :
54+ lines = route_through (ips , ips .img ,[self .buf ],self .para )
55+ rs , cs = np .vstack (lines ).T
56+ minv , maxv = ips .range
57+ if self .para ['type' ]== 'white line' :
58+ # ips.img[:,:] = minv
59+ ips .img [rs ,cs ] = maxv
60+ elif self .para ['type' ]== 'ROI' :
61+ ips .img [:,:] = minv
62+ ips .img [rs ,cs ] = maxv
63+ ndimg .binary_fill_holes (ips .img .copy (), output = ips .img )
64+ ips .img [:,:] *= 255
65+ self .buf = []
66+ self .draw (ips )
67+ return
68+ else :
69+ self .oldp = key ['canvas' ].to_panel_coor (x ,y )
70+ self .do_old = self .doing
71+ self .doing = 'all_move'
72+ return
73+ #左键按下
74+ elif btn == 1 :
75+ if self .doing == 'Nothing' :
76+ if len (self .buf ) == 0 :
77+ self .doing = 'draw'
78+ elif self .doing == 'draw' and self .cursor == wx .CURSOR_HAND :
79+ a = self .in_points (x ,y ,lim )
80+ if a != (- 1 ,- 1 ):
81+ # print('doing to move')
82+ self .doing = 'move'
83+ #记录第几个点被改变
84+ self .p_index = self .buf .index (a )
85+ elif self .doing == 'down' :
86+ #判断是否在点内,如果在,说明在移动
87+ a = self .in_points (x ,y ,lim )
88+ if a != (- 1 ,- 1 ):
89+ self .doing = 'move'
90+ self .p_index = self .buf .index (a )
91+ return
92+ self .buf = []
93+ self .doing = 'Nothing'
94+ self .draw (ips )
95+ return
96+ if self .doing == 'draw' and self .cursor == wx .CURSOR_CROSS :
97+ self .addpoint ((x ,y ))
98+ self .draw (ips )
99+ elif btn == 3 :
100+
101+ if (self .doing == 'draw' or self .doing == 'down' )and key ['ctrl' ]:
102+ a = self .in_points (x ,y ,lim )
103+ if a != (- 1 ,- 1 ):self .delete (self .buf .index (a ))
104+ self .draw (ips )
105+ elif self .doing == 'draw' :
106+ self .addpoint ((x ,y ))
107+ self .addpoint (self .buf [0 ])
108+ self .draw (ips )
109+ self .doing = 'down'
110+
111+ def mouse_up (self , ips , x , y , btn , ** key ):
112+
113+ if self .doing == 'move' and btn == 1 :
114+ self .doing = 'draw'
115+ elif self .doing == 'all_move' and btn == 2 :
116+ self .doing = self .do_old
117+ def mouse_move (self , ips , x , y , btn , ** key ):
118+ if len (self .buf )== 0 :return
119+ lim = 5.0 / key ['canvas' ].scale
120+ #如果鼠标移动的同时没有按下
121+ if btn == 1 :
122+ #如果在鼠标是手的时候左键按下,而且在移动,说明在修改点的位置
123+ if self .doing == 'move' :
124+ self .change (self .p_index ,(x ,y ))
125+ self .draw (ips )
126+ elif btn == None :
127+ #鼠标变成一个十字架
128+ self .cursor = wx .CURSOR_CROSS
129+ a = self .in_points (x ,y ,lim )
130+ if a != (- 1 ,- 1 ):
131+ self .cursor = wx .CURSOR_HAND
132+ if self .doing == 'all_move' :
133+ x ,y = key ['canvas' ].to_panel_coor (x ,y )
134+ key ['canvas' ].move (x - self .oldp [0 ], y - self .oldp [1 ])
135+ self .oldp = x , y
136+ ips .update ()
137+ # print('move')
138+ self .odx , self .ody = x , y
139+ def in_points (self ,x ,y ,range ):
140+ for i in self .buf :
141+ if ((i [0 ]> x - range ) and (i [0 ]< x + range )) and ((i [1 ]> y - range ) and (i [1 ]< y + range )):
142+ #返回找到的位置
143+ return i
144+ #返回没有找到
145+ return (- 1 ,- 1 )
146+ def mouse_wheel (self , ips , x , y , d , ** key ):pass
147+ def pop (self ):
148+ a = self .buf
149+ self .buf = []
150+ return a
151+ def change (self ,location ,val ):
152+ self .buf [location ]= val
153+ def delete (self ,location ):
154+ self .buf .pop (location )
155+ def addpoint (self , p ):
156+ self .buf .append (p )
157+ def draw (self ,ips ):
158+ mark = {'type' :'layers' , 'body' :{}}
159+ layer = {'type' :'layer' , 'body' :[]}
160+ layer ['body' ].append ({'type' :'points' , 'body' :self .buf })
161+ if len (self .buf )> 1 :
162+ lines = route_through (ips , ips .img ,[self .buf ],self .para )
163+ lst = []
164+ for line in lines :lst .append ([(j ,i ) for i ,j in line ])
165+ layer ['body' ].append ({'type' :'lines' , 'body' :lst })
166+ mark ['body' ][0 ] = layer
167+ ips .mark = GeometryMark (mark )
168+ ips .update ()
169+
170+ def mouse_wheel (self , ips , x , y , d , ** key ):
171+ if d > 0 :key ['canvas' ].zoomout (x , y , 'data' )
172+ if d < 0 :key ['canvas' ].zoomin (x , y , 'data' )
173+ ips .update ()
0 commit comments