/* * bound_comp.c Simon Towers 09-02-87 * * identifies composite/overlap objects */ #include #include #include #include struct curve { int diff; int index; int x; int y; int dir; int chg; char type; char type2; struct curve *next; }; bound_comp(obj, spobj, boundary, hist, hist_diff) struct chromosome *obj; struct object *spobj; struct polygondomain *boundary; struct histogramdomain *hist, *hist_diff; { struct curve *cur1, *cur, *cur2, *curvhist(); int aflag, rflag, lflag, jflag, dist; /* identify concavities */ cur1 = cur = curvhist(boundary, hist, hist_diff); /* check syntax */ aflag = rflag = lflag = jflag = 0; while (cur != NULL) { if (cur->type == 'a') { aflag++; if (rflag==1) lflag=1; } else if (cur->type == 'r' && lflag==0) rflag = 1; else if (cur->type == 'l') lflag = 1; else if ((cur->type=='r' && lflag==1) || cur->type=='j') jflag++; cur = cur->next; } /* check arms */ cur = cur1; while (cur != NULL && aflag > 1) { if (cur->type == 'a') { if ((cur2=cur->next) == NULL) cur2 = cur1; if (cur2->type == 'a') { dist = (cur->x - cur2->x)*(cur->x - cur2->x) + (cur->y - cur2->y)*(cur->y - cur2->y); if (dist < 50) { cur->type2 = 'u'; aflag--; } } } cur = cur->next; } /* make hypothesis */ if (jflag > 0 || aflag > 2) obj->plist->otype = composite(spobj, cur1); while (cur1 != NULL) { cur = cur1; cur1 = cur1->next; Free(cur); } } #define PNTS 100 #define MAXGREY 140 composite(obj, cur1) struct object *obj; struct curve *cur1; { struct object *tmp, *tmp2, *dilation(), *erosion(), *newgrey(); int min_grey, max_grey, a, type; tmp = newgrey(obj); tmp->plist = NULL; greyrange(tmp, &min_grey, &max_grey); setrange(tmp, min_grey, max_grey, min_grey, 255); tmp2 = dilation(tmp); free(tmp); tmp = erosion(tmp2); free(tmp2->idom); free(tmp2); type = 0; while (cur1 != NULL) { if (cur1->type == 'j') { if ((a = cutline(tmp, cur1)) == COMPOSITE) return(COMPOSITE); else if (a == OVERLAP) type = OVERLAP; } cur1 = cur1->next; } freeobj(tmp); if (!type) type = COMPOSITE; return(type); } cutline(obj, start) struct object *obj; struct curve *start; { struct polygondomain *pdom, *makepolydmn(); struct ivertex *vtx; int i, dir, range; pdom = makepolydmn(1, NULL, 0, PNTS, 1); vtx = pdom->vtx; vtx->vtX = start->x; vtx->vtY = start->y; vtx++; if ((dir = start->dir + 90) >= 360) dir -= 360; if ((dir = dir*2 + 45) >= 720) dir -= 720; dir /= 90; /* valley following algorithm */ range = 1; for (i=1 ; i= 10) range = 2; if (next_pt(obj, vtx, dir, range) == 1) { free(pdom); return(OVERLAP); } if (i>6 && bound_pt(obj, vtx) == 1) break; vtx++; } /* check found end point ok */ free(pdom); if (i == PNTS) return(0); else return(COMPOSITE); } next_pt(obj, vtx, dir, range) struct object *obj; struct ivertex *vtx; int dir, range; { int i, val, grey, *greyval(), x, k, l; grey = 500; for (i= -range ; i<=range ; i++) { x = (dir + i + 8) % 8; k = abs((x-4)*2/3) - 1; l = -((x-4) % 4); if (l != 0) l /= abs(l); val = *greyval(obj, (vtx-1)->vtY+l, (vtx-1)->vtX+k); if (val < grey) { grey = val; vtx->vtX = (vtx-1)->vtX + k; vtx->vtY = (vtx-1)->vtY + l; } } if (vtx->vtX==(vtx-2)->vtX && vtx->vtY==(vtx-2)->vtY) { k = abs((dir-4)*2/3) - 1; l = -((dir-4) % 4); if (l != 0) l /= abs(l); vtx->vtX = (vtx-1)->vtX + k; vtx->vtY = (vtx-1)->vtY + l; } if (grey > MAXGREY) return(1); return(0); } bound_pt(obj, vtx) struct object *obj; struct ivertex *vtx; { struct intervaldomain *idom; struct intervalline *intvline; struct interval *intl; int k, l, i, j, inside; idom = obj->idom; k = vtx->vtX; l = vtx->vtY; if (k==idom->kol1 || k==idom->lastkl || l==idom->line1 || l==idom->lastln) return(1); k -= idom->kol1; for (i= -1 ; i<=1 ; i++) { intvline = &idom->intvlines[l - idom->line1 + i]; intl = intvline->intvs; inside = 0; for (j=0 ; jnintvs ; j++) if (k > (intl+j)->ileft && k < (intl+j)->iright) inside++; if (!inside) return(1); } return(0); }