00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <ipPic/mitkIpPicTypeMultiplex.h>
00019 #include "ipSegmentation.h"
00020
00021
00022
00023 namespace {
00024
00025
00026 #define SEGSET(ofs) ( \
00027 ((ofs)>=0 && (ofs)<maxOfs) && \
00028 ( *(((PicType*)seg->data) + (ofs)) != 0 ) && \
00029 ( (ofs)%line != 0 || (pos+1)%line != 0 ) && \
00030 ( (ofs+1)%line != 0 || (pos)%line != 0 ) \
00031 )
00032
00033
00034
00035
00036 #define ADD_CONTOUR_POINT \
00037 result[numPts*2] = xPos+xCorner[dir]; \
00038 result[numPts*2+1] = yPos+yCorner[dir]; \
00039 if (result[numPts*2]==result[0] && result[numPts*2+1]==result[1] && numPts>0) finished = true; \
00040 numPts++; \
00041 if (numPts==resSize) { \
00042 resSize+=16+resSize/2; \
00043 result = (float*)realloc( result, resSize*2*sizeof(float) ); \
00044 if (!result) finished = true; \
00045 }
00046
00047 }
00048
00049 template<typename PicType>
00050 float* tmGetContour4N( const mitkIpPicDescriptor *seg, int startOfs, int &numPts, int &resSize, float *result )
00051
00052
00053 {
00054 numPts = 0;
00055 int line = seg->n[0];
00056 int maxOfs = seg->n[0] * seg->n[1];
00057
00058 int straight[4] = { 1, -line, -1, line };
00059 int right[4] = { line, 1, -line, -1 };
00060 float xMod[4] = { 1.0, 0.0, -1.0, 0.0 };
00061 float yMod[4] = { 0.0, -1.0, 0.0, 1.0 };
00062 float xCorner[4] = { 1.0, 1.0, 0.0, 0.0 };
00063 float yCorner[4] = { 1.0, 0.0, 0.0, 1.0 };
00064
00065 int dir = 0;
00066 int pos = startOfs;
00067 float xPos = (float)(pos % line);
00068 float yPos = (float)(pos / line);
00069
00070 while ( dir<4 && SEGSET( pos+right[dir] ) ) dir++;
00071 if (dir==4) return result;
00072
00073 bool finished = false;
00074 if (result==0) {
00075 resSize = 2048;
00076 result = (float*)malloc( resSize*2*sizeof(float) );
00077 }
00078
00079 do {
00080 if ( SEGSET( pos+right[dir] ) ) {
00081
00082 dir = (dir-1) & 3;
00083
00084 pos += straight[dir];
00085 xPos += xMod[dir];
00086 yPos += yMod[dir];
00087 }
00088 else if ( SEGSET( pos+straight[dir] ) ) {
00089 ADD_CONTOUR_POINT
00090
00091 pos += straight[dir];
00092 xPos += xMod[dir];
00093 yPos += yMod[dir];
00094 }
00095 else {
00096 ADD_CONTOUR_POINT
00097
00098 dir = (dir+1) & 3;
00099 }
00100 } while (!finished);
00101 return result;
00102 }
00103
00104
00105 float* ipMITKSegmentationGetContour4N( const mitkIpPicDescriptor *seg, int startOfs, int &numPoints, int &sizeBuffer, float *pointBuffer )
00106 {
00107 float *newBuffer = NULL;
00108 mitkIpPicTypeMultiplexR4( tmGetContour4N, seg, newBuffer, startOfs, numPoints, sizeBuffer, pointBuffer );
00109 return newBuffer;
00110 }
00111
00112
00113 template<typename PicType>
00114 float* tmGetContour8N( const mitkIpPicDescriptor *seg, int startOfs, int &numPts, int &resSize, float *result )
00115
00116
00117 {
00118 numPts = 0;
00119 int line = seg->n[0];
00120 int maxOfs = seg->n[0] * seg->n[1];
00121
00122 int straight[4] = { 1, -line, -1, line };
00123 int right[4] = { line, 1, -line, -1 };
00124 float xMod[4] = { 1.0, 0.0, -1.0, 0.0 };
00125 float yMod[4] = { 0.0, -1.0, 0.0, 1.0 };
00126 float xCorner[4] = { 1.0, 1.0, 0.0, 0.0 };
00127 float yCorner[4] = { 1.0, 0.0, 0.0, 1.0 };
00128
00129 int dir = 0;
00130 int pos = startOfs;
00131 float xPos = (float)(pos % line);
00132 float yPos = (float)(pos / line);
00133
00134 while ( dir<4 && SEGSET( pos+right[dir] ) ) dir++;
00135 if (dir==4) {
00136
00137 dir = 0;
00138 while ( dir<4 && SEGSET( pos+right[dir]+straight[dir] ) ) dir++;
00139 if (dir==4) return result;
00140
00141 pos += straight[dir];
00142 xPos += xMod[dir];
00143 yPos += yMod[dir];
00144 }
00145
00146 bool finished = false;
00147 if (result==0) {
00148 resSize = 2048;
00149 result = (float*)malloc( resSize*2*sizeof(float) );
00150 }
00151
00152
00153
00154
00155 do {
00156 if ( SEGSET( pos+right[dir] ) ) {
00157
00158 dir = (dir-1) & 3;
00159
00160 pos += straight[dir];
00161 xPos += xMod[dir];
00162 yPos += yMod[dir];
00163 }
00164 else if ( SEGSET( pos+straight[dir] ) ) {
00165 ADD_CONTOUR_POINT
00166
00167 pos += straight[dir];
00168 xPos += xMod[dir];
00169 yPos += yMod[dir];
00170 }
00171 else if ( SEGSET( pos+right[dir]+straight[dir] ) ) {
00172 ADD_CONTOUR_POINT
00173
00174 pos += straight[dir];
00175 xPos += xMod[dir];
00176 yPos += yMod[dir];
00177
00178 dir = (dir-1) & 3;
00179
00180 pos += straight[dir];
00181 xPos += xMod[dir];
00182 yPos += yMod[dir];
00183 }
00184 else {
00185 ADD_CONTOUR_POINT
00186
00187 dir = (dir+1) & 3;
00188 }
00189 } while (!finished);
00190 return result;
00191 }
00192
00193
00194 float* ipMITKSegmentationGetContour8N( const mitkIpPicDescriptor *seg, int startOfs, int &numPoints, int &sizeBuffer, float *pointBuffer )
00195 {
00196 float *newBuffer = NULL;
00197 mitkIpPicTypeMultiplexR4( tmGetContour8N, seg, newBuffer, startOfs, numPoints, sizeBuffer, pointBuffer );
00198 return newBuffer;
00199 }