sobel 梯度计算

#include<stdio.h> 
#include<memory.h>
#include<math.h>
#include <iostream>

////////////////////////////////体数据//////////////////////////////////
#define WIDTH 256
#define HEIGHT 256
#define DEPTH 225
#define volumeType unsigned char
#define maxScalarData 255.0
int width_height=WIDTH*HEIGHT;
int totalLength=width_height*DEPTH;

float * volumeData= new float [totalLength];
float * gradientX = new float [totalLength];
float * gradientY = new float [totalLength];
float * gradientZ = new float [totalLength];
float * gradient_Length = new float [totalLength];

float * grad   = new float [totalLength*3];

///////////////////////////////////////////SOBEL 算子/////////////////////////////////////////////
float  X_OPERATOR_MATRIX[27]={-1,0,1,-3,0,3,-1,0,1,-3,0,3,-6,0,6,-3,0,3,-1,0,1,-3,0,3,-1,0,1};
float  Y_OPERATOR_MATRIX[27]={-1,-3,-1,0,0,0,1,3,1,-3,-6,-3,0,0,0,3,6,3,-1,-3,-1,0,0,0,1,3,1};
float  Z_OPERATOR_MATRIX[27]={-1,-3,-1,-3,-6,-3,-1,-3,-1,0,0,0,0,0,0,0,0,0,1,3,1,3,6,3,1,3,1};

//////////////////////////////////////////判断出界算子///////////////////////////////////////////
float  BELOW_X_MIN_BORDER[27]={0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1};
float  ABOVE_X_MAX_BORDER[27]={1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0};
float  BELOW_Y_MIN_BORDER[27]={0,0,0,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1};
float  ABOVE_Y_MAX_BORDER[27]={1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,0,0,0};
float  BELOW_Z_MIN_BORDER[27]={0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
float  ABOVE_Z_MAX_BORDER[27]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0};

bool readInFile(char* FileName);
bool combine_operator(float destination_array[],float operator_array[]);
bool writeFile(float a[],int leg,char* FileName);

int main()             
{
 if(!readInFile("head256.raw"))  printf("Read File ERROR!");//foot 256x256x256 8bits/feet_8bits.raw

 memset(gradientX, 0, sizeof(float)*totalLength);   //初始化
 memset(gradientY, 0, sizeof(float)*totalLength);
 memset(gradientZ, 0, sizeof(float)*totalLength);
 memset(gradient_Length, 0, sizeof(float)*totalLength);

// printf("%d",readInFile("head.raw"));
 int i,j,k,w,h,d,temp;
 float current_x_operator[27];
 float current_y_operator[27];
 float current_z_operator[27];
 int current_volume;
//  float max_x = 0,max_y = 0,max_z = 0,max_g = 0;
//  float min_x = 0,min_y = 0,min_z = 0,min_g = 0;
    float max_g = 0,  min_g = 0;

 for(i=0;i<27;i++) current_x_operator[i]=X_OPERATOR_MATRIX[i];
 for(i=0;i<27;i++) current_y_operator[i]=Y_OPERATOR_MATRIX[i];
 for(i=0;i<27;i++) current_z_operator[i]=Z_OPERATOR_MATRIX[i];

 for(w=0;w<WIDTH;w++)
 {  

  for(h=0;h<HEIGHT;h++)
  {
   
   
   for(d=0;d<DEPTH;d++)
   {
    //////////////////////////判断出界情况,用算子记录/////////////////////
    if(w==0)
    {
     combine_operator(current_x_operator,BELOW_X_MIN_BORDER);
     combine_operator(current_y_operator,BELOW_X_MIN_BORDER);
     combine_operator(current_z_operator,BELOW_X_MIN_BORDER);
    }
    if(w==(WIDTH-1))
    {
     combine_operator(current_x_operator,ABOVE_X_MAX_BORDER);
     combine_operator(current_y_operator,ABOVE_X_MAX_BORDER);
     combine_operator(current_z_operator,ABOVE_X_MAX_BORDER);
    }
    if(h==0)
    {
     combine_operator(current_x_operator,BELOW_Y_MIN_BORDER);
     combine_operator(current_y_operator,BELOW_Y_MIN_BORDER);
     combine_operator(current_z_operator,BELOW_Y_MIN_BORDER);
    }
    if(h==(HEIGHT-1))
    {
     combine_operator(current_x_operator,ABOVE_Y_MAX_BORDER);
     combine_operator(current_y_operator,ABOVE_Y_MAX_BORDER);
     combine_operator(current_z_operator,ABOVE_Y_MAX_BORDER);
    }
    if(d==0)
    {
     combine_operator(current_x_operator,BELOW_Z_MIN_BORDER);
     combine_operator(current_y_operator,BELOW_Z_MIN_BORDER);
     combine_operator(current_z_operator,BELOW_Z_MIN_BORDER);
    }
    if(d==(DEPTH-1))
    {
     combine_operator(current_x_operator,ABOVE_Z_MAX_BORDER);
     combine_operator(current_y_operator,ABOVE_Z_MAX_BORDER);
     combine_operator(current_z_operator,ABOVE_Z_MAX_BORDER);
    }


    //////////////////////////////当前点算子确定后,下面与体数据加权计算当前点的梯度///////////////
    temp=w+h*WIDTH+d*width_height;
    for(k=0;k<3;k++)
    {
     for(j=0;j<3;j++)
     {
      for(i=0;i<3;i++)
      {
       if( current_x_operator[i+j*3+k*9]==-13 )
                            {
                                continue;//////////////算子判断出界
                            }
       current_volume=w+i-1+(h+j-1)*WIDTH+(d+k-1)*width_height;

       if( !volumeData[current_volume] )
                            {
                                continue;
                            }

       if( current_x_operator[i+j*3+k*9] )
                            {
                                gradientX[temp]+=current_x_operator[i+j*3+k*9]*volumeData[current_volume];
                            }

       if( current_y_operator[i+j*3+k*9] )
                            {
                                gradientY[temp]+=current_y_operator[i+j*3+k*9]*volumeData[current_volume];
                            }

       if( current_z_operator[i+j*3+k*9] )
                            {
                                gradientZ[temp]+=current_z_operator[i+j*3+k*9]*volumeData[current_volume];
                            }
       
      }
     }
    }
    gradient_Length[temp] = sqrt(gradientX[temp]*gradientX[temp]+gradientY[temp]*gradientY[temp]+gradientZ[temp]*gradientZ[temp]);
    min_g = min_g>gradient_Length[temp] ? gradient_Length[temp]:min_g;
    max_g = max_g<gradient_Length[temp] ? gradient_Length[temp]:max_g;

    /*turn gradient to negative*/
    if (gradient_Length[temp])
    {
     gradientX[temp] = (  ( (float)gradientX[temp]/gradient_Length[temp] )+1 ) / 2.0;
     gradientY[temp] = (  ( (float)gradientY[temp]/gradient_Length[temp] )+1 ) / 2.0;
     gradientZ[temp] = (  ( (float)gradientZ[temp]/gradient_Length[temp] )+1 ) / 2.0;
    }
    else
    {
     gradientX[temp] = 0;
     gradientY[temp] = 0;
     gradientZ[temp] = 0;
    }
//     min_x = min_x>gradient_Length[temp] ? gradient_Length[temp]:min_x;
//     max_x = max_x<gradient_Length[temp] ? gradient_Length[temp]:max_x;
//     min_y = min_y>gradient_Length[temp] ? gradient_Length[temp]:min_y;
//     max_y = max_y<gradient_Length[temp] ? gradient_Length[temp]:max_y;
//     min_z = min_z>gradient_Length[temp] ? gradient_Length[temp]:min_z;
//     max_z = max_z<gradient_Length[temp] ? gradient_Length[temp]:max_z;
    

    grad[temp]  = gradientX[temp];
    grad[temp+1] = gradientY[temp];
    grad[temp+2] = gradientZ[temp];

    /////////////////下一个点梯度开始计算前恢复算子////////////
    for(i=0;i<27;i++) current_z_operator[i]=Z_OPERATOR_MATRIX[i];
    for(i=0;i<27;i++) current_y_operator[i]=Y_OPERATOR_MATRIX[i];
    for(i=0;i<27;i++) current_x_operator[i]=X_OPERATOR_MATRIX[i];
   }   
  }  
 }


 //----------------normalize grad length----------------
 for (i=0; i<totalLength; i++)
 {
  gradient_Length[i] = (float)/*(*/gradient_Length[i]/*-3.4641)*/ / max_g/*1727.77*//*1718.3059*/;
 }

 std::cout<<gradientX[34010]<<std::endl;

  writeFile(gradientX, totalLength, "head256_gradx.raw");
  writeFile(gradientY, totalLength, "head256_grady.raw");
  writeFile(gradientZ, totalLength, "head256_gradz.raw");
 writeFile(gradient_Length, totalLength, "head256_grad.raw");

 delete volumeData;
 delete gradientX ;
 delete gradientY ;
 delete gradientZ ;
 delete gradient_Length ;
 delete grad;
 return 0;
}

 

bool readInFile(char* FileName)
{
 FILE *fd;
 fd=fopen(FileName,"rb");
 int dataLength=width_height*DEPTH;
 volumeType * t=new volumeType [dataLength];
 if(!fd)
 {
  return 0;
 }

 fread(t,sizeof(volumeType),dataLength,fd);

 for(int i=0;i<dataLength;i++)
 {
  volumeData[i]=(float) t[i];///maxScalarData;
 }

 delete t;
 fclose(fd);

 return 1;
}


bool writeFile(float  a[],int leg,char* FileName)
{
 FILE *fd;
 fd=fopen(FileName,"wb");
 if(!fd)
 {
  return 0;
 }
 
 fwrite(a,sizeof(float),leg,fd);
 return 1;
}


bool combine_operator(float destination_array[],float operator_array[])/////////默认是3*3*3矩阵的并操作
{
 int temp;
 for(int i=0;i<3;i++)
 {
  for(int j=0;j<3;j++)
  {
   for(int k=0;k<3;k++)
   {
    temp=i+j*3+k*9;
    if(!operator_array[temp]) destination_array[temp]= -13 ;//////////-13这个特殊值在算子中作为边界判断的值///////
   }
  }
 }

 return 1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值