MorphOps.C
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef IMAGE_MORPHOPS_C_DEFINED
00039 #define IMAGE_MORPHOPS_C_DEFINED
00040
00041 #include "Image/MorphOps.H"
00042
00043 #include "Image/Image.H"
00044 #include "rutz/trace.h"
00045
00046
00047 template <class T>
00048 Image<T> dilateImg(const Image<T>& img, const Image<T>& se, Point2D<int> origin)
00049 {
00050 GVX_TRACE(__PRETTY_FUNCTION__);
00051 ASSERT(img.initialized() && se.initialized());
00052
00053 int iw = img.getWidth(); int ih = img.getHeight();
00054 int sw = se.getWidth(); int sh = se.getHeight();
00055
00056 if (origin == Point2D<int>(-1,-1))
00057 {
00058 origin.i = (sw - 1) / 2;
00059 origin.j = (sh - 1) / 2;
00060 }
00061 ASSERT((origin.i < sw) && (origin.j < sh));
00062
00063 Image<T> result(iw,ih,ZEROS);
00064
00065 typename Image<T>::const_iterator iptr, sptr1, sptr2;
00066 typename Image<T>::iterator rptr1, rptr2;
00067 iptr = img.begin();
00068
00069 for (int iy = 0; iy < ih; ++iy)
00070 {
00071
00072 int rYstart = iy - origin.j;
00073 int rYend = rYstart + sh;
00074 int sYstart = 0;
00075 if (rYstart < 0)
00076 {
00077 sYstart -= rYstart;
00078 rYstart = 0;
00079 }
00080 if (rYend > ih) rYend = ih;
00081
00082 for (int ix = 0; ix < iw; ++ix)
00083 {
00084
00085 if (*iptr != T())
00086 {
00087
00088 int rXstart = ix - origin.i;
00089 int rXend = rXstart + sw;
00090 int sXstart = 0;
00091 if (rXstart < 0)
00092 {
00093 sXstart -= rXstart;
00094 rXstart = 0;
00095 }
00096 if (rXend > iw) rXend = iw;
00097
00098 rptr1 = result.beginw() + rYstart * iw + rXstart;
00099 sptr1 = se.begin() + sYstart * sw + sXstart;
00100
00101 for (int ry = rYstart; ry < rYend; ++ry)
00102 {
00103 rptr2 = rptr1; sptr2 = sptr1;
00104 for (int rx = rXstart; rx < rXend; ++rx)
00105 {
00106 *rptr2 = std::max(*rptr2,*sptr2);
00107 ++rptr2; ++sptr2;
00108 }
00109 rptr1 += iw; sptr1 += sw;
00110 }
00111 }
00112 ++iptr;
00113 }
00114 }
00115 return result;
00116 }
00117
00118
00119 template <class T>
00120 Image<T> erodeImg(const Image<T>& img, const Image<T>& se, Point2D<int> origin)
00121 {
00122 GVX_TRACE(__PRETTY_FUNCTION__);
00123 ASSERT(img.initialized() && se.initialized());
00124
00125 int iw = img.getWidth(); int ih = img.getHeight();
00126 int sw = se.getWidth(); int sh = se.getHeight();
00127
00128 if (origin == Point2D<int>(-1,-1))
00129 {
00130 origin.i = (sw - 1) / 2;
00131 origin.j = (sh - 1) / 2;
00132 }
00133 ASSERT((origin.i < sw) && (origin.j < sh));
00134
00135 Image<T> result(iw,ih,ZEROS);
00136
00137 typename Image<T>::const_iterator iptr1, iptr2, sptr1, sptr2;
00138 typename Image<T>::iterator rptr = result.beginw();
00139 T se_orig_val = se.getVal(origin);
00140
00141
00142 for (int ry = 0; ry < ih; ++ry)
00143 {
00144
00145 int iYstart = ry - origin.j;
00146 int iYend = iYstart + sh;
00147 int sYstart = 0;
00148 if (iYstart < 0)
00149 {
00150 sYstart -= iYstart;
00151 iYstart = 0;
00152 }
00153 if (iYend > ih) iYend = ih;
00154
00155
00156
00157 for (int rx = 0; rx < iw; ++rx)
00158 {
00159 int iXstart = rx - origin.i;
00160 int iXend = iXstart + sw;
00161 int sXstart = 0;
00162 if (iXstart < 0)
00163 {
00164 sXstart -= iXstart;
00165 iXstart = 0;
00166 }
00167 if (iXend > iw) iXend = iw;
00168
00169 bool flag = true;
00170 iptr1 = img.begin() + iYstart * iw + iXstart;
00171 sptr1 = se.begin() + sYstart * sw + sXstart;
00172
00173
00174 for (int iy = iYstart; iy < iYend; ++iy)
00175 {
00176
00177 iptr2 = iptr1; sptr2 = sptr1;
00178 for (int ix = iXstart; ix < iXend; ++ ix)
00179 {
00180 if ((*sptr2 != 0) && (*iptr2 == 0))
00181 {
00182 flag = false;
00183 break;
00184 }
00185 ++iptr2; ++sptr2;
00186 }
00187
00188 if (!flag) break;
00189 iptr1 += iw; sptr1 += sw;
00190
00191 }
00192
00193
00194 if (flag) *rptr = std::max(*rptr, se_orig_val);
00195
00196 ++rptr;
00197
00198 }
00199 }
00200 return result;
00201 }
00202
00203
00204 template <class T>
00205 Image<T> openImg(const Image<T>& img, const Image<T>& se, Point2D<int> origin)
00206 {
00207 return dilateImg(erodeImg(img,se,origin),se,origin);
00208 }
00209
00210
00211 template <class T>
00212 Image<T> closeImg(const Image<T>& img, const Image<T>& se, Point2D<int> origin)
00213 {
00214 return erodeImg(dilateImg(img,se,origin),se,origin);
00215 }
00216
00217
00218 #include "inst/Image/MorphOps.I"
00219
00220
00221
00222
00223
00224
00225
00226
00227 #endif // IMAGE_MORPHOPS_C_DEFINED