00001
00002
00003 #include "Mmorph.h"
00004
00005 template
00006 void Erosion3x3< int >(Image< int > &input, int iter, CONN_TYPE connect, Image< int > &output);
00007 template
00008 void Erosion3x3< byte >(Image< byte > &input, int iter, CONN_TYPE connect, Image< byte > &output);
00009 template
00010 void Dilation3x3< int >(Image< int > &input, int iter, CONN_TYPE connect, Image< int > &output);
00011 template
00012 void Dilation3x3< byte >(Image< byte > &input, int iter, CONN_TYPE connect, Image< byte > &output);
00013 template
00014 void Opening3x3< int >(Image< int > &input, int iter, CONN_TYPE connect, Image< int > &output);
00015 template
00016 void Opening3x3< byte >(Image< byte > &input, int iter, CONN_TYPE connect, Image< byte > &output);
00017 template
00018 void Closing3x3< int >(Image< int > &input, int iter, CONN_TYPE connect, Image< int > &output);
00019 template
00020 void Closing3x3< byte >(Image< byte > &input, int iter, CONN_TYPE connect, Image< byte > &output);
00021
00022 template
00023 void FlatErosion< int >(Image< int > &input, ByteKernel &kern, Image< int > &output);
00024 template
00025 void FlatErosion< byte >(Image< byte > &input, ByteKernel &kern, Image< byte > &output);
00026 template
00027 void FlatDilation< int >(Image< int > &input, ByteKernel &kern, Image< int > &output);
00028 template
00029 void FlatDilation< byte >(Image< byte > &input, ByteKernel &kern, Image< byte > &output);
00030 template
00031 void FlatOpening< int >(Image< int > &input, ByteKernel &kern, Image< int > &output);
00032 template
00033 void FlatOpening< byte >(Image< byte > &input, ByteKernel &kern, Image< byte > &output);
00034 template
00035 void FlatClosing< int >(Image< int > &input, ByteKernel &kern, Image< int > &output);
00036 template
00037 void FlatClosing< byte >(Image< byte > &input, ByteKernel &kern, Image< byte > &output);
00038
00039 template
00040 void Dilation< int >(Image< int > &input, ByteKernel &kern, Image< int > &output);
00041 template
00042 void Dilation< byte >(Image< byte > &input, ByteKernel &kern, Image< byte > &output);
00043 template
00044 void Erosion< int >(Image< int > &input, ByteKernel &kern, Image< int > &output);
00045 template
00046 void Erosion< byte >(Image< byte > &input, ByteKernel &kern, Image< byte > &output);
00047 template
00048 void Opening< int >(Image< int > &input, ByteKernel &kern, Image< int > &output);
00049 template
00050 void Opening< byte >(Image< byte > &input, ByteKernel &kern, Image< byte > &output);
00051 template
00052 void Closing< int >(Image< int > &input, ByteKernel &kern, Image< int > &output);
00053 template
00054 void Closing< byte >(Image< byte > &input, ByteKernel &kern, Image< byte > &output);
00055
00056 template
00057 void TopHat< int >(Image< int > &input, ByteKernel &kern, Image< int > &output);
00058 template
00059 void TopHat< byte >(Image< byte > &input, ByteKernel &kern, Image< byte > &output);
00060 template
00061 void BottomHat< int >(Image< int > &input, ByteKernel &kern, Image< int > &output);
00062 template
00063 void BottomHat< byte >(Image< byte > &input, ByteKernel &kern, Image< byte > &output);
00064
00065 template
00066 void HitOrMiss< int >(Image< int > &input, ByteKernel &kern1,
00067 ByteKernel &kern2, Image< int > &output);
00068 template
00069 void HitOrMiss< byte >(Image< byte > &input, ByteKernel &kern1,
00070 ByteKernel &kern2, Image< byte > &output);
00071 template
00072 void TemplateMatch< int >(Image< int > &input, ByteKernel &kern, Image< int > &output);
00073 template
00074 void TemplateMatch< byte >(Image< byte > &input, ByteKernel &kern, Image< byte > &output);
00075
00076 template< class T > static
00077 void Erosion3x3(Image< T > &input, CONN_TYPE connect, Image< T > &output);
00078 template < class T > static
00079 void Dilation3x3(Image< T > &input, CONN_TYPE connect, Image< T > &output);
00080
00081
00082 template< class T > static
00083 void Erosion3x3(Image< T > &input, CONN_TYPE connect, Image< T > &output)
00084 {
00085 int h=input.getHeight(), w=input.getWidth();
00086
00087 for(int i=0;i<h;i++)
00088 for(int j=0;j<w;j++) {
00089 int val=OFF;
00090 if(input[i][j]!=OFF) {
00091 val=ON;
00092 for(int k=-1;k<=1;k++)
00093 for(int m=-1;m<=1;m++)
00094 if(RANGE(i+k, j+m, h, w))
00095 if(((connect==FOUR) && (((k==0) && (m!=0)) ||
00096 ((k!=0) && (m==0)))) || (connect==EIGHT)) {
00097 if(input[i+k][j+m]==OFF) {
00098 val=OFF; k=1; break;
00099 }
00100 }
00101 }
00102 output[i][j]=val;
00103 }
00104 }
00105
00106 template< class T >
00107 void Erosion3x3(Image< T > &input, int iter, CONN_TYPE connect, Image< T > &output)
00108 {
00109 Image< T >tmp(input);
00110
00111 output = tmp;
00112
00113 Image< T > *pr=&tmp, *pw=&output, *tmpp;
00114
00115 for(int i=0;i<iter;i++) {
00116 Erosion3x3(*pr, connect, *pw);
00117
00118 tmpp=pr;
00119 pr=pw;
00120 pw=tmpp;
00121 }
00122
00123 output=tmp;
00124 }
00125
00126 template< class T > static
00127 void Dilation3x3(Image< T >&input, CONN_TYPE connect, Image< T >&output)
00128 {
00129 int h=input.getHeight(), w=input.getWidth();
00130
00131 for(int i=0;i<h;i++)
00132 for(int j=0;j<w;j++) {
00133 int val=ON;
00134 if(input[i][j]==OFF) {
00135 val=OFF;
00136 for(int k=-1;k<=1;k++)
00137 for(int m=-1;m<=1;m++)
00138 if(RANGE(i+k, j+m, h, w))
00139 if(((connect==FOUR) && (((k==0) && (m!=0)) ||
00140 ((k!=0) && (m==0)))) || (connect==EIGHT)) {
00141 if(input[i+k][j+m]!=OFF) {
00142 val=ON; k=1; break;
00143 }
00144 }
00145 }
00146 output[i][j]=val;
00147 }
00148 }
00149
00150 template< class T >
00151 void Dilation3x3(Image< T > &input, int iter, CONN_TYPE connect, Image< T > &output)
00152 {
00153 Image< T >tmp(input);
00154
00155 output = tmp;
00156
00157 Image< T >*pr=&tmp, *pw=&output, *tmpp;
00158
00159 for(int i=0;i<iter;i++) {
00160 Dilation3x3(*pr, connect, *pw);
00161
00162 tmpp=pr;
00163 pr=pw;
00164 pw=tmpp;
00165 }
00166
00167 output=tmp;
00168 }
00169
00170 template< class T >
00171 void Opening3x3(Image< T > &input, int iter, CONN_TYPE connect, Image< T > &output)
00172 {
00173 Erosion3x3< T >(input, iter, connect, output);
00174 Dilation3x3< T >(output, iter, connect, output);
00175 }
00176
00177 template< class T >
00178 void Closing3x3(Image< T > &input, int iter, CONN_TYPE connect, Image< T > &output)
00179 {
00180 Dilation3x3< T >(input, iter, connect, output);
00181 Erosion3x3< T >(output, iter, connect, output);
00182 }
00183
00184 template< class T >
00185 void FlatErosion(Image< T > &input, ByteKernel &kern, Image< T > &output)
00186 {
00187 int h=input.getHeight(), w=input.getWidth();
00188 int hk=kern.getHeight(), wk=kern.getWidth();
00189 int hk2=hk>>1, wk2=wk>>1;
00190
00191 if(!((hk & 1) && (wk & 1))) {
00192 ERROR("Structuring element must have odd size !")
00193 return;
00194 }
00195
00196 Image< T > tmp(input);
00197
00198 for(int i=0;i<h;i++)
00199 for(int j=0;j<w;j++) {
00200 int min=ON;
00201 for(int k=0;k<hk;k++)
00202 for(int m=0;m<wk;m++) {
00203 int posx=i+k-hk2;
00204 int posy=j+m-wk2;
00205 if(RANGE(posx, posy, h, w) && (kern[k][m]>OFF))
00206 if(input[posx][posy]<min) min=input[posx][posy];
00207 }
00208 tmp[i][j]=min;
00209 }
00210 output=tmp;
00211 }
00212
00213 template< class T >
00214 void FlatDilation(Image< T > &input, ByteKernel &kern, Image< T > &output)
00215 {
00216 int h=input.getHeight(), w=input.getWidth();
00217 int hk=kern.getHeight(), wk=kern.getWidth();
00218 int hk2=hk>>1, wk2=wk>>1;
00219
00220 if(!((hk & 1) && (wk & 1))) {
00221 ERROR("Structuring element must have odd size !")
00222 return;
00223 }
00224
00225 Image< T > tmp(input);
00226
00227 for(int i=0;i<h;i++)
00228 for(int j=0;j<w;j++) {
00229 int max=OFF;
00230 for(int k=0;k<hk;k++)
00231 for(int m=0;m<wk;m++) {
00232 int posx=i+k-hk2;
00233 int posy=j+m-wk2;
00234 if(RANGE(posx, posy, h, w) && (kern[k][m]>OFF))
00235 if(input[posx][posy]>max) max=input[posx][posy];
00236 }
00237 tmp[i][j]=max;
00238 }
00239 output=tmp;
00240 }
00241
00242 template< class T >
00243 void FlatOpening(Image< T > &input, ByteKernel &kern, Image< T > &output)
00244 {
00245 FlatErosion< T >(input, kern, output);
00246 FlatDilation< T >(output, kern, output);
00247 }
00248
00249 template< class T >
00250 void FlatClosing(Image< T > &input, ByteKernel &kern, Image< T > &output)
00251 {
00252 FlatDilation< T >(input, kern, output);
00253 FlatErosion< T >(output, kern, output);
00254 }
00255
00256 template< class T >
00257 void Erosion(Image< T > &input, ByteKernel &kern, Image< T > &output)
00258 {
00259 int h=input.getHeight(), w=input.getWidth();
00260 int hk=kern.getHeight(), wk=kern.getWidth();
00261 int hk2=hk>>1, wk2=wk>>1;
00262
00263 if(!((hk & 1) && (wk & 1))) {
00264 ERROR("Structuring element must have odd size !")
00265 return;
00266 }
00267
00268 Image< T > tmp(input);
00269
00270 for(int i=0;i<h;i++)
00271 for(int j=0;j<w;j++) {
00272 int min=ON;
00273 for(int k=0;k<hk;k++)
00274 for(int m=0;m<wk;m++) {
00275 int posx=i+k-hk2;
00276 int posy=j+m-wk2;
00277 if(RANGE(posx, posy, h, w)) {
00278 int val=input[posx][posy]-kern[k][m];
00279 if(val<min) min=val;
00280 }
00281 }
00282 tmp[i][j]=min;
00283 }
00284 output=tmp;
00285 }
00286
00287 template< class T >
00288 void Dilation(Image< T > &input, ByteKernel &kern, Image< T > &output)
00289 {
00290 int h=input.getHeight(), w=input.getWidth();
00291 int hk=kern.getHeight(), wk=kern.getWidth();
00292 int hk2=hk>>1, wk2=wk>>1;
00293
00294 if(!((hk & 1) && (wk & 1))) {
00295 ERROR("Structuring element must have odd size !")
00296 return;
00297 }
00298
00299 Image< T > tmp(input);
00300
00301 for(int i=0;i<h;i++)
00302 for(int j=0;j<w;j++) {
00303 int max=OFF;
00304 for(int k=0;k<hk;k++)
00305 for(int m=0;m<wk;m++) {
00306 int posx=i+k-hk2;
00307 int posy=j+m-wk2;
00308 if(RANGE(posx, posy, h, w)) {
00309 int val=input[posx][posy]+kern[k][m];
00310 if(val>max) max=val;
00311 }
00312 }
00313 tmp[i][j]=max;
00314 }
00315 output=tmp;
00316 }
00317
00318 template< class T >
00319 void Opening(Image< T > &input, ByteKernel &kern, Image< T > &output)
00320 {
00321 Erosion< T >(input, kern, output);
00322 Dilation< T >(output, kern, output);
00323 }
00324
00325 template< class T >
00326 void Closing(Image< T > &input, ByteKernel &kern, Image< T > &output)
00327 {
00328 Dilation< T >(input, kern, output);
00329 Erosion< T >(output, kern, output);
00330 }
00331
00332 template< class T >
00333 void TopHat(Image< T > &input, ByteKernel &kern, Image< T > &output)
00334 {
00335 Image< T > tmp(input);
00336
00337 Opening< T >(input, kern, output);
00338
00339 tmp-=output;
00340
00341 output = tmp;
00342 }
00343
00344 template< class T >
00345 void BottomHat(Image< T > &input, ByteKernel &kern, Image< T > &output)
00346 {
00347 Image< T > tmp(input);
00348
00349 Closing< T >(input, kern, output);
00350
00351 tmp-=output;
00352
00353 output = tmp;
00354 }
00355
00356 template< class T >
00357 void HitOrMiss(Image< T > &input, ByteKernel &kern1, ByteKernel &kern2, Image< T > &output)
00358 {
00359 Image< T > compl_in(input);
00360
00361 compl_in.clearImage(input.max());
00362 compl_in-=input;
00363
00364 FlatErosion(input, kern1, output);
00365 FlatErosion(compl_in, kern2, compl_in);
00366
00367
00368 for(int i=0;i<output.getSize();i++)
00369 output[0][i] &= compl_in[0][i];
00370 }
00371
00372 template< class T >
00373 void TemplateMatch(Image< T > &input, ByteKernel &kern, Image< T > &output)
00374 {
00375 ByteKernel compl_k(kern);
00376
00377 compl_k.clearImage(kern.max());
00378 compl_k-=kern;
00379
00380 HitOrMiss(input, kern, compl_k, output);
00381 }
00382
00383
00384
00385
00386