00001 /* ImLib3D 00002 * Copyright (c) 2001, ULP-IPB Strasbourg. 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or (at 00007 * your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, but 00010 * WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software 00016 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00017 */ 00020 #include<ImLib3D/FFT.hpp> 00021 #include<ImLib3D/Transformation.hpp> 00022 #include<ImLib3D/Threshold.hpp> 00023 #include<ImLib3D/Arithmetic.hpp> 00024 #include<ImLib3D/Convolution.hpp> 00025 00026 00028 00033 template <> 00034 void 00035 IP3D::TransformWithInverseField<Mask3D>(const Mask3D& src, const Field3Df& field, Mask3D& res0) 00036 { 00037 // Image Args 00038 ImageProcessorArgs<Mask3D> args(ImArgs(src),res0); 00039 args.SetDestSize(field.Size()); 00040 Mask3D &res=args.GetDest(); 00041 00042 // find distinct values 00043 vector<int> values0; 00044 values0.assign(256,0); 00045 for(Mask3D::const_iteratorFast mp=src.begin();mp!=src.end();++mp) 00046 { 00047 values0[*mp]++; 00048 } 00049 vector<byte> distinct; 00050 uint i; 00051 for(i=0;i<256;i++){if(values0[i]){distinct.push_back(i);}} 00052 00053 Image3Df resWeight(res.Size()); 00055 resWeight.Fill(.01); 00056 res.Fill(0); 00057 // extract mask for each distinct value 00058 for(i=0;i<distinct.size();i++) 00059 { 00060 byte value=distinct[i]; 00061 Mask3D srcMask; 00062 IP3D::SimpleThresholds2(src,value,value,srcMask); 00063 srcMask.Normalize(); 00064 Image3Df ima; 00065 // transform mask with field and good interpol 00066 { 00067 ima=srcMask; 00068 // smooth mask to avoid violent aliasing 00069 Filter filter(3,3,3,Vect3Di(1,1,1)); 00070 filter.Fill(1.0/filter.GetNVoxels()); 00071 IP3D::Convolution(ima,filter,ima); 00072 // apply transform 00073 IP3D::TransformWithInverseField(ima,field,ima); 00074 } 00075 // add result to final mask 00076 { 00077 Mask3D::iteratorFast rp; 00078 Image3Df::iteratorFast ip; 00079 Image3Df::iteratorFast wp; 00080 // use weight image to vote for best final pixel value 00081 for(rp=res.begin(),ip=ima.begin(),wp=resWeight.begin(); 00082 rp!=res.end(); 00083 rp++,ip++,wp++) 00084 { 00085 if(*ip>*wp) 00086 { 00087 *rp=value; 00088 *wp=*ip; 00089 } 00090 } 00091 } 00092 // mprintf("** affine trf image:for value:%d\n",value);ImLib3DDisplay::Show(ima); 00093 // mprintf("** weights after :%d\n",value);ImLib3DDisplay::Show(resWeight); 00094 // mprintf("** res after :%d\n",value);ImLib3DDisplay::Show(res); 00095 00096 00097 } 00098 } 00099 00100 00101 // void 00102 // CTransform::CreateField(Field3Df &field, const Affine3DTransform& transfo) 00103 // { 00104 // Matrix M = transfo.M; 00105 // ColumnVector T = transfo.T; 00106 // float a11=M(1,1),a21=M(2,1),a31=M(3,1); 00107 // float a12=M(1,2),a22=M(2,2),a32=M(3,2); 00108 // float a13=M(1,3),a23=M(2,3),a33=M(3,3); 00109 00110 // Field3Df::iteratorFast p; 00111 // p=field.begin(); 00112 // Vect3Df T1; 00113 // Vect3Df Ttemp(T(1), T(2), T(3)); 00114 // for(int z=0;z<field.Depth() ;z++) 00115 // { 00116 // Vect3Df Vz(a13,a23,a33); 00117 // Vz*=z; 00118 // for(int y=0;y<field.Height();y++) 00119 // { 00120 // Vect3Df Vy(a12,a22,a32); 00121 // Vy*=y; 00122 // Vy+=Vz; 00123 // for(int x=0;x<field.Width() ;x++) 00124 // { 00125 // Vect3Df Vx(a11,a21,a31); 00126 // Vx*=x; 00127 // *p=Vy+Vx+Ttemp-Vect3Df(x,y,z); 00128 // p++; 00129 // } 00130 // } 00131 // } 00132 // } 00133 00134 void 00135 IP3D::TransformAffineHelpers::CreateInverseField(Field3Df &field, const Affine3DTransform& transfo0) 00136 { 00137 // cout << "CreateField:" << endl << transfo0.M << "T:"<< transfo0.T << endl; 00138 Affine3DTransform transfo=transfo0; 00139 transfo.Inverse(); 00140 // cout << "CreateField:" << endl << transfo.M << "T:"<< transfo.T << endl; 00141 Field3Df::iteratorXYZ fp; 00142 ImageProgress tracker("CTransformAffine::CreateInverseField",fp); 00143 for(fp=field.begin();fp!=field.end();++fp) 00144 { 00145 Vect3Df P(fp.x,fp.y,fp.z); 00146 *fp=transfo(P)-P; 00147 } 00148 // Matrix M = transfo.M; 00149 // ColumnVector T = transfo.T; 00150 // float a11=M(1,1),a21=M(2,1),a31=M(3,1); 00151 // float a12=M(1,2),a22=M(2,2),a32=M(3,2); 00152 // float a13=M(1,3),a23=M(2,3),a33=M(3,3); 00153 00154 // Field3Df::iteratorFast p; 00155 // p=field.begin(); 00156 // Vect3Df T1; 00157 // Vect3Df Ttemp(T(1), T(2), T(3)); 00158 // for(int z=0;z<field.Depth() ;z++) 00159 // { 00160 // Vect3Df Vz(a13,a23,a33); 00161 // Vz*=z; 00162 // for(int y=0;y<field.Height();y++) 00163 // { 00164 // Vect3Df Vy(a12,a22,a32); 00165 // Vy*=y; 00166 // Vy+=Vz; 00167 // for(int x=0;x<field.Width() ;x++) 00168 // { 00169 // Vect3Df Vx(a11,a21,a31); 00170 // Vx*=x; 00171 // *p=Vy+Vx+Ttemp-Vect3Df(x,y,z); 00172 // p++; 00173 // } 00174 // } 00175 // } 00176 00177 } 00178 00179 // template <> 00180 // void IP3D::TransformWithFieldInt<Mask3D>(const Mask3D& imOrig, const Field3Df& field, Mask3D& _imRes) 00181 // { 00182 // Image3Df src1;src1=imOrig; 00183 // Image3Df res1; 00184 // Apply( src1, field, res1); 00185 // res1+=.5; 00186 // float minv,maxv; 00187 // res1.FindMinMax(minv,maxv);mprintf("** minv:%f,maxv:%f\n",minv,maxv); 00188 // IP3D::LimitThreshold(res1,0.0f,255.0f,res1); 00189 // res1.FindMinMax(minv,maxv);mprintf("** minv:%f,maxv:%f\n",minv,maxv); 00190 // _imRes=res1; 00191 // } 00192 00193