⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scale-h.c

📁 Hausdorff Distance for Image Recognition
💻 C
📖 第 1 页 / 共 5 页
字号:
     * Destroy model->trans as you go, so that there are never two     * ListNodes which hold the same stransval. This makes cleanup     * in the case of failure (bailout) possible, since otherwise we     * wouldn't be able to tell which bits of model->trans had been read     * out and which hadn't.     */    for (ln = liFirst(model->trans);	 ln != NULLLISTNODE;	 ln = liRemAndNext(ln)) {	t = (stransval *)liGet(ln);	assert(t != (stransval *)NULL);	/* Compute the scale space grid coordinates */	xs = (int)(t->scalex / model->scaleStepX + 0.5);	ys = (int)(t->scaley / model->scaleStepY + 0.5);	assert(xs >= 0);	assert(ys >= 0);	assert(xs <= maxxscale);	assert(ys <= maxyscale);	    	if (imRef(scaleim, xs, ys) == (void *)NULL) {	    /* First one at this scale */	    slist = liNew();	    if (slist == NULLLIST) {		goto bailout;		}	    imRef(scaleim, xs, ys) = (void *)slist;	    }	/* Hook it into the bin */	newln = liAdd((List)imRef(scaleim, xs, ys), (void *)t);	if (newln == NULLLISTNODE) {	    goto bailout;	    }	}    /*     * We don't need model->trans any more - free it.     * Note that we *do not* use free_stranslist, since that would free     * all the stransvals, which we just hooked into scaleim. Actually,     * at this point model->trans should be empty.     */    assert(liLen(model->trans) == 0);    liFree(model->trans);    model->trans = NULLLIST;    /* Now work on the bins in scaleim. */    for (ys = 0; ys <= maxyscale; ys++) {	for (xs = 0; xs <= maxxscale; xs++) {	    if (imRef(scaleim, xs, ys) != (void *)NULL) {		slist = (List)imRef(scaleim, xs, ys);		/* Build the dtrans for scalings of xs, ys */		if (revstyle == REVERSE_BOX) {		    model_dtrans = get_smodel_dtrans(model, xs, ys);		    }		else {		    assert(revstyle == REVERSE_ALLIMAGE);		    /*		     * Put borders of model->image_thresh on the dtrans.		     * This means that if an image pixel's value is below		     * thresh, then we will get its real value; any image		     * pixel outside the model trans would have been over		     * thresh if we'd seen it; we just need to keep track		     * of how many such pixels there are.		     */		    model_dtrans =			get_smodel_dtrans_padded(model, xs, ys,						 (int)ceil(model->image_thresh /						      (double)DSCALE));		    }		if (model_dtrans == (LongImage)NULL) {		    goto bailout;		    }				/* Find out the area we need to scan */		curw = imGetWidth(model_dtrans);		curh = imGetHeight(model_dtrans);		/* Now work on the list */		for (ln = liFirst(slist); ln != NULLLISTNODE; ) {		    t = (stransval *)liGet(ln);		    assert(t != (stransval *)NULL);		    x = t->transpos.x;		    y = t->transpos.y;		    		    /* Scan over the place in the image where this lands */		    nvals = 0;		    if (revstyle == REVERSE_BOX) {			assert(imGetXBase(model_dtrans) == 0);			assert(imGetYBase(model_dtrans) == 0);			/* We know that this lies within borders */			for (y2 = y; y2 < y + curh; y2++) {			    for (x2 = x; x2 < x + curw; x2++) {				if (imRef(image_dtrans, x2, y2) == 0) {				    vals[nvals++] =					imRef(model_dtrans, x2 - x, y2 - y);				    }				}			    }			}		    else {			/* We have to do border checks */			minx = MAX(x + imGetXBase(model_dtrans),				   imGetXBase(image_dtrans));			miny = MAX(y + imGetYBase(model_dtrans),				   imGetYBase(image_dtrans));			maxx = MIN(x + imGetXMax(model_dtrans),				   imGetXMax(image_dtrans));			maxy = MIN(y + imGetYMax(model_dtrans),				   imGetYMax(image_dtrans));						for (y2 = miny; y2 <= maxy; y2++) {			    for (x2 = minx; x2 <= maxx; x2++) {				if (imRef(image_dtrans, x2, y2) == 0) {				    vals[nvals++] =					imRef(model_dtrans, x2 - x, y2 - y);				    }				}			    }			}		    if (revstyle == REVERSE_BOX) {			whichval =			    (int)(ceil(model->image_frac * (nvals - EPSILON)));			pointval = pickNth(vals, nvals, whichval - 1);			}		    else {			/*			 * OK - we have nvals values which have been probed			 * and nimage - nvals which haven't been,			 * but which would be large if they were.			 */			whichval = (int)(ceil(model->image_frac * nimage));			if (whichval > nvals) {			    /* Reject */			    pointval = model->image_thresh * 2 + 1;			    }			else {			    /* Give it a chance */			    pointval = pickNth(vals, nvals, whichval - 1);			    }			}		    if (pointval <= model->image_thresh) {			/* A good point. Keep it. */			t->reverse_val = pointval;			if (revstyle == REVERSE_BOX) {			    if (nvals == 0) {				t->reverse_frac = 1.;				t->reverse_frac2 = 1.;				}			    else {				t->reverse_frac =				    frac_lower(vals, nvals,					       model->image_thresh);				if (pointval == model->image_thresh) {				    t->reverse_frac2 = t->reverse_frac;				    }				else {				    t->reverse_frac2 =					frac_lower(vals, nvals, pointval);				    }				}			    t->reverse_num = nvals;			    }			else {			    if (nvals == 0) {				if (nimage == 0) {				    t->reverse_frac = 1.;				    t->reverse_frac2 = 1.;				    }				else {				    t->reverse_frac = 0.;				    t->reverse_frac2 = 0.;				    }				}			    else {				t->reverse_frac =				    frac_lower(vals, nvals,					       model->image_thresh) * nvals /						   nimage;				if (pointval == model->image_thresh) {				    t->reverse_frac2 = t->reverse_frac;				    }				else {				    t->reverse_frac2 =					frac_lower(vals, nvals,						   pointval) * nvals /						       nimage;				    }				}			    			    t->reverse_num = nimage;			    }			assert(t->reverse_frac >= model->image_frac - EPSILON);						/* and advance */			ln = liNext(ln);			}		    else {			/* Free the hook from slist */			free_strans(t);			ln = liRemAndNext(ln);			}		    		    }		}	    }	}    /*     * The stransvals which remain in scaleim have been validated     * and filled out. Read them out into model->trans.     */    model->trans = liNew();    if (model->trans == NULLLIST) {	goto bailout;	}    for (ys = 0; ys <= maxyscale; ys++) {	for (xs = 0; xs <= maxxscale; xs++) {	    if (imRef(scaleim, xs, ys) != (void *)NULL) {		slist = (List)imRef(scaleim, xs, ys);		liApp(model->trans, slist);		imRef(scaleim, xs, ys) = (void *)NULL;		}	    }	}    imFree(scaleim);    return;  bailout:    /* Don't free model_dtrans - we don't own it */    if (model->trans != NULLLIST) {	free_stranslist(model->trans);	model->trans = NULLLIST;	}    if (scaleim != (PtrImage)NULL) {	for (ys = 0; ys <= maxyscale; ys++) {	    for (xs = 0; xs <= maxxscale; xs++) {		if (imRef(scaleim, xs, ys) != (void *)NULL) {		    slist = (List)imRef(scaleim, xs, ys);		    free_stranslist(slist);		    }		}	    }	imFree(scaleim);	}    return;    }/* * Evaluate the transformation (x,y,xs,ys) for model wrt image, using * the supplied matching parameters and revstyle. * Return TRUE in *result if it checks out, FALSE if not. * Return TRUE on success, FALSE on failure. */static booleancheckOneSTransItoM(simage_info *image, smodel_info *model,		   long reverse_thresh, double reverse_frac, int revstyle,		   int x, int y, int xs, int ys, boolean *result){    int curw, curh;    int minx, maxx;    int miny, maxy;    int nvals;    int nunder;    LongImage image_dtrans;    LongImage model_dtrans;    int x2, y2;    assert(image != (simage_info *)NULL);    assert(model != (smodel_info *)NULL);    assert(image->dtrans != (LongImage)NULL);    assert(result != (boolean *)NULL);    assert(xs >= 0);    assert(ys >= 0);    if (revstyle == REVERSE_NONE) {	/* All succeed */	*result = TRUE;	return(TRUE);	}    /* At the moment, it has to be this */    assert((revstyle == REVERSE_BOX) || (revstyle == REVERSE_ALLIMAGE));    /* Cache stuff */    image_dtrans = image->dtrans;    /* Get the model dtrans */    if (revstyle == REVERSE_BOX) {	model_dtrans = get_smodel_dtrans(model, xs, ys);	}    else {	model_dtrans = get_smodel_dtrans_padded(model, xs, ys,						(int)ceil(reverse_thresh /							  (double)DSCALE));	}    if (model_dtrans == (LongImage)NULL) {	goto bailout;	}    curw = imGetWidth(model_dtrans);    curh = imGetHeight(model_dtrans);    /* Scan over the place in the image where this lands */    nvals = nunder = 0;    if (revstyle == REVERSE_BOX) {	/* We know that this lies within borders */	for (y2 = y; y2 < y + curh; y2++) {	    for (x2 = x; x2 < x + curw; x2++) {		if (imRef(image_dtrans, x2, y2) == 0) {		    nvals++;		    if (imRef(model_dtrans, x2 - x, y2 - y) <= reverse_thresh) {			nunder++;			}		    }		}	    }	}    else {	/* We have to do border checks */	minx = MAX(x + imGetXBase(model_dtrans),		   imGetXBase(image_dtrans));	miny = MAX(y + imGetYBase(model_dtrans),		   imGetYBase(image_dtrans));	maxx = MIN(x + imGetXMax(model_dtrans),		   imGetXMax(image_dtrans));	maxy = MIN(y + imGetYMax(model_dtrans),		   imGetYMax(image_dtrans));		for (y2 = miny; y2 <= maxy; y2++) {	    for (x2 = minx; x2 <= maxx; x2++) {		if (imRef(image_dtrans, x2, y2) == 0) {		    if (imRef(model_dtrans, x2 - x, y2 - y) <= reverse_thresh) {			nunder++;			}		    }		}	    }	nvals = image->npts;	}    if (nunder >= nvals * reverse_frac) {	*result = TRUE;	}    else {	*result = FALSE;	}    return(TRUE);  bailout:    /* Don't free model_dtrans - we don't own it */    return(FALSE);    }/* Do the forwstyle == FORWARD_ONE matching */static voidfindSTransOne(simage_info *image, smodel_info *model, int revstyle){    BFS(image, model, revstyle, findOneCompare, findOneMatch);    /* We only wanted one match, and it's been thoroughly checked out. */    }static voidfindSTransBestDist(simage_info *image, smodel_info *model, int revstyle){    ListNode ln;    stransval *t;    assert(model != (smodel_info *)NULL);    assert(image != (simage_info *)NULL);    /* Set the model distance to a known large value, if it is < 0 */    if (model->model_thresh < 0) {	model->model_thresh =	    DSCALE * (image->xsize + image->ysize +		      image->leftborder + image->topborder +		      image->rightborder + image->bottomborder);	}    /* Otherwise, it's set to a good starting value */    BFS(image, model, revstyle, findDistCompare, findDistMatch);    if (model->trans == NULLLIST) {	/* Failed */	return;	}    /*     * model->trans now has a bunch of matches, some of which may not     * meet the specs, due to the search method: whenever we find a match     * which is better than the previous best, we throw it on to model->trans,     * and rely on this cleanup phase to remove the previous best.     *     * Also, the forward_frac values won't be right: they will be based on     * whatever the threshold was set to when this match was generated; it     * may have decreased since then. However, the frac2 will be exactly     * what we want; they'll all be based on the right model_thresh, since     * all the matches we want to keep have the same forward_val.     */    for (ln = liFirst(model->trans); ln != NULLLISTNODE; ) {	t = (stransval *)liGet(ln);	assert(t != (stransval *)NULL);	assert(t->forward_val >= model->model_thresh);	if (t->forward_val > model->model_thresh) {	    /* This one didn't work */	    free_strans(t);	    ln = liRemAndNext(ln);	    }	else {	    /* t->forward_frac may be out of date - clobber it */	    t->forward_frac = t->forward_frac2;	    ln = liNext(ln);	    }	}    }static voidfindSTransBestFrac(simage_info *image, smodel_info *model, int revstyle){    ListNode ln;    stransval *t;    assert(model != (smodel_info *)NULL);    assert(image != (simage_info *)NULL);    /* Set the model fraction to a known small value, if it is < 0 */    if (model->model_frac < 0) {	model->model_frac = 0.;	}    /* Otherwise, it's set to a good starting value */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -