RobotKomar2.pdf:
[makomar.git] / Detector.m
blobaf263bf62b7eae31bba6e432adebf4745d3f2be5
1 classdef Detector < handle
2     %DETECTOR Modul pro vyhledavani komara v snimcich zachycenych kamerou.
3     
4     properties (Constant)
5         % Brightness Limit - Jasova hranice pro rozpoznani komara
6         BRG_LIM = 180;
7         % Brightness Gnat - Jasova hranice, ktera urci, zda se jedna o
8         % tmavy bod
9         BRG_GNAT = 70;
10     end
11     
12     properties (GetAccess = 'private', SetAccess = 'private')
13         % Komar
14         Gnat;
15         % Detektor
16         Detect;
17         % Snimek
18         Shot;
19         % Zamerny kriz komara
20         Cross;        
21     end
22     
23     methods (Access = private)
24         function initProperties(obj, Shot)
25             obj.Gnat.SIZE = 20; % Velikost komara na snimku v pixelech
26             obj.Gnat.SIZE_MIN = 3; % Minimalni tolerovana velikost komara
27             obj.Gnat.SIZE_MAX = 80; % Maximalni tolerovana velikost komara
28             obj.Gnat.SIZE_TOL = obj.Gnat.SIZE_MAX + 10; % Tolerance velikosti komara
29             
30             obj.Detect.ROW = 4; % Pocet radku snimku, po kolika ma byt detekovan komar
31             obj.Detect.BORDER.Lin = -204;
32             obj.Detect.BORDER.Lout = -284;
33             obj.Detect.BORDER.Rin = 55;
34             obj.Detect.BORDER.Rout = 126;
35             obj.Detect.BORDER.Uin = -121;
36             obj.Detect.BORDER.Uout = -193;
37             obj.Detect.BORDER.Din = 80;
38             obj.Detect.BORDER.Dout = 119;
39             
40             obj.Detect.BORDER.diffLoutLin = obj.Detect.BORDER.Lout - obj.Detect.BORDER.Lin;
41             obj.Detect.BORDER.diffRoutRin = obj.Detect.BORDER.Rout - obj.Detect.BORDER.Rin;
42             obj.Detect.BORDER.diffUoutUin = obj.Detect.BORDER.Uout - obj.Detect.BORDER.Uin;
43             obj.Detect.BORDER.diffDoutDin = obj.Detect.BORDER.Dout - obj.Detect.BORDER.Din;
44             
45             obj.Shot = Shot; % Parametry snimku
46             obj.Shot.HALF_WIDTH = Shot.WIDTH/2;
47             obj.Shot.HALF_HEIGHT = Shot.HEIGHT/2;
48             
49             obj.Cross.SIZE = 20;
50             obj.Cross.HALF_SIZE = round(obj.Cross.SIZE/2);
51             obj.Cross.QUARTER_SIZE = round(obj.Cross.SIZE/4);
52         end
54         % Nalezeni nejtmavsiho bodu v snimku "shot" a vraceni v podobe
55         % souradnic "PointDark". Pokud bude nalezeny bod tmavsi nez
56         % stanovena hranice jasu, tak "PointDark.exist" bude true, v
57         % opacnem pripade bude false.
58         function [PointDark] = detectDark(obj, shot)
59             PointDark.exist = false;
60             PointDark.x = 0;
61             PointDark.y = 0;
62             
63             [mins,idx] = min(shot);
64             [Brightness,PointDark.x] = min(mins);
65             PointDark.y = idx(PointDark.x);
66             
67             if Brightness <= obj.BRG_GNAT
68                 PointDark.exist = true;
69             end
70         end
71         
72         function [PointGnat, Dct] = detectGnat01Sub01(obj, shot, PointGnat, Dct)
73             Dct.GnatHeight = 0;
74             Dct.PointStartY.exist = false;
75             Dct.PointEndY.exist = false;
77             c = Dct.PointStartX.x +...
78                 round((Dct.PointEndX.x - Dct.PointStartX.x)/2);
79             rF = Dct.PointStartX.y - obj.Gnat.SIZE_TOL;
80             if rF < 1
81                 rF = 1;
82             end
83             rI = Dct.PointStartX.y + obj.Gnat.SIZE_TOL;
84             if rI > obj.Shot.HEIGHT
85                 rI = obj.Shot.HEIGHT;
86             end
87             for r = rF:rI
88                 if (shot(r,c) <= obj.BRG_LIM) && (~Dct.PointStartY.exist)
89                     tempR = r - 1;
90                     if tempR >= 1
91                         if (shot(tempR,c) > obj.BRG_LIM)
92                             Dct.PointStartY.exist = true;
93                             Dct.PointStartY.x = c;
94                             Dct.PointStartY.y = r;
95                         end
96                     end
97                 elseif (Dct.PointStartY.exist) &&...
98                         (shot(r,c) > obj.BRG_LIM)
99                     if (Dct.GnatHeight >= obj.Gnat.SIZE_MIN) &&...
100                             (Dct.GnatHeight <= obj.Gnat.SIZE_MAX)
101                         Dct.PointEndY.exist = true;
102                         Dct.PointEndY.x = c;
103                         Dct.PointEndY.y = r;
104                         break;
105                     else
106                         Dct.PointStartY.exist = false;
107                         Dct.GnatHeight = 0;
108                     end
109                 end
110                 if Dct.PointStartY.exist && (~Dct.PointEndY.exist)
111                     Dct.GnatHeight = Dct.GnatHeight + 1;
112                 end
113             end
114             if Dct.PointEndY.exist
115                 PointGnat.exist = true;
116                 PointGnat.x = c;
117                 PointGnat.y = Dct.PointStartY.y +...
118                     round((Dct.PointEndY.y - Dct.PointStartY.y)/2);
119             else
120                 Dct.GnatWidth = 0;
121                 Dct.PointStartX.exist = false;
122                 Dct.PointEndX.exist = false;
123             end
124         end
125         
126         function [PointGnat, Dct] = detectGnat01Sub02(obj, shot, PointGnat, Dct)
127             Dct.GnatWidth = 0;
128             Dct.PointStartX.exist = false;
129             Dct.PointEndX.exist = false;
131             r = Dct.PointStartY.y +...
132                 round((Dct.PointEndY.y - Dct.PointStartY.y)/2);
133             cF = Dct.PointStartY.x - obj.Gnat.SIZE_TOL;
134             if cF < 1
135                 cF = 1;
136             end
137             cI = Dct.PointStartY.x + obj.Gnat.SIZE_TOL;
138             if cI > obj.Shot.WIDTH
139                 cI = obj.Shot.WIDTH;
140             end
141             for c = cF:cI
142                 if (shot(r,c) <= obj.BRG_LIM) && (~Dct.PointStartX.exist)
143                     tempC = c - 1;
144                     if tempC >= 1
145                         if (shot(r,tempC) > obj.BRG_LIM)
146                             Dct.PointStartX.exist = true;
147                             Dct.PointStartX.x = c;
148                             Dct.PointStartX.y = r;
149                         end
150                     end
151                 elseif (Dct.PointStartX.exist) &&...
152                         (shot(r,c) > obj.BRG_LIM)
153                     if (Dct.GnatWidth >= obj.Gnat.SIZE_MIN) &&...
154                             (Dct.GnatWidth <= obj.Gnat.SIZE_MAX)
155                         Dct.PointEndX.exist = true;
156                         Dct.PointEndX.x = c;
157                         Dct.PointEndX.y = r;
158                         break;
159                     else
160                         Dct.PointStartX.exist = false;
161                         Dct.GnatWidth = 0;
162                     end
163                 end
164                 if Dct.PointStartX.exist && (~Dct.PointEndX.exist)
165                     Dct.GnatWidth = Dct.GnatWidth + 1;
166                 end
167             end
168             if Dct.PointEndX.exist
169                 PointGnat.exist = true;
170                 PointGnat.x = Dct.PointStartX.x +...
171                     round((Dct.PointEndX.x - Dct.PointStartX.x)/2);
172                 PointGnat.y = r;
173             else
174                 Dct.GnatHeight = 0;
175                 Dct.PointStartY.exist = false;
176                 Dct.PointEndY.exist = false;
177             end
178         end
179         
180         function [PointGnat] = detectGnat01Sub03(obj, shot, PointGnat)
181             if shot(PointGnat.y,PointGnat.x) > obj.BRG_GNAT
182                 PointGnat.exist = false;
183             end
184         end
185         
186         % Vyhledani komara v snimku "shot" pomoci metody prohledavani po
187         % radcich a sloupcich v blizkosti odhadovaneho bodu
188         % "PointEstimation". Pokud "PointEstimation" neexistuje, pak se
189         % prohledava cely snimek.
190         function [PointGnat] = detectGnat01(obj, shot, varargin)
191             optargin = size(varargin,2);
192             
193             PointGnat.exist = false;
194             PointGnat.x = 0;
195             PointGnat.y = 0;
196             
197             Dct.GnatWidth = 0;
198             Dct.GnatHeight = 0;
199             Dct.PointStartX.exist = false;
200             Dct.PointEndX.exist = false;
201             Dct.PointStartY.exist = false;
202             Dct.PointEndY.exist = false;
203             
204             if optargin == 0
205                 rowFrom = 1;
206                     rowInto = obj.Shot.HEIGHT;
207                     colFrom = 1;
208                     colInto = obj.Shot.WIDTH;
209             elseif optargin == 1
210                 PointEstimation = varargin{1};
211                 
212                 if PointEstimation.exist
213                     rowFrom = PointEstimation.y - obj.Gnat.SIZE_TOL;
214                     if rowFrom < 1
215                         rowFrom = 1;
216                     end
217                     rowInto = PointEstimation.y + obj.Gnat.SIZE_TOL;
218                     if rowInto > obj.Shot.HEIGHT
219                         rowInto = obj.Shot.HEIGHT;
220                     end
221                     colFrom = PointEstimation.x - obj.Gnat.SIZE_TOL;
222                     if colFrom < 1
223                         colFrom = 1;
224                     end
225                     colInto = PointEstimation.x + obj.Gnat.SIZE_TOL;
226                     if colInto > obj.Shot.WIDTH
227                         colInto = obj.Shot.WIDTH;
228                     end
229                 else
230                     return;
231                 end
232             else
233                 fprintf('Detector - neznamy pocet parametru')
234                 return;
235             end
236             
237             for row = rowFrom:obj.Detect.ROW:rowInto
238                 Dct.GnatWidth = 0;
239                 Dct.GnatHeight = 0;
240                 Dct.PointStartX.exist = false;
241                 Dct.PointEndX.exist = false;
242                 Dct.PointStartY.exist = false;
243                 Dct.PointEndY.exist = false;
245                 for col = colFrom:colInto
246                     if (shot(row,col) <= obj.BRG_LIM) && (~Dct.PointStartX.exist)
247                         tempCol = col - 1;
248                         if tempCol >= 1
249                             if (shot(row,tempCol) > obj.BRG_LIM)
250                                 Dct.PointStartX.exist = true;
251                                 Dct.PointStartX.x = col;
252                                 Dct.PointStartX.y = row;
253                                 %fprintf('PSX: %d %d\n',Dct.PointStartX.x,Dct.PointStartX.y)
254                             end
255                         end
256                     elseif (Dct.PointStartX.exist) &&...
257                             (shot(row,col) > obj.BRG_LIM)
258                         
259                         if (Dct.GnatWidth >= obj.Gnat.SIZE_MIN) &&...
260                                 (Dct.GnatWidth <= obj.Gnat.SIZE_MAX)
261                             
262                             Dct.PointEndX.exist = true;
263                             Dct.PointEndX.x = col;
264                             Dct.PointEndX.y = row;
265                             
266                             fprintf('');
267                             
268                             [PointGnat, Dct] = obj.detectGnat01Sub01(shot, PointGnat, Dct);
269                             
270                             if PointGnat.exist
271                                 [PointGnat, Dct] = obj.detectGnat01Sub02(shot, PointGnat, Dct);
272                                 [PointGnat] = detectGnat01Sub03(obj, shot, PointGnat);
273                             end
274                             
275                             if PointGnat.exist
276                                 break;
277                             end
278                         else
279                             Dct.PointStartX.exist = false;
280                             Dct.GnatWidth = 0;
281                         end
282                     end
283                     if Dct.PointStartX.exist && (~Dct.PointEndX.exist)
284                         Dct.GnatWidth = Dct.GnatWidth + 1;
285                     end
286                 end
287                 if PointGnat.exist
288                     break;
289                 end
290             end
291         end
292         
293         function [Border] = detectBorder(obj,x,y)
294             Border.L = 1;
295             Border.R = obj.Shot.WIDTH;
296             Border.U = 1;
297             Border.D = obj.Shot.HEIGHT;
298             
299             if x < obj.Detect.BORDER.Lin
300                 Border.L = (x - obj.Detect.BORDER.Lin)/...
301                     obj.Detect.BORDER.diffLoutLin * obj.Shot.HALF_WIDTH;
302             elseif x > obj.Detect.BORDER.Rin
303                 Border.R = obj.Shot.WIDTH - ((x - obj.Detect.BORDER.Rin)/...
304                     obj.Detect.BORDER.diffRoutRin * obj.Shot.HALF_WIDTH);
305             end
306             
307             if y < obj.Detect.BORDER.Uin
308                 Border.U = (y - obj.Detect.BORDER.Uin)/...
309                     obj.Detect.BORDER.diffUoutUin * obj.Shot.HALF_HEIGHT;
310             elseif y > obj.Detect.BORDER.Din
311                 Border.D = obj.Shot.HEIGHT - ((y - obj.Detect.BORDER.Din)/...
312                     obj.Detect.BORDER.diffDoutDin * obj.Shot.HALF_HEIGHT);
313             end
314         end
315     end
316     
317     methods
318         function obj = Detector()
319             
320         end
321         
322         function initDetector(obj,Shot)
323             obj.initProperties(Shot);
324         end
325         
326         function [PointGnat] = detection(obj, shot)
327             PointGnat.exist = false;
328             PointEstimation = obj.detectDark(shot);
329             if PointEstimation.exist
330                 PointGnat = obj.detectGnat01(shot, PointEstimation);
331                 if ~PointGnat.exist
332                     PointGnat = obj.detectGnat01(shot);
333                 end
334             end
335         end
336         
337         function [PointGnat] = detection1(obj, shot)
338             PointGnat.exist = false;
339             PointEstimation = obj.detectDark(shot);
340             if PointEstimation.exist
341                 PointGnat = obj.detectGnat01(shot);
342             end
343         end
344         
345         function [PointGnat] = detection2(obj, shot)
346             PointGnat.exist = false;
347             PointGnat = obj.detectGnat01(shot);
348         end
349         
350         % Vykresli do vlozeneho snimku "shot" kriz ukazujici na pozici
351         % "Point" a pak vrati tento snimek "shot".
352         function [shot] = paintCross(obj, shot, Point)
353             if ~Point.exist
354                 return;
355             end
356             
357             crs.xFrom = Point.x - obj.Cross.HALF_SIZE;
358             crs.xInto = Point.x + obj.Cross.HALF_SIZE;
359             crs.yFrom = Point.y - obj.Cross.HALF_SIZE;
360             crs.yInto = Point.y + obj.Cross.HALF_SIZE;
361             
362             % Hlavni kriz
363             for x = crs.xFrom:(crs.xFrom+obj.Cross.QUARTER_SIZE)
364                 if (x >= 1) && (x <= obj.Shot.WIDTH)
365                     shot(Point.y,x) = 255;
366                     if (Point.y+1 <= obj.Shot.HEIGHT)
367                         shot(Point.y+1,x) = 0;
368                     end
369                 end
370             end
371             for x = (crs.xInto-obj.Cross.QUARTER_SIZE):crs.xInto
372                 if (x >= 1) && (x <= obj.Shot.WIDTH)
373                     shot(Point.y,x) = 255;
374                     if (Point.y+1 <= obj.Shot.HEIGHT)
375                         shot(Point.y+1,x) = 0;
376                     end
377                 end
378             end
379             for y = crs.yFrom:(crs.yFrom+obj.Cross.QUARTER_SIZE)
380                 if (y >= 1) && (y <= obj.Shot.HEIGHT)
381                     shot(y,Point.x) = 255;
382                     if (Point.x+1 <= obj.Shot.WIDTH)
383                         shot(y,Point.x+1) = 0;
384                     end
385                 end
386             end
387             for y = (crs.yInto-obj.Cross.QUARTER_SIZE):crs.yInto
388                 if (y >= 1) && (y <= obj.Shot.HEIGHT)
389                     shot(y,Point.x) = 255;
390                     if (Point.x+1 <= obj.Shot.WIDTH)
391                         shot(y,Point.x+1) = 0;
392                     end
393                 end
394             end
395             
396             % Okraje krize
397             for x = (crs.xFrom+obj.Cross.QUARTER_SIZE):...
398                     (crs.xInto-obj.Cross.QUARTER_SIZE)
399                 if (x >= 1) && (x <= obj.Shot.WIDTH) && (crs.yFrom >= 1)
400                     shot(crs.yFrom,x) = 255;
401                     shot(crs.yFrom+1,x) = 0;
402                 end
403             end
404             for x = (crs.xFrom+obj.Cross.QUARTER_SIZE):...
405                     (crs.xInto-obj.Cross.QUARTER_SIZE)
406                 if (x >= 1) && (x <= obj.Shot.WIDTH) && (crs.yInto <= obj.Shot.HEIGHT)
407                     shot(crs.yInto,x) = 255;
408                     shot(crs.yInto-1,x) = 0;
409                 end
410             end
411             for y = (crs.yFrom+obj.Cross.QUARTER_SIZE):...
412                     (crs.yInto-obj.Cross.QUARTER_SIZE)
413                 if (y >= 1) && (y <= obj.Shot.HEIGHT) && (crs.xFrom >= 1)
414                     shot(y,crs.xFrom) = 255;
415                     shot(y,crs.xFrom+1) = 0;
416                 end
417             end
418             for y = (crs.yFrom+obj.Cross.QUARTER_SIZE):...
419                     (crs.yInto-obj.Cross.QUARTER_SIZE)
420                 if (y >= 1) && (y <= obj.Shot.HEIGHT) && (crs.xInto <= obj.Shot.WIDTH)
421                     shot(y,crs.xInto) = 255;
422                     shot(y,crs.xInto-1) = 0;
423                 end
424             end
425         end
426         
427         %% Ladici funkce
428         function Border = dB(obj,x,y)
429             Border = obj.detectBorder(x,y);
430         end
431         
432     end