#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;
}