亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來(lái)到蟲(chóng)蟲(chóng)下載站! | ?? 資源下載 ?? 資源專(zhuān)輯 ?? 關(guān)于我們
? 蟲(chóng)蟲(chóng)下載站

?? skeleton.cpp

?? 獲取對(duì)象骨架的方法
?? CPP
字號(hào):
//***************************************************************************
//
// Matlab C routine file:  skelgrad.cpp
//
// Written 8/04 by N. Howe
//
// Input:
//   img:  binary silhouette image
//
// Output:
//   skg:  skeleton gradient transform
//   skr:  skeleton radius
//
//***************************************************************************

#include "mex.h"

//***************************************************************************

#define SQR(x) (x)*(x)
#define MIN(x,y) (((x) < (y)) ? (x):(y))
#define MAX(x,y) (((x) > (y)) ? (x):(y))
#define ABS(x) (((x) < 0) ? (-(x)):(x))
#define errCheck(a,b) if (!(a)) mexErrMsgTxt((b));
#define cutBounds(i) (((i)>0) ? (((i)<ncut) ? cut[(i)]:mxGetInf()):-mxGetInf())
#define MOD(x,n) (((x)%(n)<0) ? ((x)%(n)+(n)):((x)%(n)))

//***************************************************************************

enum direction {North, South, East, West, None};

const direction dircode[16] = {
  None, West, North, West, East, None, North, West,
  South, South, None, South, East, East, North, None
};

//************************************************************
//
//  quicksort() recursively calls itself to sort the array.
//  It splits the array around a randomly chosen pivot,
//  and calls itself on each piece.
//
//  R/W arr:  The array to sort.
//  R/O n:    The length of the array to sort.
//

void quicksort(int *arr, int n) {

  if (n > 8) {
    int pivot;
    int pivid;
    int lo = 1;    // everything to the left of lo is smaller than pivot
    int hi = n-1;  // everything to the right of hi is larger than the pivot
    int tmp;

    pivid = rand()%n;
    mxAssert((pivid >= 0),"Randomness too small");
    mxAssert((pivid < n),"Randomness too big");
    tmp = arr[0];
    arr[0] = arr[pivid];
    arr[pivid] = tmp;
    pivot = arr[0];  // store value for convenience
    while (hi != lo-1) {  // keep going until everything has been categorized.
      if (arr[lo] < pivot) {
        // smaller than pivot, so stays here
        lo++;
      } else {
        // larger than pivot, so moves to the other end
        tmp = arr[hi];
        arr[hi] = arr[lo];
        arr[lo] = tmp;
        hi--;
      }
    }
    tmp = arr[hi];
    arr[hi] = arr[0];
    arr[0] = tmp;
    quicksort(arr,hi);          // sort smaller side of array
    quicksort(arr+lo,n-lo);  // sort bigger side of array
  } else {
    // use insertion sort
    int i, j;
    int tmp;

    for (i = 0; i < n; i++) {
      for (j = i; (j > 0)&&(arr[j] < arr[j-1]); j--) {
        tmp = arr[j];
        arr[j] = arr[j-1];
        arr[j-1] = tmp;
      }
    }
  }
}
// end of quicksort()

//****************************************************************************
//
// joint_neighborhood() returns a byte value representing the immediate 
// neighborhood of the specified joint in bit form, clockwise from NW.
//
// R/O arr:  binary pixel array
// R/O i,j:  coordinates of point
// R/O nrow, ncol:  dimensions of binary image
// Returns:  bit representation of 8-neighbors
//

template <class T>
inline int joint_neighborhood(T *arr, int i, int j, int nrow, int ncol) {
  int p = i+j*nrow;
  int condition = 8*(i <= 0)+4*(j <= 0)+2*(i >= nrow)+(j >= ncol);

  switch (condition) {
  case 0:  // all points valid
    return (arr[p-nrow-1]?1:0)+(arr[p-1]?2:0)+(arr[p]?4:0)+(arr[p-nrow]?8:0);
  case 1:  // right side not valid
    return (arr[p-nrow-1]?1:0)+(arr[p-nrow]?8:0);
  case 2:  // bottom not valid
    return (arr[p-nrow-1]?1:0)+(arr[p-1]?2:0);
  case 3:  // bottom and right not valid
    return (arr[p-nrow-1]?1:0);
  case 4:  // left side not valid
    return (arr[p-1]?2:0)+(arr[p]?4:0);
  case 5:  // left and right sides not valid
    return 0;
  case 6:  // left and bottom sides not valid
    return (arr[p-1]?2:0);
  case 7:  // left, bottom, and right sides not valid
    return 0;
  case 8:  // top side not valid
    return (arr[p]?4:0)+(arr[p-nrow]?8:0);
  case 9:  // top and right not valid
    return (arr[p-nrow]?8:0);
  case 10:  // top and bottom not valid
  case 11:  // top, bottom and right not valid
    return 0;
  case 12:  // top and left not valid
    return (arr[p]?4:0);
  case 13:  // top, left and right sides not valid
  case 14:  // top, left and bottom sides not valid
  case 15:  // no sides valid
    return 0;
  default:
    mexErrMsgTxt("Impossible condition.\n");
    return -1;
  }
}

//***************************************************************************
//
// compute_skeleton_gradient() does the main computation.
// Written as a template to support multiple image types.
//
// R/O img:  the image
// R/O nrow, ncol:  image dimensions
// R/O nlhs:  number of arguments to return
// W/O plhs:  array of return arguments (0 = gradient, 1 = radius)
// 

template <class T> void
compute_skeleton_gradient(T *img, int nrow, int ncol, int nlhs, 
			  mxArray **plhs) {
  int i, j, ei, ej, inear;
  int ijunc, iedge, iseq, lastdir, mind, minjunc, pspan;
  int jnrow = nrow+1, jncol = ncol+1;
  int njunc, jhood, nedge, nnear;
  int mindNE, mindNW, mindSE, mindSW;
  int *jx, *jy, *edgej, *seqj, *edgelen;
  int *dNE, *dNW, *dSE, *dSW, *nearj;
  bool *seenj;
  double *skg, *rad;

  // count junctions
  njunc = 0;
  for (j = 0; j < jncol; j++) {
    for (i = 0; i < jnrow; i++) {
      jhood = joint_neighborhood(img,i,j,nrow,ncol);
      if ((jhood != 0)&&(jhood != 15)) {
	njunc++;
      }
    }
  }
  //mexPrintf("Counted %d junctions.\n",njunc);
 
  // allocate scratch space
  jx = (int*)mxMalloc(njunc*sizeof(int));
  jy = (int*)mxMalloc(njunc*sizeof(int));
  seqj = (int*)mxMalloc(njunc*sizeof(int));
  edgej = (int*)mxMalloc(njunc*sizeof(int));
  seenj = (bool*)mxMalloc(jnrow*jncol*sizeof(bool));
  dNE = (int*)mxMalloc(njunc*sizeof(int));
  dNW = (int*)mxMalloc(njunc*sizeof(int));
  dSE = (int*)mxMalloc(njunc*sizeof(int));
  dSW = (int*)mxMalloc(njunc*sizeof(int));
  nearj = (int*)mxMalloc(njunc*sizeof(int));
  for (i = 0; i < jnrow*jncol; i++) {
    seenj[i] = false;
  }
  //mexPrintf("Space allocated\n");

  // register junctions
  ijunc = 0;
  nedge = 0;
  for (j = 0; j < jncol; j++) {
    for (i = 0; i < jnrow; i++) {
      jhood = joint_neighborhood(img,i,j,nrow,ncol);
      //mexPrintf("(%d,%d) neighborhood:  %d.\n",i,j,jhood);
      mxAssert(i+j*jnrow>=0&&i+j*jnrow<jnrow*jncol,"Out of bounds.");
      if ((jhood != 0)&&(jhood != 15)&&(jhood != 5)&&(jhood != 10)
	  &&!seenj[i+j*jnrow]) {
	// found new edge; traverse it
	iseq = 0;
	ei = i;
	ej = j;
	lastdir = North;
	//mexPrintf("Beginning traverse.\n");
	while (!seenj[ei+ej*jnrow]||(jhood==5)||(jhood==10)) {
	  //mexPrintf("Traversing at (%d,%d).\n",ei,ej);

	  if (!seenj[ei+ej*jnrow]) {
	    // register this junction
	    mxAssert((ijunc>=0)&&(ijunc<njunc),"Junction index error.");
	    jx[ijunc] = ej;
	    jy[ijunc] = ei;
	    edgej[ijunc] = nedge;
	    seqj[ijunc] = iseq;
	    iseq++;
	    ijunc++;
	    seenj[ei+ej*jnrow] = true;
	  }

	  // traverse clockwise
	  switch (dircode[jhood]) {
	  case North:
	    ei--;
	    lastdir = North;
	    break;
	  case South:
	    ei++;
	    lastdir = South;
	    break;
	  case East:
	    ej++;
	    lastdir = East;
	    break;
	  case West:
	    ej--;
	    lastdir = West;
	    break;
	  case None:
	    switch (lastdir) {
	    case East:  // go North
	      ei--;
	      lastdir = North;
	      break;
	    case West:  // go South
	      ei++;
	      lastdir = South;
	      break;
	    case South:  // go East
	      ej++;
	      lastdir = East;
	      break;
	    case North:  // go West
	      ej--;
	      lastdir = West;
	      break;
	    }
	    break;
	  }
	  mxAssert((ei>=0)&&(ej>=0)&&(ei<jnrow)&&(ej<jncol),"Traversed out.");
	  jhood = joint_neighborhood(img,ei,ej,nrow,ncol);
	  //mexPrintf("Traversal direction:  %d; new neighborhood:  %d.\n",
	  //    lastdir,jhood);
	}
	nedge++;
	}
    }
  }
  mxAssert(njunc == ijunc,"Junction miscount.");
  //mexPrintf("Junctions counted.\n");

  // count perimeter along each edge
  edgelen = (int*)mxMalloc(nedge*sizeof(int));
  for (iedge = 0; iedge < nedge; iedge++) {
    edgelen[iedge] = 0;
  }
  for (ijunc = 0; ijunc < njunc; ijunc++) {
    edgelen[edgej[ijunc]]++;
  }

  // create output
  plhs[0] = mxCreateNumericMatrix(nrow,ncol,mxDOUBLE_CLASS,mxREAL);
  skg = mxGetPr(plhs[0]);
  if (nlhs > 1) {
    plhs[1] = mxCreateNumericMatrix(nrow,ncol,mxDOUBLE_CLASS,mxREAL);
    rad = mxGetPr(plhs[1]);
  }
  for (j = 0; j < ncol; j++) {
    for (i = 0; i < nrow; i++) {
      if (img[i+j*nrow]) {
	// compute distance to all junction points
	// keeping track of minimum
	mind = mindNE = mindNW = mindSE = mindSW = SQR(jnrow+jncol);
	minjunc = -1;
	for (ijunc = 0; ijunc < njunc; ijunc++) {
	  dNE[ijunc] = SQR(i-jy[ijunc])+SQR(j-jx[ijunc]);
	  dNW[ijunc] = SQR(i-jy[ijunc])+SQR(j+1-jx[ijunc]);
	  dSE[ijunc] = SQR(i+1-jy[ijunc])+SQR(j-jx[ijunc]);
	  dSW[ijunc] = SQR(i+1-jy[ijunc])+SQR(j+1-jx[ijunc]);
	  if (dNE[ijunc] < mindNE) {
	    mindNE = dNE[ijunc];
	    if (dNE[ijunc] < mind) {
	      mind = dNE[ijunc];
	      minjunc = ijunc;
	    }
	  }
	  if (dNW[ijunc] < mindNW) {
	    mindNW = dNW[ijunc];
	    if (dNW[ijunc] < mind) {
	      mind = dNW[ijunc];
	      minjunc = ijunc;
	    }
	  }
	  if (dSE[ijunc] < mindSE) {
	    mindSE = dSE[ijunc];
	    if (dSE[ijunc] < mind) {
	      mind = dSE[ijunc];
	      minjunc = ijunc;
	    }
	  }
	  if (dSW[ijunc] < mindSW) {
	    mindSW = dSW[ijunc];
	    if (dSW[ijunc] < mind) {
	      mind = dSW[ijunc];
	      minjunc = ijunc;
	    }
	  }
	}
	//mexPrintf("Point (%d,%d):  junction %d.\n",i,j,minjunc);
	mxAssert((minjunc >=0)&&(minjunc<njunc),"Bad minimum junction.");
	mxAssert((edgej[minjunc] >=0)&&(edgej[minjunc]<nedge),
		 "Bad minimum junction edge.");

	// store radius if desired
	if (nlhs > 1) {
	  rad[i+j*nrow] = mind;
	}

	// find all other junction points at minimal distance
	nnear = pspan = 0;
	for (ijunc = 0; ijunc < njunc; ijunc++) {
	  if ((dNE[ijunc] <= MIN(mindNE,dNE[minjunc]))
	      ||(dNW[ijunc] <= MIN(mindNW,dNW[minjunc]))
	      ||(dSE[ijunc] <= MIN(mindSE,dSE[minjunc]))
	      ||(dSW[ijunc] <= MIN(mindSW,dSW[minjunc]))) {
	    // we have a candidate junction
	    if (edgej[ijunc] != edgej[minjunc]) {
	      pspan = -1;
	      break;
	    } else {
	      nearj[nnear] = seqj[ijunc];
	      nnear++;
	    }
	  }
	}

	if (pspan >= 0){
	  // compute perimeter span -- find largest gap and take remainder
	  quicksort(nearj,nnear);
	  //mexPrintf("Positions:  ");
	  //for (inear = 0; inear < nnear; inear++) {
	  //  mexPrintf("%d ",nearj[inear]);
	  //}
	  pspan = nearj[0]-nearj[nnear-1]+edgelen[edgej[minjunc]];
	  //mexPrintf("\nDifferences:  %d ",pspan);
	  for (inear = 1; inear < nnear; inear++) {
	    if (pspan < nearj[inear]-nearj[inear-1]) {
	      pspan = nearj[inear]-nearj[inear-1];
	    }
	    //mexPrintf("%d ",nearj[inear]-nearj[inear-1]);
	  }
	  //mexPrintf(" => Result:  %d (from %d; ep = %d).\n",
	  //    edgelen[edgej[minjunc]]-pspan,pspan,
	  //    edgelen[edgej[minjunc]]);
	  pspan = edgelen[edgej[minjunc]]-pspan;
	  skg[i+j*nrow] = pspan;
	} else {
	  skg[i+j*nrow] = mxGetInf();
	}

	//mexPrintf("Final span:  %g.\n",pspan);
      } else {
	skg[i+j*nrow] = 0;
	if (nlhs > 1) {
	  rad[i+j*nrow] = 0;
	}
      }
    }
  }

  // free space
  mxFree(jx);
  mxFree(jy);
  mxFree(seqj);
  mxFree(edgej);
  mxFree(seenj);
  mxFree(dNE);
  mxFree(dNW);
  mxFree(dSE);
  mxFree(dSW);
  mxFree(nearj);
}
// end of compute_skeleton_gradient()

//***************************************************************************
//
// Gateway driver to call the calculation from Matlab.
//
// This is the Matlab entry point.
// 

void 
mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
  int nrow, ncol;
  double *img;

  // check for proper number of arguments
  errCheck(nrhs == 1,"Exactly one input argument required.");
  errCheck(nlhs <= 2,"Too many output arguments.");

  // check format of arguments
  errCheck(mxIsUint8(prhs[0])||mxIsLogical(prhs[0])||mxIsDouble(prhs[0]),
	   "Input must be double binary image.");
  nrow = mxGetM(prhs[0]);
  ncol = mxGetN(prhs[0]);
  img = mxGetPr(prhs[0]);

  // process image
  if (mxIsDouble(prhs[0])) {
    compute_skeleton_gradient(img,nrow,ncol,nlhs,plhs);
  } else {
    compute_skeleton_gradient((unsigned char *)img,nrow,ncol,nlhs,plhs);
  }
}
// end of mexFunction()

?? 快捷鍵說(shuō)明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號(hào) Ctrl + =
減小字號(hào) Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
voyeur盗摄精品| 欧美日韩三级视频| 中文字幕av资源一区| 成人激情校园春色| 中文字幕av一区二区三区| 亚洲国产日韩a在线播放| 欧美日韩精品二区第二页| 五月激情六月综合| 日韩一卡二卡三卡四卡| 免费成人结看片| 精品国产乱码久久久久久蜜臀| 国产美女久久久久| 久久久久久电影| 国产精品一区二区三区乱码| 久久久不卡网国产精品一区| 国产成人午夜视频| 久久亚洲春色中文字幕久久久| 国产乱码精品一区二区三区忘忧草 | 日韩av一级电影| 日韩欧美一区二区免费| 国内精品视频666| 国产精品三级久久久久三级| 99综合电影在线视频| 亚洲永久免费视频| 欧美日韩不卡一区| 日韩国产欧美三级| 久久久久97国产精华液好用吗| 成人99免费视频| 亚洲色图第一区| 这里只有精品电影| 久久精品久久精品| 中文字幕在线观看一区| 欧美亚洲图片小说| 免费av成人在线| 国产亚洲视频系列| 色婷婷综合久久久久中文| 亚洲高清中文字幕| 国产日韩欧美精品在线| 一本久道中文字幕精品亚洲嫩| 同产精品九九九| wwwwxxxxx欧美| 色综合久久88色综合天天6| 一区二区三区在线播| 精品国产乱码久久久久久图片 | 亚洲.国产.中文慕字在线| 日韩视频免费直播| 色综合色综合色综合色综合色综合| 亚洲成人一二三| 欧美国产日韩亚洲一区| 欧美色网站导航| 国产制服丝袜一区| 亚洲五月六月丁香激情| 欧美精品一区二区三区蜜桃视频| 色婷婷国产精品综合在线观看| 免费国产亚洲视频| 国产精品久久免费看| 这里只有精品99re| 播五月开心婷婷综合| 免费精品99久久国产综合精品| 国产精品国产a级| 欧美一区二区三区免费| 色中色一区二区| 蓝色福利精品导航| 亚洲一区二区精品久久av| 久久精品人人做人人爽97| 在线视频你懂得一区二区三区| 国产福利一区二区| 亚洲成人一区二区在线观看| 最新日韩av在线| 欧美一级欧美一级在线播放| 99r国产精品| 国产激情视频一区二区三区欧美| 亚洲一区中文日韩| 中文字幕亚洲区| 欧美不卡一区二区三区四区| 国模冰冰炮一区二区| 亚洲成av人影院| 成人动漫视频在线| 在线播放日韩导航| 成人va在线观看| 狠狠网亚洲精品| 国产精品大尺度| 久久久一区二区| 日韩欧美一区二区视频| 91久久线看在观草草青青| 麻豆成人久久精品二区三区红| 亚洲国产日韩精品| 成人免费在线视频| 日本一二三四高清不卡| 日韩写真欧美这视频| 欧美人xxxx| 91黄色免费看| av在线综合网| voyeur盗摄精品| 国产精品1024久久| 精品一区精品二区高清| 亚洲mv在线观看| 亚洲欧美日韩一区二区三区在线观看| 26uuu久久综合| 欧美一区二区三区播放老司机| 在线视频观看一区| 91色.com| 一本一本久久a久久精品综合麻豆| 国产精品一区二区你懂的| 久久超级碰视频| 日本91福利区| 丝袜美腿亚洲一区二区图片| 亚洲女人的天堂| 亚洲视频免费在线观看| 欧美国产1区2区| 国产精品你懂的| 中国av一区二区三区| 中文字幕在线观看一区| 国产精品国产三级国产aⅴ无密码| 国产精品高清亚洲| 中文字幕在线不卡视频| 亚洲蜜桃精久久久久久久| 国产精品传媒视频| 国产精品美女久久久久久2018| 久久久www免费人成精品| 久久无码av三级| 国产精品网站在线| 国产欧美视频一区二区三区| 国产精品美女久久久久久2018| 欧美韩日一区二区三区| 《视频一区视频二区| 亚洲视频一区二区在线| 亚洲线精品一区二区三区| 亚洲午夜精品网| 亚洲在线视频网站| 日本特黄久久久高潮| 日韩vs国产vs欧美| 精品伊人久久久久7777人| 国产一区二区伦理片| 成人爽a毛片一区二区免费| 国产91高潮流白浆在线麻豆| 99久久久久久99| 91成人在线观看喷潮| 在线免费观看成人短视频| 欧美高清你懂得| 日韩亚洲欧美成人一区| 国产精品午夜久久| 亚洲欧美欧美一区二区三区| 丝袜美腿亚洲色图| 美日韩一区二区| 丁香一区二区三区| 91色|porny| 91精品国产综合久久精品麻豆| 日韩欧美一区电影| 欧美一区二区视频观看视频| 久久久久久免费网| 亚洲欧洲国产专区| 日一区二区三区| 精彩视频一区二区| 91美女蜜桃在线| 欧美日韩视频专区在线播放| 精品国产免费人成电影在线观看四季 | 国产a精品视频| 色哟哟国产精品免费观看| 91精彩视频在线观看| 欧美一区二区三区在线电影| 久久丝袜美腿综合| 中文字幕在线播放不卡一区| 亚洲综合自拍偷拍| 91福利在线观看| 91精品久久久久久久91蜜桃 | 日本电影亚洲天堂一区| 欧美成人三级电影在线| 久久蜜桃香蕉精品一区二区三区| 亚洲人午夜精品天堂一二香蕉| 午夜视频在线观看一区| 国产v综合v亚洲欧| 欧美日韩你懂得| 亚洲国产成人午夜在线一区| 亚洲综合色视频| 国产激情91久久精品导航| 91久久精品日日躁夜夜躁欧美| 日韩一区二区麻豆国产| 国产精品人妖ts系列视频| 丝袜美腿亚洲色图| 国产乱人伦偷精品视频不卡 | 91精品国产综合久久久久久久久久| 日本一区二区三区电影| 亚洲国产一二三| 国产在线播放一区| 97国产一区二区| 日韩免费高清电影| 成人欧美一区二区三区黑人麻豆 | 一区二区三区日韩精品视频| 日本人妖一区二区| 国产乱一区二区| 欧美一级免费观看| 亚洲欧美日韩电影| 国产高清久久久久| 欧美精品在线观看一区二区| 国产精品欧美一级免费| 日日夜夜精品视频免费| 欧洲色大大久久| 国产亚洲人成网站| 九九视频精品免费|