TPCCLIB
Loading...
Searching...
No Matches
ecat_roi.c
Go to the documentation of this file.
1
5/*****************************************************************************/
6#include "libtpcroi.h"
7/*****************************************************************************/
8
9/*****************************************************************************/
11char roierrmsg[128];
12/*****************************************************************************/
13#define SUPPORT_LEGACY
14/*****************************************************************************/
15
16/*****************************************************************************/
20 ROI_list *rl
21) {
22 int r;
23 RoiList *next;
24#ifdef SUPPORT_LEGACY
25 if(rl->roi) {
26 for(r=0; r<rl->nr; r++) {
27 if(rl->roi[r].point_nr>0) {
28 free(rl->roi[r].x);
29 free(rl->roi[r].y);
30 rl->roi[r].point_nr=0;
31 }
32 }
33 }
34 if(rl->_allocNr>0) free(rl->roi);
35 rl->_allocNr=0;
36#endif
37 rl->nr=0;
38 while(rl->rois) {
39 next=rl->rois->next;
40 free(rl->rois);
41 rl->rois=next;
42 }
43}
44/*****************************************************************************/
45
46/*****************************************************************************/
51 ROI_list *rl
52) {
53 rl->roi=(ROI*)NULL;
54 rl->nr=0;
55#ifdef SUPPORT_LEGACY
56 rl->_allocNr=0;
57 rl->rois=NULL;
58#endif
59}
60/*****************************************************************************/
61
62/*****************************************************************************/
66 ROI_list *rl,
68 int ind
69) {
70 RoiList *rois=rl->rois;
71 int pos=0;
72 while(pos<ind) {
73 rois=rois->next;
74 if(!rois) return;
75 pos++;
76 }
77 if(rois->prev) rois->prev->next=rois->next; else rl->rois=rois->next;
78 if(rois->next) rois->next->prev=rois->prev;
79 if(rois->roi->x) free(rois->roi->x);
80 if(rois->roi->y) free(rois->roi->y);
81 free(rois->roi);
82 free(rois);
83 rl->nr--;
84}
85/*****************************************************************************/
86
87/*****************************************************************************/
91 ROI_list *rl,
93 ROI *roi
94) {
95 RoiList *rois=rl->rois;
96 while(rois->roi!=roi) {
97 rois=rois->next;
98 if(!rois) return;
99 }
100 if(rois->prev) rois->prev->next=rois->next; else rl->rois=rois->next;
101 if(rois->next) rois->next->prev=rois->prev;
102 if(rois->roi->x) free(rois->roi->x);
103 if(rois->roi->y) free(rois->roi->y);
104 free(rois->roi);
105 free(rois);
106 rl->nr--;
107}
108/*****************************************************************************/
109
110/*****************************************************************************/
116 const char *fname,
118 ROI_list *rl
119) {
120 RoiList *newroientry;
121 RoiList *roilist=rl->rois;
122 ROI *newroi;
123 int verbose=0;
124
125 if(verbose>0) printf("roi_read(%s, rl)\n", fname);
126 if(fname==NULL || rl==NULL) return(1);
127
128 /* read the lines of the ROI file */
129 STR_TOKEN_LIST lines;
130 str_token_list_init(&lines);
131 if(textfileReadLines(fname, &lines)!=0) {
132 strcpy(roierrmsg, "cannot read file");
133 str_token_list_empty(&lines); return(1);
134 }
135 if(verbose>3)
136 for(int i=0; i<lines.token_nr; i++)
137 printf("%d: %s\n", 1+i, lines.tok[i]);
138
139 /* Prepare for the data */
140 if(roilist) while(roilist->next) roilist=roilist->next;
141 int n=0; // roi number
142
143 int li=0;
144 while(li<lines.token_nr) {
145
146 /* Allocate space for the new ROI and initialize it*/
147 newroi=malloc(sizeof(ROI));
148 memset(newroi, 0, sizeof(ROI));
149 newroi->userdata=NULL;
150
151 /* Find first line that starts with '*' */
152 for(; li<lines.token_nr; li++) if(lines.tok[li][0]=='*') break;
153 if(li==lines.token_nr) break;
154
155 /* Read line contents until roiname */
156 int c=sscanf(lines.tok[li], "*%s %f %f %d %d %d %d %d %d %d %d %d ",
157 newroi->imgfile, &newroi->zoom, &newroi->recon_zoom,
158 &newroi->matnum, &newroi->type, &newroi->status,
159 &newroi->pos_x, &newroi->pos_y, &newroi->w, &newroi->h, &newroi->t,
160 &newroi->roi);
161 if(c!=12) {
162 strcpy(roierrmsg, "invalid format");
163 str_token_list_empty(&lines); return(2);
164 }
165
166 /* read roi name and the rest of the line */
167 char buf[256]="", buf2[256];
168 int ti=13;
169 while(strTokenNCpy(lines.tok[li], " \t", ti, buf2, 256)>0) {
170 if(strlen(buf)>0) strcat(buf, " ");
171 strcat(buf, buf2);
172 ti++;
173 }
174 if(strlen(buf)<3) {
175 strcpy(roierrmsg, "invalid roi name");
176 free(newroi->x); free(newroi->y); free(newroi);
177 str_token_list_empty(&lines); return(3);
178 }
179 char *cptr=strstr(buf, "///"); if(cptr!=NULL) {*cptr=(char)0; cptr+=3;}
180 c=strncpyCleanSpaces(newroi->roiname, buf, 128);
181 if(c==0) sprintf(newroi->roiname, "ROI%d", 1+n);
182 strReplaceChar(newroi->roiname, ' ', '_');
183 /* Read point number, skipping useless value before it */
184 c=sscanf(cptr, "%*d %d \n", &newroi->point_nr);
185 if(c!=1) {
186 strcpy(roierrmsg, "invalid roi point number");
187 free(newroi->x); free(newroi->y); free(newroi);
188 str_token_list_empty(&lines); return(4);
189 }
190
191 /* Trace ROI should contain another line with points */
192 if(newroi->type==ROI_TRACE && newroi->point_nr>0) {
193 li++; //printf(" line='%s'\n", lines.tok[li]);
194 if(strTokenNr(lines.tok[li], " \t") < 2*newroi->point_nr) {
195 strcpy(roierrmsg, "cannot read ROI border definition");
196 free(newroi->x); free(newroi->y); free(newroi);
197 str_token_list_empty(&lines); return(7);
198 }
199 newroi->x=malloc(newroi->point_nr*sizeof(int));
200 newroi->y=malloc(newroi->point_nr*sizeof(int));
201 char xs[16], ys[16];
202 int i;
203 for(i=0; i<newroi->point_nr; i++) {
204 if(strTokenNCpy(lines.tok[li], " \t", 2*i+1, xs, 16)<1) break;
205 if(strTokenNCpy(lines.tok[li], " \t", 2*i+2, ys, 16)<1) break;
206 newroi->x[i]=atoi(xs);
207 newroi->y[i]=atoi(ys);
208 } //printf("i=%d / %d\n", i, newroi->point_nr);
209 if(i < newroi->point_nr) {
210 strcpy(roierrmsg, "cannot read ROI border definition");
211 free(newroi->x); free(newroi->y); free(newroi);
212 str_token_list_empty(&lines); return(9);
213 }
214 }
215 /* Append ROI to list */
216 newroientry=malloc(sizeof(RoiList));
217 newroientry->roi=newroi;
218 newroientry->prev=roilist;
219 newroientry->next=NULL;
220 if(roilist) {
221 roilist->next=newroientry;
222 roilist=newroientry;
223 } else {
224 roilist=newroientry;
225 rl->rois=roilist;
226 }
227 rl->nr++;
228 n++; li++;
229 }
230 str_token_list_empty(&lines);
231
232 if(n==0) {
233 strcpy(roierrmsg, "error in ROI file");
234 return(2);
235 }
236 return(0);
237}
238/*****************************************************************************/
239
240/*****************************************************************************/
246 ROI *roi
247) {
248 roi->point_nr=4;
249 if((roi->x=malloc(roi->point_nr*sizeof(int)))==NULL)
250 return(-1);
251 if((roi->y=malloc(roi->point_nr*sizeof(int)))==NULL) {
252 free(roi->x); return(-1);}
253 roi->x[0]=0; roi->y[0]=0;
254 roi->x[1]=roi->w; roi->y[1]=0;
255 roi->x[2]=roi->w; roi->y[2]=roi->h;
256 roi->x[3]=0; roi->y[3]=roi->h;
257 return(0);
258}
259
260#ifdef SUPPORT_LEGACY
266 ROI *roi
267) {
268 roi->point_nr=5;
269 if((roi->x=malloc(roi->point_nr*sizeof(int)))==NULL)
270 return(-1);
271 if((roi->y=malloc(roi->point_nr*sizeof(int)))==NULL) {
272 free((char*)roi->x); return(-1);}
273 roi->x[0]=0; roi->y[0]=0;
274 roi->x[1]=roi->w; roi->y[1]=0;
275 roi->x[2]=roi->w; roi->y[2]=roi->h;
276 roi->x[3]=0; roi->y[3]=roi->h;
277 roi->x[4]=0; roi->y[4]=0;
278 return(0);
279}
280#endif
281/*****************************************************************************/
282
283/*****************************************************************************/
289 ROI *roi
290) {
291 int points,r;
292 r=roi->w/2;
293 roi->pos_x+=r;
294 roi->pos_y+=roi->w;
295 roi->point_nr=36; // TODO: clever algorithm to decide how many points we need
296 roi->x=malloc(sizeof(int)*roi->point_nr);
297 roi->y=malloc(sizeof(int)*roi->point_nr);
298 for(points=0;points<roi->point_nr;points++) {
299 float rad=(M_PI/180.0)*(360.0*(points/(float)roi->point_nr));
300 roi->x[points]=sin(rad)*r;
301 roi->y[points]=cos(rad)*r-r;
302 }
303 return 0;
304}
305/*****************************************************************************/
306
307/*****************************************************************************/
313 ROI *roi
314) {
315 int points;
316 roi->pos_x+=roi->w/2;
317 roi->pos_y+=roi->h;
318 roi->point_nr=40; // TODO: clever algorithm to decide how many points we need
319 roi->x=malloc(sizeof(int)*roi->point_nr);
320 roi->y=malloc(sizeof(int)*roi->point_nr);
321 for(points=0;points<roi->point_nr;points++) {
322 float rad=(M_PI/180.0)*(360.0*(points/(float)roi->point_nr));
323 roi->x[points]=sin(rad)*(roi->w/2);
324 roi->y[points]=cos(rad)*(roi->h/2)-roi->h/2;
325 }
326 return 0;
327
328}
329/*****************************************************************************/
330
331/*****************************************************************************/
335 ROI *roi
336) {
337 int i;
338
339 printf("imgfile: %s\n", roi->imgfile);
340 printf("zoom: %f\n recon_zoom: %f\n", roi->zoom, roi->recon_zoom);
341#if 0
342 printf("matnum: %d ; plane: %d frame: %d\n",
343 roi->matnum, roi_mplane(roi->matnum), roi_mframe(roi->matnum) );
344#endif
345 printf("type: %d\n status: %d\n", roi->type, roi->status);
346 printf("pos_x=%d pos_y=%d w=%d h=%d t=%d\n",
347 roi->pos_x, roi->pos_y, roi->w, roi->h, roi->t);
348 printf("roi=%d _%s_\n", roi->roi, roi->roiname);
349 printf("points=%d\n", roi->point_nr);
350 if(roi->point_nr>0) {
351 for(i=0; i<roi->point_nr; i++) printf("(%d,%d) ", roi->x[i], roi->y[i]);
352 printf("\n");
353 }
354}
355/*****************************************************************************/
356
357/*****************************************************************************/
359typedef struct {
361 float minY;
363 float maxY;
365 float x;
367 float m;
368} PolygonEdge;
369
371static void fill_traceroi(
373 char **m,
375 int dimx,
377 int dimy,
379 int pos_x,
381 int pos_y,
383 int *roix,
385 int *roiy,
387 int point_nr
388) {
389 PolygonEdge *edges=malloc(sizeof(PolygonEdge)*point_nr);
390 int edge=0;
391 for(int p=0; p<point_nr; p++) {
392 float maxX;
393 int n;
394 if(p==point_nr-1) n=0; else n=p+1;
395 if(roiy[p]>roiy[n]) {
396 edges[edge].minY=roiy[n]+pos_y;
397 edges[edge].x=roix[n]+pos_x;
398 edges[edge].maxY=roiy[p]+pos_y;
399 maxX=roix[p]+pos_x;
400 } else if(roiy[p]<roiy[n]) {
401 edges[edge].minY=roiy[p]+pos_y;
402 edges[edge].x=roix[p]+pos_x;
403 edges[edge].maxY=roiy[n]+pos_y;
404 maxX=roix[n]+pos_x;
405 } else
406 continue;
407 edges[edge].m=(maxX-edges[edge].x)/(edges[edge].maxY-edges[edge].minY);
408 /* printf("edge[%d]: p=%d minY=%g maxY=%g x=%g m=%g\n", edge, p, edges[edge].minY,
409 edges[edge].maxY, edges[edge].x, edges[edge].m); */
410 edge++;
411 }
412 int *px=malloc(sizeof(int)*point_nr);
413 for(int y=0; y<dimy; y++) {
414 //printf("y=%d\n", y);
415 int pc=0;
416 for(int p=0; p<edge; p++) {
417// if(temp_roundf(edges[p].minY)<=y && y<temp_roundf(edges[p].maxY)) {
418// 2018-12-20 by VO
419 if(temp_roundf(edges[p].minY)<=y && y<=temp_roundf(edges[p].maxY)) {
420 px[pc]=temp_roundf(edges[p].x+edges[p].m*(y-temp_roundf(edges[p].minY)));
421 if(px[pc]<0) px[pc]=0;
422 pc++;
423 }
424 }
425 int odd=0;
426 for(int x=0; x<dimx; x++) {
427 //printf(" x=%d odd=%d\n", x, odd);
428 m[x][y]=odd;
429 for(int p=0; p<pc; p++) {
430 if(x==px[p]) {
431 if(pc>1) odd=!odd;
432 m[x][y]=1;
433 }
434 }
435 //printf(" m[%d][%d]=%d\n", x, y, m[x][y]);
436 }
437 }
438 free(px);
439 free(edges);
440}
441
453 ROI *roi,
455 int dimx,
457 int dimy,
459 char **m
460) {
461 /* Check the parameters */
462 if(roi==NULL || dimx<2 || dimy<2 || m==NULL) {
463 strcpy(roierrmsg, "invalid arguments for roi_onoff()");
464 return 1;
465 }
466 /* Prepare */
467 float pos_x=roi->pos_x;
468 float pos_y=roi->pos_y;
469 for(int x=0; x<dimx; x++) for(int y=0; y<dimy; y++) m[x][y]=0;
470
471 /* Fill the matrix */
472 switch(roi->type) {
473 case ROI_TRACE: /* Trace ROI */
474 fill_traceroi(m, dimx, dimy, pos_x, pos_y, roi->x, roi->y, roi->point_nr);
475 break;
476 case ROI_RECTANGULAR: /* Rectangle ROI */
477 for(int x=pos_x; x<pos_x+roi->w; x++)
478 for(int y=pos_y; y<pos_y+roi->h; y++)
479 m[x][y]=1;
480 break;
481 case ROI_CIRCULAR:{ /* Circle ROI */
482 int x1, x2;
483 int y1, y2;
484 int r=roi->w;
485 for(int y=0; y<r; y++) {
486 y1=pos_y-y;
487 y2=pos_y+y;
488 x1=temp_roundf(sqrt(r*r-y*y));
489 x2=pos_x+x1;
490 x1=pos_x-x1;
491 if(x1<0) x1=0;
492 if(x2>dimx) x2=dimx;
493 while(x1<x2) {
494 if(y1>=0 && y1<dimy) m[x1][y1]=1;
495 if(y2>=0 && y2<dimy) m[x1][y2]=1;
496 x1++;
497 }
498 }
499 } break;
500 case ROI_ELLIPSE: { /* Ellipse ROI */
501 int x1, x2, a;
502 int y1, y2, b;
503 a=roi->w;
504 b=roi->h;
505 for(int y=0; y<b; y++) {
506 y1=pos_y-y;
507 y2=pos_y+y;
508 x1=sqrt(1-(y*y)/(float)(b*b))*a;
509 x2=pos_x+x1;
510 x1=pos_x-x1;
511 if(x1<0) x1=0;
512 if(x2>dimx) x2=dimx;
513 while(x1<x2) {
514 if(y1>=0 && y1<dimy) m[x1][y1]=1;
515 if(y2>=0 && y2<dimy) m[x1][y2]=1;
516 x1++;
517 }
518 }
519 } break;
520 default:
521 strcpy(roierrmsg,"invalid roi type");
522 return 2;
523 }
524 return 0;
525}
526/*****************************************************************************/
532 const char *fname,
534 ROI_list *rl
535) {
536 RoiList *rois;
537 FILE *fp;
538
539 /* Check arguments */
540 if(!fname[0] || rl==NULL || rl->nr<1) {
541 strcpy(roierrmsg, "invalid arguments for roiSave()");
542 return 1;
543 }
544
545 /* Create file */
546 if((fp=fopen(fname, "w"))==NULL) {
547 strcpy(roierrmsg, "cannot open file");
548 return 2;
549 }
550 /* Loop and save the ROIs */
551 rois=rl->rois;
552 while(rois) {
553 if(roi_append(fp,rois->roi)) return 3;
554 rois=rois->next;
555 }
556 return 0;
557}
558/*****************************************************************************/
559
560/*****************************************************************************/
566 FILE *fp,
568 ROI *roi
569) {
570 /* Write first line */
571 if(fprintf(fp, "*%s %f %f %d %d %d %d %d %d %d %d %d %s///%d %d\n",
572 roi->imgfile, roi->zoom, roi->recon_zoom,
573 roi->matnum, roi->type, roi->status,
574 roi->pos_x, roi->pos_y, roi->w, roi->h,
575 roi->t, roi->roi, roi->roiname,
576 0, roi->point_nr ) < 10 )
577 {
578 strcpy(roierrmsg, "cannot write data");
579 fclose(fp); return 1;
580 }
581 /* Write second line, if trace ROI */
582 if(roi->type==ROI_TRACE) {
583 int j;
584 for(j=0; j<roi->point_nr; j++)
585 fprintf(fp, "%d %d ", roi->x[j], roi->y[j]);
586 fprintf(fp, "\n");
587 }
588 return 0;
589}
590
591/*****************************************************************************/
597 FILE *fp,
599 ROI_list *rl,
601 int ind
602) {
603 RoiList *rois=rl->rois;
604 int pos=0;
605 while(pos<ind) {
606 rois=rois->next;
607 pos++;
608 }
609 return roi_append(fp,rois->roi);
610}
611/*****************************************************************************/
612
613/*****************************************************************************/
619 int n
620) {
621 int x, x2, q, r, t;
622
623 if(n<2) return n;
624 t=x=n; while(t>>=2) x>>=1; x++;
625 while(1) {
626 q=n/x; r=n%x;
627 if(x<=q) {x2=x+2; if(q<x2 || (q==x2 && r==0)) break;}
628 x=(x+q)>>1;
629 }
630 return x;
631}
632/*****************************************************************************/
633
634/*****************************************************************************/
638 int matnum
639) {
640 Matval matval;
641
642 mat_numdoc(matnum, &matval);
643 return matval.plane;
644}
645/*****************************************************************************/
646
647/*****************************************************************************/
651 int matnum
652) {
653 Matval matval;
654
655 mat_numdoc(matnum, &matval);
656 return matval.frame;
657}
658/*****************************************************************************/
659
660/*****************************************************************************/
void mat_numdoc(int matnum, Matval *matval)
Definition ecat63ml.c:254
int roi_mplane(int matnum)
Definition ecat_roi.c:636
void roi_empty(ROI_list *rl)
Definition ecat_roi.c:18
int roi_append(FILE *fp, ROI *roi)
Definition ecat_roi.c:564
int roi_mframe(int matnum)
Definition ecat_roi.c:649
void roi_delete(ROI_list *rl, ROI *roi)
Definition ecat_roi.c:89
int roi_compute_rect(ROI *roi)
Definition ecat_roi.c:244
int roi_save(const char *fname, ROI_list *rl)
Definition ecat_roi.c:530
void roi_print(ROI *roi)
Definition ecat_roi.c:333
void roi_init(ROI_list *rl)
Definition ecat_roi.c:49
void roi_delete_n(ROI_list *rl, int ind)
Definition ecat_roi.c:64
int roi_read(const char *fname, ROI_list *rl)
Definition ecat_roi.c:114
char roierrmsg[128]
Definition ecat_roi.c:11
int roi_compute_circle(ROI *roi)
Definition ecat_roi.c:287
int roi_compute_ellipse(ROI *roi)
Definition ecat_roi.c:311
int roiComputeRect(ROI *roi)
Definition ecat_roi.c:264
int roi_append_n(FILE *fp, ROI_list *rl, int ind)
Definition ecat_roi.c:595
int jsqrt(int n)
Definition ecat_roi.c:617
int roi_onoff(ROI *roi, int dimx, int dimy, char **m)
Definition ecat_roi.c:451
void str_token_list_empty(STR_TOKEN_LIST *lst)
Definition readfile.c:26
int textfileReadLines(const char *filename, STR_TOKEN_LIST *lst)
Definition readfile.c:136
void strReplaceChar(char *str, char c1, char c2)
Definition strext.c:159
void str_token_list_init(STR_TOKEN_LIST *lst)
Definition readfile.c:13
int strTokenNCpy(const char *str1, const char *str2, int i, char *str3, int count)
Definition strext.c:45
int strncpyCleanSpaces(char *s1, const char *s2, int maxlen)
Definition strext.c:308
int strTokenNr(const char *str1, const char *str2)
Definition strext.c:17
int temp_roundf(float e)
Definition petc99.c:20
Header file for libtpcroi.
#define ROI_CIRCULAR
Definition libtpcroi.h:36
#define ROI_ELLIPSE
Definition libtpcroi.h:38
#define ROI_TRACE
Definition libtpcroi.h:40
#define ROI_RECTANGULAR
Definition libtpcroi.h:34
int frame
int plane
ROI * roi
Definition libtpcroi.h:104
RoiList * rois
Definition libtpcroi.h:96
float zoom
Definition libtpcroi.h:47
int pos_x
Definition libtpcroi.h:57
int t
Definition libtpcroi.h:65
int * x
Definition libtpcroi.h:72
int pos_y
Definition libtpcroi.h:59
int type
Definition libtpcroi.h:53
char roiname[256]
Definition libtpcroi.h:69
int matnum
Definition libtpcroi.h:51
int point_nr
Definition libtpcroi.h:78
int roi
Definition libtpcroi.h:67
int status
Definition libtpcroi.h:55
int h
Definition libtpcroi.h:63
void * userdata
Definition libtpcroi.h:80
float recon_zoom
Definition libtpcroi.h:49
int * y
Definition libtpcroi.h:75
char imgfile[FILENAME_MAX]
Definition libtpcroi.h:45
int w
Definition libtpcroi.h:61
struct _RoiList * prev
Definition libtpcroi.h:90
ROI * roi
Definition libtpcroi.h:86
struct _RoiList * next
Definition libtpcroi.h:88