sdf.cpp
上传用户:liuping58
上传日期:2022-06-05
资源大小:105k
文件大小:10k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. /*(C) 2007 Timothy B. Terriberry*/
  2. /*Redistribution and use in source and binary forms, with or without
  3.   modification, are permitted provided that the following conditions
  4.   are met:
  5.   - Redistributions of source code must retain the above copyright
  6.   notice, this list of conditions and the following disclaimer.
  7.   - Redistributions in binary form must reproduce the above copyright
  8.   notice, this list of conditions and the following disclaimer in the
  9.   documentation and/or other materials provided with the distribution.
  10.   - Neither the name of the Xiph.org Foundation nor the names of its
  11.   contributors may be used to endorse or promote products derived from
  12.   this software without specific prior written permission.
  13.   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  14.   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  15.   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  16.   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
  17.   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  18.   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  19.   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  20.   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  21.   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  22.   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  23.   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <limits.h>
  27. #include <string.h>
  28. /*Computes the signed Euclidean distance transform of a binary image in two
  29.    dimensions.
  30.   Regions inside the shape have negative distance, and regions outside have
  31.    positive distance (_d[i,j]<0 if and only if _bimg[i,j] is non-zero).
  32.   The result is symmetric with respect to "inside" and "outside" the shape.
  33.   That is, if bimg1[i,j]==!bimg2[i,j] for all i, j, then the resulting
  34.    distance transforms d1 and d2 obey the relation d1[i,j]==-d2[i,j].
  35.   We use the distance to the boundary of the shape, which is equivalent to
  36.    the following procedure:
  37.    a) Compute a new boundary image b, twice the size of the original, where
  38.     b[i,j] is zero if i and j are both even, and non-zero elsewhere if and
  39.     only if the set of values _bimg[y>>1,x>>1] for the 8-connected neighbors
  40.     (x,y) of (i,j) contain both zero and non-zero values.
  41.    b) Compute db[i,j], the normal, unsigned distance transform of the boundary
  42.     image, b[i,j].
  43.    c) Negate the result inside the shape and downsample by setting
  44.     d[i,j]=_bimg[i,j]?-db[i<<1,j<<1]:db[i<<1,j<<1].
  45.   _d:    Returns the signed squared distance in half-pixel squared units.
  46.          That is, the Euclidean distance to the boundary of the binary shape is
  47.           0.5*sqrt(fabs(_d[i,j])).
  48.          If there is _no_ boundary in the image, i.e., _bimg[i,j] is zero
  49.           everywhere resp. non-zero everywhere, then the returned distance is
  50.           INT_MAX resp. INT_MIN everywhere.
  51.   _bimg: The binary image to compute the distance transform over.
  52.          A pixel is "inside" the shape if _bimg[i,j] is non-zero, and
  53.           "outside" otherwise.
  54.   _h:    The number of rows in _bimg.
  55.   _w:    The number of columns in _bimg.*/
  56. void sedt2d(int *_d,unsigned char *_bimg,int _h,int _w){
  57.   int *dd;
  58.   int *f;
  59.   int *v;
  60.   int *z;
  61.   int  i;
  62.   int  j;
  63.   int  k;
  64.   int  n;
  65.   /*We use an adaptation of the O(n) algorithm from cite{FH04}.
  66.     Our adaptation computes the positive and negative transform values
  67.      simultaneously in a single pass.
  68.     We could use the orignal algorithm on a doubled image as described in our
  69.      documentation, but choose instead to operate directly on the original
  70.      image, which makes for more complex code, but vastly reduced memory usage.
  71.   @TECHREPORT{
  72.     author="Pedro F. Felzenszwalb and Daniel P. Huttenlocher",
  73.     title="Distance Transforms of Sampled Functions",
  74.     number="TR2004-1963",
  75.     institution="Cornell Computing and Information Science",
  76.     year=2004
  77.   }*/
  78.   if(_h<=0||_w<=0)return;
  79.   /*We do not strictly need this temporary image, but using it allows us to
  80.      read out of it untransposed in the second pass, which is much nicer to the
  81.      cache.
  82.     We still have to write a transposed image in each pass, but writing
  83.      introduces fewer stalls than reading.*/
  84.   dd=(int *)malloc(_h*_w*sizeof(*dd));
  85.   n=_h>_w?_h:_w;
  86.   v=(int *)malloc(n*sizeof(*v));
  87.   z=(int *)malloc((n+1)*sizeof(*z));
  88.   f=(int *)malloc(_h*sizeof(*f));
  89.   /*First compute the signed distance transform along the X axis.*/
  90.   for(i=0;i<_h;i++){
  91.     k=-1;
  92.     /*At this stage, every transition contributes a parabola to the final
  93.        envelope, and the intersection point _must_ lie between the vertices, so
  94.        there's no need to worry about deletion or bounds checking.*/
  95.     for(j=1;j<_w;j++)if(!_bimg[i*_w+j-1]!=!_bimg[i*_w+j]){
  96.       int q;
  97.       int s;
  98.       q=(j<<1)-1;
  99.       s=k<0?0:(v[k]+q>>2)+1;
  100.       v[++k]=q;
  101.       z[k]=s;
  102.     }
  103.     /*Now, go back and compute the distances to each parabola.
  104.       If there were _no_ parabolas, then fill the row with +/- infinity.*/
  105.     /*This is equivalent to dd[j*_h+i]=_bimg[i*_w+j]?INT_MIN:INT_MAX;*/
  106.     if(k<0)for(j=0;j<_w;j++)dd[j*_h+i]=INT_MAX+!!_bimg[i*_w+j];
  107.     else{
  108.       int zk;
  109.       z[k+1]=_w;
  110.       j=k=0;
  111.       do{
  112.         int d1;
  113.         int d2;
  114.         d1=(j<<1)-v[k];
  115.         d2=d1*d1;
  116.         d1=d1+1<<2;
  117.         zk=z[++k];
  118.         for(;;){
  119.           /*This is equivalent to dd[j*_h+i]=_bimg[i*_w+j]?-d2:d2;*/
  120.           dd[j*_h+i]=d2-(d2<<1&-!!_bimg[i*_w+j]);
  121.           if(++j>=zk)break;
  122.           d2+=d1;
  123.           d1+=8;
  124.         }
  125.       }
  126.       while(zk<_w);
  127.     }
  128.   }
  129.   /*Now extend the signed distance transform along the Y axis.
  130.     This part of the code heavily depends on good branch prediction to be
  131.      fast.*/
  132.   for(j=0;j<_w;j++){
  133.     int psign;
  134.     /*v2 is not used uninitialzed, despite what your compiler may think.*/
  135.     int v2;
  136.     int q2;
  137.     k=-1;
  138.     /*Choose an initial value of psign that ensures there's no transition.
  139.       This is the reason for the _h<=0 test at the start of the function.*/
  140.     psign=dd[j*_h+0]<0;
  141.     for(i=0,q2=1;i<_h;i++){
  142.       int sign;
  143.       int d;
  144.       d=dd[j*_h+i];
  145.       sign=d<0;
  146.       /*If the sign changes, we've found a boundary point, and place a parabola
  147.          of height 0 there.*/
  148.       if(sign!=psign){
  149.         int q;
  150.         int s;
  151.         q=(i<<1)-1;
  152.         if(k<0)s=0;
  153.         else for(;;){
  154.           s=q2-v2-f[k];
  155.           /*This is subtle: if q==v[k], then the parabolas never intersect, but
  156.              our test is correct anyway, because f[k] is always positive.*/
  157.           if(s>0){
  158.             s=s/(q-v[k]<<2)+1;
  159.             if(s>z[k])break;
  160.           }
  161.           else s=0;
  162.           if(--k<0)break;
  163.           v2=v[k]*v[k];
  164.         }
  165.         v[++k]=q;
  166.         f[k]=0;
  167.         z[k]=s;
  168.         v2=q2;
  169.       }
  170.       /*We test for INT_MIN and INT_MAX together by adding +1 or -1 depending
  171.          on the sign of d and checking if it retains that sign.
  172.         If we have a finite point, we place up to three parabolas around it at
  173.          height abs(d).
  174.         There's no need to distinguish between the envelope inside and outside
  175.          the shape, as a parabola of height 0 will always lie between them.*/
  176.       if(sign==d-sign+!sign<0){
  177.         int fq;
  178.         int q;
  179.         int s;
  180.         int t;
  181.         fq=abs(d);
  182.         q=(i<<1)-1;
  183.         if(k<0){
  184.           s=0;
  185.           t=1;
  186.         }
  187.         else for(;;){
  188.           t=(q+1-v[k])*(q+1-v[k])+f[k]-fq;
  189.           /*If the intersection point occurs to the left of the vertex, we will
  190.              add all three parabolas, so we compute the intersection with the
  191.              left-most parabola here.*/
  192.           if(t>0){
  193.             /*This is again subtle: if q==v[k], then we will take this branch
  194.                whenever f[k]>=fq.
  195.               The parabolas then intersect everywhere (when f[k]==fq) or
  196.                nowhere (when f[k]>fq).
  197.               However, in either case s<=0, and so we skip the division by zero
  198.                below and delete the previous parabola.
  199.               This relies on the fact that we ensure z[k] is never negative.*/
  200.             s=q2-v2+fq-f[k];
  201.             s=s<=0?0:s/(q-v[k]<<2)+1;
  202.           }
  203.           /*Otherwise we only add the right-most, so we compute that
  204.              intersection point.
  205.             (q+1)'s intersection point must lie even farther to the right than
  206.              q's, so there is no needs to boundary check against 0.*/
  207.           else s=(q2+(i<<3)-v2+fq-f[k])/(q+2-v[k]<<2)+1;
  208.           if(s>z[k]||--k<0)break;
  209.           v2=v[k]*v[k];
  210.         }
  211.         if(t>0){
  212.           /*We only add the left-most parabola if it affects at least one
  213.              pixel to prevent overrunning our arrays (e.g., consider the case
  214.              _h==1).*/
  215.           if(s<i){
  216.             v[++k]=q;
  217.             f[k]=fq;
  218.             z[k]=s;
  219.           }
  220.           /*The center parabola will always span the interval [i,i+1), since
  221.              the left and right parabolas are better outside of it.*/
  222.           v[++k]=q+1;
  223.           f[k]=fq;
  224.           z[k]=i;
  225.           s=i+1;
  226.         }
  227.         /*We only add the right-most parabola if it affects at least one pixel,
  228.            to prevent overrunning our arrays (e.g., consider the case _h==1).
  229.           This also conveniently ensures that z[k] is never larger than _h.*/
  230.         if(s<_h){
  231.           v[++k]=q+2;
  232.           f[k]=fq;
  233.           z[k]=s;
  234.           v2=q2+(i<<3);
  235.         }
  236.       }
  237.       psign=sign;
  238.       q2+=i<<3;
  239.     }
  240.     /*Now, go back and compute the distances to each parabola.*/
  241.     if(k<0){
  242.       /*If there were _no_ parabolas, then the shape is uniform, and we've
  243.          already filled it with +/- infinity in the X pass, so there's no need
  244.          to examine the rest of the columns.
  245.         Just copy the whole thing to the output image.*/
  246.       memcpy(_d,dd,_w*_h*sizeof(*_d));
  247.       break;
  248.     }
  249.     else{
  250.       int zk;
  251.       z[k+1]=_h;
  252.       i=k=0;
  253.       do{
  254.         int d2;
  255.         int d1;
  256.         d1=(i<<1)-v[k];
  257.         d2=d1*d1+f[k];
  258.         d1=d1+1<<2;
  259.         zk=z[++k];
  260.         for(;;){
  261.           /*This is equivalent to _d[i*_w+j]=dd[j*_h+i]<0?-d2:d2;*/
  262.           _d[i*_w+j]=d2-(d2<<1&-(dd[j*_h+i]<0));
  263.           if(++i>=zk)break;
  264.           d2+=d1;
  265.           d1+=8;
  266.         }
  267.       }
  268.       while(zk<_h);
  269.     }
  270.   }
  271.   free(f);
  272.   free(z);
  273.   free(v);
  274.   free(dd);
  275. }