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

📄 merge_blobs.c

📁 it runs for blob detection with opencv
💻 C
字号:
/***  Source file for blobdetect. (c) 2004 Per-Erik Forssen****  This program is free software; you can redistribute it and/or modify**  it under the terms of the GNU General Public License as published by**  the Free Software Foundation; either version 2 of the License, or**  (at your option) any later version.**  **  See the file COPYING for details.***/#include "merge_blobs.h"#include <stdlib.h>#include <math.h>/*** Blob merging subroutine****  mvec1        Moment vector 1**  mvec2        Moment vector 2**  mvecn        Output moment vector**  pvec1        Property vector 1**  pvec2        Property vector 2**  pvecn        Output property vector**  ndim         Dimensionality of vector field*/void merge_blobs(fpnum *mvec1,fpnum *mvec2,fpnum *mvecn,		 fpnum *pvec1,fpnum *pvec2,fpnum *pvecn,		 int ndim){  int d;  fpnum atot,mx,my,ixx,ixy,iyy;  atot=mvec1[0]+mvec2[0];  mx=(mvec1[1]*mvec1[0]+mvec2[1]*mvec2[0])/atot;  my=(mvec1[2]*mvec1[0]+mvec2[2]*mvec2[0])/atot;  /* Inertia about (0,0) */  ixx =((mvec1[3]+mvec1[1]*mvec1[1])*mvec1[0]+	(mvec2[3]+mvec2[1]*mvec2[1])*mvec2[0])/atot;  ixy =((mvec1[4]+mvec1[1]*mvec1[2])*mvec1[0]+	(mvec2[4]+mvec2[1]*mvec2[2])*mvec2[0])/atot;  iyy =((mvec1[5]+mvec1[2]*mvec1[2])*mvec1[0]+	(mvec2[5]+mvec2[2]*mvec2[2])*mvec2[0])/atot;  /* Inertia about (mx,my) */  ixx=ixx-mx*mx;  ixy=ixy-mx*my;  iyy=iyy-my*my;    /* Store in mvecn,pvecn */  mvecn[0]=atot;  mvecn[1]=mx;  mvecn[2]=my;  mvecn[3]=ixx;  mvecn[4]=ixy;  mvecn[5]=iyy;    for(d=0;d<ndim;d++) {    pvecn[d]=(pvec1[d]*mvec1[0]+pvec2[d]*mvec2[0])/atot;  }}/*** Main bloblist_merge_cnt function**** bf_mvec0    Array of input moment vectors** bf_pvec0    Array of input property vectors** bf_mvecn    Array of output moment vectors** bf_pvecn    Array of output property vectors** bf_out_ind  Array of index pointers** cntl        Overlap count list** minc        Merger threshold**** Returns number of merged regions*/int bloblist_merge_cnt(buffer *bf_mvec0,buffer *bf_pvec0,buffer *bf_mvecn,		       buffer *bf_pvecn,ibuffer *bf_out_ind,ibuffer *bf_cntl,		       fpnum minc){  int k,l,d,cind,m1,m2,mh,ml,mregions;  int ndim,regions;  fpnum amin;  fpnum *mvec0,*pvec0,*mvecn,*pvecn;  fpnum *mvec1,*mvec2,*mvec3,*pvec1,*pvec2,*pvec3;  int *cntl,*out_ind;  mvec0   = bf_mvec0->data;  pvec0   = bf_pvec0->data;  mvecn   = bf_mvecn->data;  pvecn   = bf_pvecn->data;  cntl    = bf_cntl->data;  out_ind = bf_out_ind->data;  ndim    = bf_pvec0->rows;  regions = bf_pvec0->cols;  mvec3=(fpnum *)calloc(6,sizeof(fpnum));  pvec3=(fpnum *)calloc(ndim,sizeof(fpnum));  /* First copy old mvec and pvec, and initialize out_ind */  for(k=0;k<regions;k++) {    for(d=0;d<6;d++) {      mvecn[d+k*6]=mvec0[d+k*6];    }    for(d=0;d<ndim;d++) {      pvecn[d+k*ndim]=pvec0[d+k*ndim];    }    out_ind[k]=k;  }  /* Merging algorithm */  for(k=0;k<regions;k++) {    for(l=k+1;l<regions;l++) {      cind=l*(l-1)/2+k;      /* find smallest area of blob k and l */      amin=mvec0[0+k*6];      if(amin>mvec0[0+l*6]) amin=mvec0[0+l*6];      if((cntl[cind]>minc*sqrt(amin))&&(amin>0)) {	/* Merge blob k and l */	/* Find merger if already merged */	m1=k;while(m1!=out_ind[m1]) m1=out_ind[m1];	m2=l;while(m2!=out_ind[m2]) m2=out_ind[m2];	if(m1!=m2) {	  /* Not already merged */	  mvec1=&mvecn[m1*6];pvec1=&pvecn[m1*ndim];	  mvec2=&mvecn[m2*6];pvec2=&pvecn[m2*ndim];	  merge_blobs(mvec1,mvec2,mvec3,pvec1,pvec2,pvec3,ndim);	  /* Find highest and lowest index */	  mh=m1;if(m2>mh) mh=m2;	  ml=m1;if(m2<ml) ml=m2;	  /* Store result */	  for(d=0;d<6;d++) {	    mvecn[d+ml*6]=mvec3[d];    /* Store here */	    mvecn[d+mh*6]=0;           /* Clear here */	  }	  for(d=0;d<ndim;d++) {	    pvecn[d+ml*ndim]=pvec3[d]; /* Store here */	    pvecn[d+mh*ndim]=0;        /* Clear here */	  }	  /* Point to merged blob */	  out_ind[mh]=ml;	  out_ind[k]=ml;	  out_ind[l]=ml;	}      }    }  }  free(mvec3);  free(pvec3);  mregions=0;  for(k=0;k<regions;k++) {    if(mvecn[0+k*6]>0) mregions++;  }  return(mregions);}/*** Main bloblist_merge_cnt2 function** More costly merge, but better.**** bf_mvec0    Array of input moment vectors** bf_pvec0    Array of input property vectors** bf_mvecn    Array of output moment vectors** bf_pvecn    Array of output property vectors** bf_out_ind  Array of index pointers** cntl        Overlap count list** minc        Merger threshold** dmax2       Squared max property distance**** Returns number of merged regions*/int bloblist_merge_cnt2(buffer *bf_mvec0,buffer *bf_pvec0,buffer *bf_mvecn,			buffer *bf_pvecn,ibuffer *bf_out_ind,ibuffer *bf_cntl,			fpnum minc,fpnum dmax2){  int k,l,d,cind,rind,mh,ml,mregions;  int ndim,regions,min1,min2,mcind,ncnt;  fpnum amin,diff,cdist,mindist;  fpnum *mvec0,*pvec0,*mvecn,*pvecn;  int *cntl,*out_ind;  fpnum *mvec1,*mvec2,*mvec3,*pvec1,*pvec2,*pvec3;  fpnum *dlist;  buffer *bf_dlist;  int *mlist;  ibuffer *bf_mlist;  mvec0   = bf_mvec0->data;  pvec0   = bf_pvec0->data;  mvecn   = bf_mvecn->data;  pvecn   = bf_pvecn->data;  cntl    = bf_cntl->data;  out_ind = bf_out_ind->data;  ndim    = bf_pvec0->rows;  regions = bf_pvec0->cols;  mvec3=(fpnum *)calloc(6,sizeof(fpnum));  pvec3=(fpnum *)calloc(ndim,sizeof(fpnum));  /* First copy old mvec and pvec, and initialize out_ind */  for(k=0;k<regions;k++) {    for(d=0;d<6;d++) {      mvecn[d+k*6]=mvec0[d+k*6];    }    for(d=0;d<ndim;d++) {      pvecn[d+k*ndim]=pvec0[d+k*ndim];    }    out_ind[k]=k;  }  /* Count merging candidates (for allocation) */  ncnt=0;  for(k=0;k<regions*(regions-1)/2;k++)    if(cntl[k]>0) ncnt++;    /* Generate compact relationship list */  bf_mlist=ibuffer_new(2,ncnt,1);  mlist=bf_mlist->data;  /* Generate compact distance list */  bf_dlist=buffer_new(1,ncnt,1);  dlist=bf_dlist->data;  /* Find smallest distance */  mindist=10000;mcind=0;  rind=0;  for(l=1;l<regions;l++) {    for(k=0;k<l;k++) {      cind=l*(l-1)/2+k;      if(cntl[cind]>0) {	/* find smallest area of blob k and l */	amin=mvec0[0+k*6];	if(amin>mvec0[0+l*6]) amin=mvec0[0+l*6];	if((cntl[cind]>minc*sqrt(amin))&&(amin>0)) {	  mlist[0+rind*2]=k;	  mlist[1+rind*2]=l;	  /* Compute property distance */	  cdist=0.0;	  for(d=0;d<ndim;d++) {	    diff=pvecn[d+k*ndim]-pvecn[d+l*ndim];	    cdist+=diff*diff;	  }	  dlist[rind]=cdist;	  if(cdist<mindist) {	    /* Remember smallest distance */	    mindist=cdist;	    mcind=rind;	  }	  rind++;	}      }    }  }/*   mexPrintf("TEST: rind=%d < ncnt=%d ?\n",rind,ncnt); */  ncnt=rind;  /* Actual number of neighbours */  /*   * Merging algorithm:   * Keep merging regions with property distance   * below dmax, starting with most similar.   */  while(mindist<dmax2) {    /* Blobs to merge */    min1=mlist[0+mcind*2];    min2=mlist[1+mcind*2];    mvec1=&mvecn[min1*6];pvec1=&pvecn[min1*ndim];    mvec2=&mvecn[min2*6];pvec2=&pvecn[min2*ndim];          merge_blobs(mvec1,mvec2,mvec3,pvec1,pvec2,pvec3,ndim);    /* Find highest and lowest index */    if(min1>min2) {mh=min1;ml=min2;} else {mh=min2;ml=min1;}        /* Store result */    for(d=0;d<6;d++) {      mvecn[d+ml*6]=mvec3[d];    /* Store here */      mvecn[d+mh*6]=0;           /* Clear here */    }    for(d=0;d<ndim;d++) {      pvecn[d+ml*ndim]=pvec3[d]; /* Store here */      pvecn[d+mh*ndim]=0;        /* Clear here */    }        /* Point to merged blob */    for(k=0;k<regions;k++) {      if(out_ind[k]==mh) out_ind[k]=ml;    }        /* Remove merger candidate */    mlist[0+mcind*2]=-1;    mlist[1+mcind*2]=-1;    dlist[mcind]=2*dmax2; /* Ignore this one from now on */        /* Update mlist and dlist */    for(rind=0;rind<ncnt;rind++) {      k=mlist[0+rind*2];      l=mlist[1+rind*2];      /* Replace occurrences of mh with ml */      if(k==mh) { mlist[0+rind*2]=ml;k=ml;}      if(l==mh) { mlist[1+rind*2]=ml;l=ml;}      if(k==l) {	/* Remove if same */	k=-1;l=-1;	mlist[0+rind*2]=-1;	mlist[1+rind*2]=-1;	dlist[rind]=2*dmax2;      }      if((k==ml)||(l==ml)) {	/* Recompute this distance */	cdist=0.0;	for(d=0;d<ndim;d++) {	  diff=pvecn[d+k*ndim]-pvecn[d+l*ndim];	  cdist+=diff*diff;	}	dlist[rind]=cdist;      }    }    /* Find new smallest distance */    mindist=10000;mcind=0;    for(rind=0;rind<ncnt;rind++) {      if(dlist[rind]<mindist) {	mindist=dlist[rind];	mcind=rind;      }    }  }    free(mvec3);  free(pvec3);  ibuffer_free(bf_mlist);  buffer_free(bf_dlist);  mregions=0;  for(k=0;k<regions;k++) {    if(mvecn[0+k*6]>0) mregions++;  }  return(mregions);}/* *  Require that all blobs have det(I)>0 and mvec(0)>amin *  Mark invalid blobs by setting mvec(0)=0 and out_ind(k)=0 *  and count number of valid blobs. * *  bf_mvec     Moment vectors *  bf_out_ind  Array of index pointers *  amin        Minimum required area * */int bloblist_mark_invalid(buffer *bf_mvec,ibuffer *bf_out_ind,int amin){  int regions,k,validcnt;  fpnum *mvec;  int *out_ind;  mvec    = bf_mvec->data;  regions = bf_mvec->cols;  out_ind = bf_out_ind->data;  validcnt=0;  for(k=0;k<regions;k++) {    if(out_ind[k]==k) {      if((mvec[0+k*6]>amin)&&	 ((mvec[3+k*6]*mvec[5+k*6]-SQR(mvec[4+k*6]))>2e-9)) {	validcnt++;      } else {	mvec[0+k*6]=0; /* Mark as invalid */      }    }  }  return(validcnt);}/* *  Remove holes in bloblists after bloblist_merge_cnt * *  bf_mvecn    Input moment vectors *  bf_pvecn    Input property vectors *  bf_cscn     Input detection scales *  bf_mvecm    Output moment vectors *  bf_pvecm    Output property vectors *  bf_cscm     Output detection scales *  bf_out_ind  Index pointer list * */void  bloblist_compact(buffer *bf_mvecn,buffer *bf_pvecn,ibuffer *bf_cscn,		       buffer *bf_mvecm,buffer *bf_pvecm,ibuffer *bf_cscm,		       ibuffer *bf_out_ind){  fpnum *mvecn,*pvecn;  int *cscn,*cscm,*out_ind;  fpnum *mvecm,*pvecm;  int ndim,regions,mregions,k,d,rind;  cscn     = bf_cscn->data;  mvecn    = bf_mvecn->data;  pvecn    = bf_pvecn->data;  out_ind  = bf_out_ind->data;  mvecm    = bf_mvecm->data;  pvecm    = bf_pvecm->data;  cscm     = bf_cscm->data;  ndim     = bf_pvecn->rows;  regions  = bf_pvecn->cols;  mregions = bf_pvecm->cols;  rind=0;  for(k=0;k<regions;k++) {    /* Eliminate empty blobs and translate to region numbers */    if((out_ind[k]==k)&&(mvecn[0+k*6]==0)) {      out_ind[k]=0;    } else {      out_ind[k]=out_ind[k]+1; /* Translate to blob number (0 means none) */    }    /* Shrink list */    if(mvecn[0+k*6]>0) {      for(d=0;d<6;d++) {	mvecm[d+rind*6]=mvecn[d+k*6];      }      for(d=0;d<ndim;d++) {	pvecm[d+rind*ndim]=pvecn[d+k*ndim];      }      cscm[rind]=cscn[k];      rind++;    }  }}

⌨️ 快捷键说明

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