1 /**********
2 *
3 * This file is part of the TINA Open Source Image Analysis Environment
4 * henceforth known as TINA
5 *
6 * TINA is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation.
9 *
10 * TINA is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with TINA; if not, write to the Free Software Foundation, Inc.,
17 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * ANY users of TINA who require exemption from the existing licence must
20 * negotiate a new licence with Dr. Neil.A.Thacker, the sole agent for
21 * the University of Manchester.
22 *
23 **********
24 *
25 * Program : TINA
26 * File : $Source: visShape_hough1.c $
27 * Date : $Date: 2012/06/21 10:50 $
28 * Version : $Revision: 1.6 $
29 *
30 * Author : Legacy TINA modified NAT/HR
31 *
32 * Notes :
33 * if the view tool is included and used then
34 * the view tool sets a pointer to a refresh
35 * function that is used to tell the user which
36 * tv tool is the current
37 * similarly for the sroi tool
38 *
39 *********
40 */
41
42
43 #if HAVE_CONFIG_H
44 #include <config.h>
45 #endif
46
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <math.h>
50 #include <tina/sys/sysDef.h>
51 #include <tina/sys/sysPro.h>
52 #include <tina/math/mathDef.h>
53 #include <tina/image/imgDef.h>
54 #include <tina/image/imgPro.h>
55 #include <tina/geometry/geomDef.h>
56 #include <tina/geometry/geomPro.h>
57 #include <tina/vision/vis_ShapeDef.h>
58 #include <tina/vision/visShape_hough1.h> /* HR */
59
60 /* Function prototypes from other files */
61
62
63 /* ---------- Functions ---------- */
64
65 float chi_2(double p, float pos, float delta_theta)
66 {
67 float chi_sq;
68
69 chi_sq = (float)pow(((p - pos)/(delta_theta)),2.0);
70
71 return(chi_sq);
72 }
73
74 Imrect *hough1_alloc(double minn, double maxx, double binsize, Vartype vtype)
75 {
76 Imrect *hough1;
77 Imregion roi;
78 Hough_region *hough1_roi;
79
80 /* Define the physical size of the hough space aray. Need to use the 'ceil'
81 function because the hough space may not be exactly divisable by the bin
82 size. */
83
84 roi.lx = 0;
85 roi.ux = (int)ceil((maxx-minn)/binsize);
86 roi.ly = 0;
87 roi.uy = 1; /* The 1D hough data is stored in a 1 bin wide array */
88
89 hough1 = im_alloc(roi.uy, roi.ux, &roi, vtype);
90
91 /* Add the logical hough coords to the props list */
92
93 hough1_roi = ralloc(sizeof(Hough_region));
94
95 if (hough1_roi!=NULL)
96 {
97 hough1_roi->lx = minn;
98 hough1_roi->ly = 0.0;
99 hough1_roi->ux = maxx;
100 hough1_roi->uy = binsize; /* TEMP use of this variable */
101
102 hough1->props = proplist_add(hough1->props, hough1_roi, HOUGH1_ROI_TYPE,
103 rfree);
104 }
105
106 return (hough1);
107
108 }
109
110 /* ---------- */
111
112 Hough1_peak hough1_locate_max_peak(Imrect *hough1, double thres, Vartype vtype)
113 {
114 Hough1_peak peak;
115
116 switch(vtype)
117 {
118 case char_v: peak = hough1_locate_max_peak_char(hough1, thres);
119 break;
120 case float_v: peak = hough1_locate_max_peak_float(hough1, thres);
121 break;
122 default: format("hough1_locate_max_peak: image vtype not supported\n");
123 }
124
125 return(peak);
126 }
127
128 /* ---------- */
129
130 List *hough1_locate_peaks(Imrect *hough1, double thres, Vartype vtype)
131 {
132 List *peaks=NULL;
133
134 switch(vtype)
135 {
136 case char_v: peaks = hough1_locate_peaks_char(hough1, thres);
137 break;
138 case float_v: peaks = hough1_locate_peaks_float(hough1, thres);
139 break;
140 default: format("hough1_locate_peaks: image vtype not supported\n");
141 }
142 return(peaks);
143 }
144
145 /* ---------- */
146
147 void hough1_plot_point_char(double p, Imrect *hough1)
148 {
149 int x;
150 char *im_data;
151 double minn, maxx, binsize;
152 Hough_region *hough1_roi;
153
154
155 /* (1) Transform from logical coords to array indices.
156 (2) Plot the point. */
157
158 /* Extract the logical coords from the props list */
159
160 hough1_roi = prop_get(hough1->props, HOUGH1_ROI_TYPE);
161
162 if (hough1_roi==NULL)
163 {
164 format("Error: hough1_roi not set.\n");
165 return ;
166 }
167
168 minn = hough1_roi->lx;
169 maxx = hough1_roi->ux;
170 binsize = hough1_roi->uy;
171
172 /* The array index can now be determined */
173
174 x = (int)((p-minn)/binsize);
175
176 if ( (x<0) || (x>hough1->region->ux) )
177 {
178 return;
179 }
180
181 /* Access the image data */ /* Assume char_v images */
182
183 im_data = IM_ROW(hough1,0);
184
185 /* Now plot the point */
186
187 im_data[x] = im_data[x]+1;
188
189 }
190
191 /* ----------- */
192
193 Hough1_peak hough1_locate_max_peak_char(Imrect *hough1, double thres)
194 {
195 List *peaks_list=NULL, *peak_ptr=NULL;
196 Hough1_peak *peak=NULL, max_peak;
197
198 max_peak.height = 0.0;
199
200 /* Added to prevent compiler warnings PAB 02/12/2008 */
201
202 max_peak.x = 0.0;
203 max_peak.label = 0;
204 max_peak.type = 0;
205 max_peak.props = NULL;
206
207 peaks_list = hough1_locate_peaks(hough1, thres, hough1->vtype);
208
209 for(peak_ptr=peaks_list;peak_ptr!=NULL;peak_ptr=peak_ptr->next)
210 {
211 peak=peak_ptr->to;
212 if (peak->height>max_peak.height)
213 max_peak=*peak;
214 }
215
216 list_rm(peaks_list, rfree);
217
218 return (max_peak);
219 }
220
221 /* ---------- */
222
223 List *hough1_locate_peaks_char(Imrect *hough1, double thres)
224 {
225 int x0, x1;
226 int i;
227 char *im_data;
228 char pixel_intensity;
229 List *peaks_list=NULL;
230 double minn, maxx;
231 double binsize;
232 Hough1_peak *peak;
233 Hough_region *hough1_roi;
234 int h, j;
235
236 if (hough1==NULL)
237 {
238 format("Error: hough1 not defined.\n");
239 return NULL;
240 }
241
242 /* Extract the physical coords of the hough space */
243
244 x0 = hough1->region->lx;
245 x1 = hough1->region->ux;
246
247 /* Extract the logical coords of the hough space */
248
249 if ((hough1_roi = prop_get(hough1->props, HOUGH1_ROI_TYPE)) == NULL)
250 {
251 format("Error: hough1_roi not defined.\n");
252 return NULL;
253 }
254
255 minn = hough1_roi->lx;
256 maxx = hough1_roi->ux;
257 binsize = hough1_roi->uy; /* TEMP */
258
259 /* if the hough1 is less than 3 bins wide then cannot find peaks */
260
261 if (x1-x0 < 3)
262 {
263 format("Error: hough1 too small to find peaks.\n");
264 return NULL;
265 }
266
267 /* Access the image data */ /* Assume char_v images */
268
269 im_data = IM_ROW(hough1,0);
270
271 /* Pass a 3 bin wide window over the hough1 */
272 for(i=x0;i<x1;i++)
273 {
274 pixel_intensity = im_data[i];
275
276 if ((double)pixel_intensity>=thres)
277 {
278 if (i-1 < x0) h = x1-1; else h = i-1; /* Wrap around */
279 if (i+1 >= x1) j = x0; else j = i+1;
280
281 if ((pixel_intensity>=im_data[h]) &&
282 (pixel_intensity>im_data[j]))
283 {
284 peak = ralloc(sizeof(Hough1_peak));
285 peak->x = ((double)i+0.5)*binsize+minn;
286 peak->height = (double)pixel_intensity;
287 peaks_list = ref_addtostart(peaks_list, peak, HOUGH1_PEAK);
288 }
289 }
290 }/*endfor(i)*/
291
292 return (peaks_list);
293
294 }
295
296 /* ---------- */
297
298 void hough1_plot_log_gauss(Imrect *hough1, double mean, double sigma)
299 {
300 int x, point;
301 float *im_data;
302 double minn, maxx, binsize;
303 Hough_region *hough1_roi;
304 float pos, cons, temp;
305
306 /* (1) Transform from logical coords to array indices.
307 (2) Blur the point with chi_squared
308 (3) Plot the point. */
309
310 /* Extract the logical coords from the props list */
311
312 hough1_roi = prop_get(hough1->props, HOUGH1_ROI_TYPE);
313
314 if (hough1_roi==NULL)
315 {
316 format("Error: hough1_roi not set.\n");
317 return ;
318 }
319
320 minn = hough1_roi->lx;
321 maxx = hough1_roi->ux;
322 binsize = hough1_roi->uy;
323
324 /* The array index can now be determined */
325
326 x = (int)((mean-minn)/binsize);
327
328 if ( (x<-3.0*sigma/binsize) || (x>hough1->region->ux+3.0*sigma/binsize) ) /* fixed NAT */
329 {
330 return;
331 }
332
333 /* Access the image data */ /* Assume float_v images */
334
335 im_data = IM_ROW(hough1,0);
336
337 /* Now blur the point */
338
339 /* The standard deviation of the error ellipse on the line segmentation is one hence ignore*/
340
341 cons = (float)9.0;
342
343 for(point=hough1->region->lx;point<hough1->region->ux;point++)
344 {
345 pos = (float)(((point+0.5)*binsize) + minn); /* =angle at centre of bin numbered point */
346 temp = (float)(cons - chi_2(mean, pos, (float)sigma));
347 if(temp > 0)
348 im_data[point] = im_data[point] + temp;
349 }
350
351 }
352
353 /* ---------- */
354
355 List *hough1_locate_peaks_float(Imrect *hough1, double thres)
356 {
357 int x0, x1;
358 int i;
359 float *im_data;
360 float pixel_intensity;
361 List *peaks_list=NULL;
362 double minn, maxx;
363 double binsize;
364 Hough1_peak *peak;
365 Hough_region *hough1_roi;
366
367 if (hough1==NULL)
368 {
369 format("Error: hough1 not defined.\n");
370 return NULL;
371 }
372
373 /* Extract the physical coords of the hough space */
374
375 x0 = hough1->region->lx;
376 x1 = hough1->region->ux;
377
378 /* Extract the logical coords of the hough space */
379
380 if ((hough1_roi = prop_get(hough1->props, HOUGH1_ROI_TYPE)) == NULL)
381 {
382 format("Error: hough1_roi not defined.\n");
383 return NULL;
384 }
385
386 minn = hough1_roi->lx;
387 maxx = hough1_roi->ux;
388 binsize = hough1_roi->uy; /* TEMP */
389
390 /* if the hough1 is less than 3 bins wide then cannot find peaks */
391
392 if (x1-x0 < 3)
393 {
394 format("Error: hough1 too small to find peaks.\n");
395 return NULL;
396 }
397
398 /* Access the image data */ /* Assume float_v images */
399
400 im_data = IM_ROW(hough1,0);
401
402
403 /* Pass a 3 bin wide window over the hough1 */
404
405 for(i=(x0+1);i<(x1-1);i++)
406 {
407 pixel_intensity = im_data[i];
408 if ((double)pixel_intensity>=thres)
409 if ((pixel_intensity>=im_data[i-1]) &&
410 (pixel_intensity>im_data[i+1]))
411 {
412 peak = ralloc(sizeof(Hough1_peak));
413 peak->x = (((hough1_quad_fit_float(&i, &pixel_intensity, im_data)+i+0.5)*binsize)
414 +minn);
415 peak->height = (double)pixel_intensity;
416 peaks_list = ref_addtostart(peaks_list, peak, HOUGH1_PEAK);
417 }
418 }/*endfor(i)*/
419
420 return (peaks_list);
421
422 }
423
424 /* ---------- */
425
426 double hough1_pw; /* Last peak width made accessible */
427
428 double hough1_quad_fit_float(int *location, float *Y2, float* im_data)
429 {
430 float Y1, Y3, A, B;
431 double x_coord;
432
433 /* Get the values in the hough space at the three points */
434
435 Y1 = im_data[*location+1];
436 Y3 = im_data[*location-1];
437
438 /* Compute the values of the coefficients of the quadratic, ignore C 'cos not used */
439
440 B = (float)(-(Y3 - Y1)/2.0);
441 A = (float)(-((Y3/2.0) - *Y2 + (Y1/2.0)));
442
443 /* Find x_coord at which derivative = 0 */
444
445 x_coord = B/(2.0*A);
446
447 /* TEMP */
448 hough1_pw = sqrt(1/A);
449
450 return(x_coord);
451 }
452
453 /* ---------- */
454
455 Hough1_peak hough1_locate_max_peak_float(Imrect *hough1, double thres)
456 {
457 List *peaks_list=NULL, *peak_ptr=NULL;
458 Hough1_peak *peak=NULL, max_peak;
459
460 max_peak.height = 0.0;
461
462 /* Added to prevent compiler warnings PAB 02/12/2008 */
463
464 max_peak.x = 0.0;
465 max_peak.label = 0;
466 max_peak.type = 0;
467 max_peak.props = NULL;
468
469 peaks_list = hough1_locate_peaks_float(hough1, thres);
470
471 for(peak_ptr=peaks_list;peak_ptr!=NULL;peak_ptr=peak_ptr->next)
472 {
473 peak=peak_ptr->to;
474 if (peak->height>max_peak.height)
475 max_peak=*peak;
476 }
477
478 list_rm(peaks_list, rfree);
479
480 return (max_peak);
481 }
482
483 /* ---------- */
484
485
486
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.