1+ from imagepy import IPy
2+ import numpy as np
3+ from imagepy .core .engine import Simple
4+ from skimage .feature import blob_dog , blob_doh , blob_log
5+ from imagepy .core .mark import GeometryMark
6+ import pandas as pd
7+
8+ class Dog (Simple ):
9+ title = 'Blob Dog'
10+ note = ['all' , 'preview' ]
11+ para = {'min_sigma' :1 , 'max_sigma' :50 , 'sigma_ratio' :1.6 , 'threshold' :0.1 ,
12+ 'overlap' :0.5 , 'exclude_border' :False , 'showid' :True , 'slice' :False }
13+
14+ view = [(int , 'min_sigma' , (1 , 50 ), 0 , 'min' , 'sigma' ),
15+ (int , 'max_sigma' , (1 , 50 ), 0 , 'max' , 'sigma' ),
16+ (float , 'sigma_ratio' , (1.3 , 5 ), 1 , 'ratio' , '1.3~5' ),
17+ (float , 'threshold' , (0.1 , 10 ), 1 , 'threshold' , '0.1~10' ),
18+ (float , 'overlap' , (0 , 10 ), 1 , 'overlap' , '' ),
19+ (bool , 'exclude_border' , 'exclude border' ),
20+ (bool , 'showid' , 'show id on image' ),
21+ (bool , 'slice' , 'slice' )]
22+
23+ def preview (self , ips , para ):
24+ grayimg = ips .img if ips .img .ndim == 2 else ips .img .mean (axis = - 1 )
25+ grayimg /= grayimg .max ()
26+ pts = blob_dog (grayimg , min_sigma = para ['min_sigma' ], max_sigma = para ['max_sigma' ],
27+ sigma_ratio = para ['sigma_ratio' ], threshold = para ['threshold' ],
28+ overlap = para ['overlap' ], exclude_border = para ['exclude_border' ])
29+ pts [:,2 ] *= np .sqrt (2 )
30+ ips .mark = GeometryMark ({'type' :'circles' , 'body' :pts [:,[1 ,0 ,2 ]]})
31+
32+ def cancel (self , ips ): ips .mark = None
33+
34+ def run (self , ips , imgs , para = None ):
35+ if not para ['slice' ]:imgs = [ips .img ]
36+
37+ data , sid , fid , mark = [], [], [], {'type' :'layers' , 'body' :{}}
38+
39+ for i in range (len (imgs )):
40+ grayimg = imgs [i ] if imgs [i ].ndim == 2 else imgs [i ].mean (axis = - 1 )
41+ grayimg /= grayimg .max ()
42+ pts = blob_dog (grayimg , min_sigma = para ['min_sigma' ], max_sigma = para ['max_sigma' ],
43+ sigma_ratio = para ['sigma_ratio' ], threshold = para ['threshold' ],
44+ overlap = para ['overlap' ], exclude_border = para ['exclude_border' ])
45+ pts [:,2 ] *= np .sqrt (2 )
46+ sid .extend ([i ]* len (pts ))
47+ fid .extend (range (1 , len (pts )+ 1 ))
48+ data .append (pts )
49+
50+ layer = {'type' :'layer' , 'body' :[{'type' :'circles' , 'body' :pts [:,[1 ,0 ,2 ]]}]}
51+ if para ['showid' ]:
52+ layer ['body' ].append ({'type' :'texts' , 'body' :[
53+ (x ,y ,'id=%d' % i ) for (x ,y ),i in zip (pts [:,1 ::- 1 ], fid )]})
54+ mark ['body' ][i ] = layer
55+
56+ ips .mark = GeometryMark (mark )
57+ df = pd .DataFrame (np .vstack (data )* ips .unit [0 ], columns = ['X' , 'Y' , 'R' ])
58+ df .insert (0 , 'FID' , fid )
59+ if para ['slice' ]: df .insert (o , 'SliceID' , sid )
60+ IPy .show_table (df , ips .title + '-dogblob' )
61+
62+ class Doh (Simple ):
63+ title = 'Blob Doh'
64+ note = ['all' , 'preview' ]
65+ para = {'min_sigma' :1 , 'max_sigma' :30 , 'num_sigma' :10 , 'threshold' :0.01 ,
66+ 'overlap' :0.5 , 'log_scale' :False , 'showid' :True , 'slice' :False }
67+
68+ view = [(int , 'min_sigma' , (1 , 50 ), 0 , 'min' , 'sigma' ),
69+ (int , 'max_sigma' , (1 , 50 ), 0 , 'max' , 'sigma' ),
70+ (int , 'num_sigma' , (5 , 30 ), 0 , 'num' , 'sigma' ),
71+ (float , 'threshold' , (0.01 , 1 ), 2 , 'threshold' , '0.1~10' ),
72+ (float , 'overlap' , (0 , 10 ), 1 , 'overlap' , '' ),
73+ (bool , 'log_scale' , 'log scale' ),
74+ (bool , 'showid' , 'show id on image' ),
75+ (bool , 'slice' , 'slice' )]
76+
77+ def preview (self , ips , para ):
78+ grayimg = ips .img if ips .img .ndim == 2 else ips .img .mean (axis = - 1 )
79+ grayimg /= grayimg .max ()
80+ pts = blob_doh (grayimg , min_sigma = para ['min_sigma' ], max_sigma = para ['max_sigma' ],
81+ num_sigma = para ['num_sigma' ], threshold = para ['threshold' ],
82+ overlap = para ['overlap' ], log_scale = para ['log_scale' ])
83+ ips .mark = GeometryMark ({'type' :'circles' , 'body' :pts [:,[1 ,0 ,2 ]]})
84+
85+ def cancel (self , ips ): ips .mark = None
86+
87+ def run (self , ips , imgs , para = None ):
88+ if not para ['slice' ]:imgs = [ips .img ]
89+
90+ data , sid , fid , mark = [], [], [], {'type' :'layers' , 'body' :{}}
91+
92+ for i in range (len (imgs )):
93+ grayimg = imgs [i ] if imgs [i ].ndim == 2 else imgs [i ].mean (axis = - 1 )
94+ grayimg /= grayimg .max ()
95+ pts = blob_doh (grayimg , min_sigma = para ['min_sigma' ], max_sigma = para ['max_sigma' ],
96+ num_sigma = para ['num_sigma' ], threshold = para ['threshold' ],
97+ overlap = para ['overlap' ], log_scale = para ['log_scale' ])
98+
99+ sid .extend ([i ]* len (pts ))
100+ fid .extend (range (1 , len (pts )+ 1 ))
101+ data .append (pts )
102+
103+ layer = {'type' :'layer' , 'body' :[{'type' :'circles' , 'body' :pts [:,[1 ,0 ,2 ]]}]}
104+ if para ['showid' ]:
105+ layer ['body' ].append ({'type' :'texts' , 'body' :[
106+ (x ,y ,'id=%d' % i ) for (x ,y ),i in zip (pts [:,1 ::- 1 ], fid )]})
107+ mark ['body' ][i ] = layer
108+
109+ ips .mark = GeometryMark (mark )
110+ df = pd .DataFrame (np .vstack (data )* ips .unit [0 ], columns = ['X' , 'Y' , 'R' ])
111+ df .insert (0 , 'FID' , fid )
112+ if para ['slice' ]: df .insert (o , 'SliceID' , sid )
113+ IPy .show_table (df , ips .title + '-dohblob' )
114+
115+ class Log (Simple ):
116+ title = 'Blob Log'
117+ note = ['all' , 'preview' ]
118+ para = {'min_sigma' :1 , 'max_sigma' :30 , 'num_sigma' :10 , 'threshold' :0.1 , 'overlap' :0.5 ,
119+ 'log_scale' :False , 'showid' :True , 'exclude_border' :False , 'slice' :False }
120+
121+ view = [(int , 'min_sigma' , (1 , 50 ), 0 , 'min' , 'sigma' ),
122+ (int , 'max_sigma' , (1 , 50 ), 0 , 'max' , 'sigma' ),
123+ (int , 'num_sigma' , (5 , 30 ), 0 , 'num' , 'sigma' ),
124+ (float , 'threshold' , (0.01 , 1 ), 2 , 'threshold' , '0.02~1' ),
125+ (float , 'overlap' , (0 , 10 ), 1 , 'overlap' , '' ),
126+ (bool , 'log_scale' , 'log scale' ),
127+ (bool , 'exclude_border' , 'exclude border' ),
128+ (bool , 'showid' , 'show id on image' ),
129+ (bool , 'slice' , 'slice' )]
130+
131+ def preview (self , ips , para ):
132+ grayimg = ips .img if ips .img .ndim == 2 else ips .img .mean (axis = - 1 )
133+ grayimg /= grayimg .max ()
134+ pts = blob_log (grayimg , min_sigma = para ['min_sigma' ], max_sigma = para ['max_sigma' ],
135+ num_sigma = para ['num_sigma' ], threshold = para ['threshold' ],
136+ overlap = para ['overlap' ], log_scale = para ['log_scale' ], exclude_border = para ['exclude_border' ])
137+ pts [:,2 ] *= np .sqrt (2 )
138+ ips .mark = GeometryMark ({'type' :'circles' , 'body' :pts [:,[1 ,0 ,2 ]]})
139+
140+ def cancel (self , ips ): ips .mark = None
141+
142+ def run (self , ips , imgs , para = None ):
143+ if not para ['slice' ]:imgs = [ips .img ]
144+
145+ data , sid , fid , mark = [], [], [], {'type' :'layers' , 'body' :{}}
146+
147+ for i in range (len (imgs )):
148+ grayimg = imgs [i ] if imgs [i ].ndim == 2 else imgs [i ].mean (axis = - 1 )
149+ grayimg /= grayimg .max ()
150+ pts = blob_log (grayimg , min_sigma = para ['min_sigma' ], max_sigma = para ['max_sigma' ],
151+ num_sigma = para ['num_sigma' ], threshold = para ['threshold' ],
152+ overlap = para ['overlap' ], log_scale = para ['log_scale' ], exclude_border = para ['exclude_border' ])
153+ pts [:,2 ] *= np .sqrt (2 )
154+ sid .extend ([i ]* len (pts ))
155+ fid .extend (range (1 , len (pts )+ 1 ))
156+ data .append (pts )
157+
158+ layer = {'type' :'layer' , 'body' :[{'type' :'circles' , 'body' :pts [:,[1 ,0 ,2 ]]}]}
159+ if para ['showid' ]:
160+ layer ['body' ].append ({'type' :'texts' , 'body' :[
161+ (x ,y ,'id=%d' % i ) for (x ,y ),i in zip (pts [:,1 ::- 1 ], fid )]})
162+ mark ['body' ][i ] = layer
163+
164+ ips .mark = GeometryMark (mark )
165+ df = pd .DataFrame (np .vstack (data )* ips .unit [0 ], columns = ['X' , 'Y' , 'R' ])
166+ df .insert (0 , 'FID' , fid )
167+ if para ['slice' ]: df .insert (o , 'SliceID' , sid )
168+ IPy .show_table (df , ips .title + '-dohblob' )
169+
170+ plgs = [Dog , Doh , Log ]
0 commit comments