📄 detect_blobs.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.***/#ifndef WIN32#include <string.h>#endif#include "mex.h"#include "image_buffer.h"#include "extract_blobs.h"/*** Function to check wether an argument is** a 2d matrix of given size** -1 as size means any size*/int has_size(const mxArray *arg,int mdims,int *msize){const int *dims;int k,retval; dims = mxGetDimensions(arg); retval=1; if(mxGetNumberOfDimensions(arg) != mdims) retval=0; for(k=0;k<mdims;k++) { if((msize[k] != -1) && (dims[k] != msize[k])) retval=0; } return retval;}/*** Copy dimensions of a buffer struct** to a list of integers.*/void copy_dims(int *out_dims,buffer *bf){ out_dims[0]=bf->rows; out_dims[1]=bf->cols; out_dims[2]=bf->ndim;}/*** mexFunction is the interface function to MATLAB.**** plhs - pointer to left-hand OUTPUT mxArrays** nlhs - number of left-hand OUTPUT arrays** prhs - pointer to right-hand INPUT mxArrays** nrhs - number of right-hand INPUT arrays***/void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){buffer *bf_mvec,*bf_pvec,*bf_im0;ibuffer *bf_csc,*bf_labelim,*bf_ic0; const int *im0_dims;double *argpr;int im0_ndims,pbase;int textfl=1; /* Display usage text if set */buffer **bl_lout;int out_dims[]={0,0,0};int ref_dims[]={1,1,0}; /* Matrix size of a scalar *//* Default parameters for the algorithm */ fpnum dmax=0.16; /* Maximum colour distance */fpnum cmin=0.5; /* Area threshold for pyramid generation */int amin=20; /* Min required area */int lowsc=2; /* Finest scale to detect blobs in 1 or more */int roi=0; /* Side of spatial window (or 0 for 12 pixel roi) */fpnum minc=0.5; /* Merger threshold */int miter=5; /* Number of m-estimation steps *//* Argument count check */ if((nrhs < 2)||(nrhs > 6)) { if(nrhs !=0) mexPrintf("Error: 2-6 input arguments expected.\n"); goto mexErrExit; }/* Parse arg 1 (input image) */ im0_dims = mxGetDimensions(prhs[0]); im0_ndims = mxGetNumberOfDimensions(prhs[0]); if(mxGetClassID(prhs[0]) != mxDOUBLE_CLASS) { mexPrintf("Type mismatch: <im0> should be of class double.\n"); goto mexErrExit; } if((im0_ndims<2)||(im0_ndims>3)) { mexPrintf("Type mismatch: <im0> should be 2D or 3D.\n"); goto mexErrExit; } if(im0_ndims<3) { bf_im0=buffer_new0((double *)mxGetPr(prhs[0]),im0_dims[0],im0_dims[1],1); } else { bf_im0=buffer_new0((double *)mxGetPr(prhs[0]),im0_dims[0],im0_dims[1], im0_dims[2]); }/* Parse arg 2 (certainty mask) */ pbase=1; /* Position of dmax arg */ if(has_size(prhs[1],2,(int *)im0_dims)) { /* First two dims same? */ if(mxGetClassID(prhs[1]) != mxUINT32_CLASS) { mexPrintf("Type mismatch: <ic0> should be of class uint32.\n"); goto mexErrExit2; } if(nrhs<3) { mexPrintf("Error 3-6 input arguments expected.\n"); goto mexErrExit2; } /* Input cert supplied */ bf_ic0=ibuffer_new0((int *)mxGetPr(prhs[1]),im0_dims[0],im0_dims[1],1); pbase=2; } else { /* No certainty image supplied -> create all ones image */ bf_ic0 = ibuffer_new(im0_dims[0],im0_dims[1],1); set_to_ones(bf_ic0); }/* Parse arg 3 (dmax) */ if(pbase<nrhs) { if(!has_size(prhs[pbase],2,ref_dims)) { mexPrintf("Type mismatch: <dmax> should be a double scalar.\n"); goto mexErrExit3; } argpr=mxGetPr(prhs[pbase]);dmax=argpr[0]; }/* Parse arg 3 (cmin) */ if(pbase+1<nrhs) { if(!has_size(prhs[pbase+1],2,ref_dims)) { mexPrintf("Type mismatch: <cmin> should be a double scalar.\n"); goto mexErrExit3; } argpr=mxGetPr(prhs[pbase+1]);cmin=argpr[0]; }/* Parse arg 4 (amin) */ if(pbase+2<nrhs) { if(!has_size(prhs[pbase+2],2,ref_dims)) { mexPrintf("Type mismatch: <amin> should be a double scalar.\n"); goto mexErrExit3; } argpr=mxGetPr(prhs[pbase+2]);amin=argpr[0]; }/* Parse arg 5 (lowsc) */ if(pbase+3<nrhs) { if(!has_size(prhs[pbase+3],2,ref_dims)) { mexPrintf("Type mismatch: <lowsc> should be a double scalar.\n"); goto mexErrExit3; } argpr=mxGetPr(prhs[pbase+3]);lowsc=argpr[0]; } /* Allocate array of result pointers */ bl_lout=(buffer **)calloc(4,sizeof(buffer *)); /* Call the blob extraction function */ extract_blobs(bf_im0,bf_ic0,bl_lout,dmax,cmin,roi,miter,lowsc,minc,amin); /* Extract results */ bf_mvec = bl_lout[0]; bf_pvec = bl_lout[1]; bf_csc = (ibuffer *)bl_lout[2]; bf_labelim = (ibuffer *)bl_lout[3];/* Copy to Matlab memory if there is a left hand */ if(nlhs>0) { /* MVEC array */ copy_dims(out_dims,bf_mvec); plhs[0] = mxCreateNumericArray(2,out_dims,mxDOUBLE_CLASS,mxREAL); memcpy(mxGetPr(plhs[0]),bf_mvec->data,out_dims[0]*out_dims[1]*sizeof(double)); } if(nlhs>1) { /* PVEC array */ copy_dims(out_dims,bf_pvec); plhs[1] = mxCreateNumericArray(2,out_dims,mxDOUBLE_CLASS,mxREAL); memcpy(mxGetPr(plhs[1]),bf_pvec->data,out_dims[0]*out_dims[1]*sizeof(double)); } if(nlhs>2) { /* LIMG array */ copy_dims(out_dims,(buffer *)bf_labelim); plhs[2] = mxCreateNumericArray(2,out_dims,mxUINT32_CLASS,mxREAL); memcpy(mxGetPr(plhs[2]),bf_labelim->data,out_dims[0]*out_dims[1]*sizeof(int)); } free(bl_lout); buffer_free(bf_mvec); buffer_free(bf_pvec); ibuffer_free(bf_csc); ibuffer_free(bf_labelim); textfl=0; /* No usage text */mexErrExit3: if(pbase==2) free(bf_ic0); /* Only release struct */ else ibuffer_free(bf_ic0); /* Release data and struct */mexErrExit2: free(bf_im0); if(!textfl) goto mexExit;/* Exit with error message */mexErrExit: mexPrintf("Usage: [<mvec>,<pvec>[,<Limg>]]=detect_blobs(<im0>,[<ic0>,]<dmax>[,<cmin>[,<amin>[,<lowsc>]])\n");mexExit: {}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -