prepare for working
[Laueye.git] / src / graphical_analysis.py
blob5faca791345c4ac3f72ce42e5c4e81afda5cedc7
1 #coding: utf-8
2 #file name: graphical_analysis_pyqt4.py
3 #Laueye - A program to analyze Laue diffraction diagrams.
4 #Copyright (C) <2008> <Grissiom>
6 #This program is free software: you can redistribute it and/or modify
7 #it under the terms of the GNU General Public License as published by
8 #the Free Software Foundation, either version 3 of the License, or
9 #(at your option) any later version.
11 #This program is distributed in the hope that it will be useful,
12 #but WITHOUT ANY WARRANTY; without even the implied warranty of
13 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 #GNU General Public License for more details.
16 #You should have received a copy of the GNU General Public License
17 #along with this program. If not, see <http://www.gnu.org/licenses/>.
19 import Image
20 import ImageFilter
21 import numpy
23 class circle:
24 '''a circle's data'''
25 def __init__(self):
26 self.edge = []
27 self.x_boundry = []
28 self.y_boundry = []
29 def center(self):
30 '''return the location of the circle, in flaot format'''
31 x = 0
32 y = 0
33 for i in self.edge:
34 x += i[0]
35 y += i[1]
36 return float(x) / len(self.edge), float(y) / len(self.edge)
38 scope = 2
39 '''设置程序扫描的范围'''
41 cl_size_min = 5
42 '''define the min size of a circle, used to swapt put noise.'''
44 cl_size_max = 500
45 '''define the max size of a circle, used to swapt put noise.'''
47 threshold = 7
48 '''define the threshold of the spot'''
50 def figure_out_circles(im_in):
51 '''figure out the circles in it
53 @param im_in the img to analyz
54 @return return a list of circles
55 '''
56 im_in = denoise_img(im_in)
57 gray_table = conv_to_array(im_in)
58 width, height = im_in.size
59 assert gray_table.shape == (height, width)
60 status = []
61 for i in range(height):
62 status.append([])
63 for k in range(width):
64 status[i].append(0)
65 find_edge(gray_table, status, im_in)
66 return _get_circles(status)
68 def denoise_img(im_in):
69 '''return a denoised img
71 @param im_in img in
72 @return im_out img out'''
73 im_out = im_in.filter(ImageFilter.BLUR)
74 im_out = im_out.filter(ImageFilter.BLUR)
75 return im_out
77 def conv_to_array(im_in):
78 '''convert the given img to numpy.narray
80 convert the given img to numpy.narray, each item indicates the gray scale.
81 @param im_in the img to convert
82 @return nar narray that convert from img'''
83 width, height = im_in.size
84 nar = numpy.zeros((height, width), 'l')
85 im_in = im_in.convert('L')
86 pix = im_in.load()
87 for i in range(width):
88 for k in range(height):
89 nar[k, i] = pix[i, k]
90 return nar
92 def find_edge(nar_in, status, im_in):
93 '''determine edge in nar_in.
95 set edge status to 2.
96 @param nar_in the gray scaled matrix
97 @param status the status table to set up'''
98 height, width = nar_in.shape
99 size = 2
100 k = size
101 while k < width - size:
102 i = size
103 while i < height - size:
104 gr1 = numpy.average(nar_in[i - size:i, k - size:k])
105 gr2 = numpy.average(nar_in[i:i + size, k - size:k])
106 gr3 = numpy.average(nar_in[i:i + size, k:k + size])
107 gr4 = numpy.average(nar_in[i - size:i, k:k + size])
108 if max(gr1, gr2, gr3, gr4) - min(gr1, gr2, gr3, gr4) > threshold:
109 status[i][k] = 2
110 im_in.putpixel((k, i), (255, 0, 0))
111 i += size
112 k += size
113 im_in.save('../test/test-pred.png')
116 def _get_boundry(in_list, status):
117 '''get the boundry of the whole circle based on the status table.
119 @param in_list a point on the circle.
120 @param status the status table which is the base to analyze
121 @return edge a list of tuples which are the edge of the circle, in (x, y) format.
123 edge = []
124 while len(in_list) != 0:
125 y, x = in_list.pop()
126 edge.append((y, x))
127 status[y][x] = 4
128 for i in range(-scope, scope + 1):
129 for k in range(-scope, scope + 1):
130 if status[y + i][x + k] == 2:
131 in_list.append([y + i, x + k])
132 return edge
134 def _get_circles(status):
135 '''get the circles in the whole image.
137 @param status the status table which is the base of analyze.
138 @return a list of circles.'''
139 width = len(status)
140 height = len(status[0])
141 #TODO:maybe we need to check whether im_status is a matrices here.
142 # i.e, all the len(im_status[:]) have the same value.
143 circles = []
144 for i in range(scope, width - scope):
145 for k in range(scope, height - scope):
146 if status[k][i] == 2:
147 circles.append(circle())
148 circles[-1].edge = _get_boundry([[k, i]], status)
149 if len(circles[-1].edge) < cl_size_min or len(circles[-1].edge) > cl_size_max:
150 del circles[-1]
151 return circles
153 if __name__ == '__main__':
154 circles = figure_out_circles(Image.open('../test/test_laue.jpg'))
155 # circles = figure_out_circles(Image.open('../test/test.png'))
156 print 'we have', len(circles),'circles'
157 #print 'thay are', [i.center() for i in circles]
158 else:
159 pass
160 pass