00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <assert.h>
00019 #include <queue>
00020 #include <ipPic/mitkIpPicTypeMultiplex.h>
00021 #include "ipSegmentation.h"
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 template<typename PicType>
00035 mitkIpPicDescriptor*
00036 tmGrowRegion4N( mitkIpPicDescriptor *src, int startOfs, bool relativeBounds, float lowerBoundFlt, float upperBoundFlt, int maxIterations, mitkIpPicDescriptor *segBuffer, int &contourOfs, float &startCol, mitkIpPicDescriptor *histBuffer )
00037 {
00038 PicType lowerBound = static_cast<PicType>(lowerBoundFlt);
00039 PicType upperBound = static_cast<PicType>(upperBoundFlt);
00040 std::queue<int> ofsQueue;
00041
00042 if (maxIterations <= 0) maxIterations = 32000;
00043 if (!src) return 0;
00044 if (!segBuffer) {
00045 segBuffer = mitkIpPicCopyHeader( src, segBuffer );
00046 segBuffer->type = mitkIpPicUInt;
00047 segBuffer->bpe = 8;
00048 mitkIpUInt4_t size = _mitkIpPicSize( segBuffer );
00049 segBuffer->data = malloc( size );
00050 }
00051 else {
00052
00053 if (segBuffer->n[0] != src->n[0] || segBuffer->n[1] != src->n[1]) {
00054 segBuffer->n[0] = src->n[0];
00055 segBuffer->n[1] = src->n[1];
00056 mitkIpUInt4_t size = _mitkIpPicSize( segBuffer );
00057 segBuffer->data = realloc( segBuffer->data, size );
00058 if (segBuffer->data == 0) return 0;
00059 }
00060 }
00061 if (histBuffer) {
00062
00063 if (histBuffer->n[0] != src->n[0] || histBuffer->n[1] != src->n[1]) {
00064 histBuffer->n[0] = src->n[0];
00065 histBuffer->n[1] = src->n[1];
00066 mitkIpUInt4_t size = _mitkIpPicSize( histBuffer );
00067 histBuffer->data = realloc( histBuffer->data, size );
00068 if (histBuffer->data == 0) return 0;
00069 memset( histBuffer->data, 0, size );
00070 }
00071 }
00072
00073 int line = segBuffer->n[0];
00074 int maxOfs = (int)(line * segBuffer->n[1]);
00075
00076
00077 PicType lowest, highest;
00078 if (relativeBounds) {
00079
00080
00081
00082 int offset;
00083 int numberOfValidOffsets = 0;
00084 int baseCol = 0;
00085 offset = startOfs; if ( (offset >= 0) && (offset < (int)(src->n[0] * src->n[1])) ) { baseCol += *((PicType*)(src->data)+offset); ++numberOfValidOffsets; }
00086 offset = startOfs+1; if ( (offset >= 0) && (offset < (int)(src->n[0] * src->n[1])) ) { baseCol += *((PicType*)(src->data)+offset); ++numberOfValidOffsets; }
00087 offset = startOfs+1-line; if ( (offset >= 0) && (offset < (int)(src->n[0] * src->n[1])) ) { baseCol += *((PicType*)(src->data)+offset); ++numberOfValidOffsets; }
00088 offset = startOfs-line; if ( (offset >= 0) && (offset < (int)(src->n[0] * src->n[1])) ) { baseCol += *((PicType*)(src->data)+offset); ++numberOfValidOffsets; }
00089 offset = startOfs-1-line; if ( (offset >= 0) && (offset < (int)(src->n[0] * src->n[1])) ) { baseCol += *((PicType*)(src->data)+offset); ++numberOfValidOffsets; }
00090 offset = startOfs-1; if ( (offset >= 0) && (offset < (int)(src->n[0] * src->n[1])) ) { baseCol += *((PicType*)(src->data)+offset); ++numberOfValidOffsets; }
00091 offset = startOfs-1+line; if ( (offset >= 0) && (offset < (int)(src->n[0] * src->n[1])) ) { baseCol += *((PicType*)(src->data)+offset); ++numberOfValidOffsets; }
00092 offset = startOfs+line; if ( (offset >= 0) && (offset < (int)(src->n[0] * src->n[1])) ) { baseCol += *((PicType*)(src->data)+offset); ++numberOfValidOffsets; }
00093 offset = startOfs+1+line; if ( (offset >= 0) && (offset < (int)(src->n[0] * src->n[1])) ) { baseCol += *((PicType*)(src->data)+offset); ++numberOfValidOffsets; }
00094
00095 if ( numberOfValidOffsets > 0 )
00096 baseCol = (PicType)( (float)baseCol / (float)numberOfValidOffsets );
00097
00098 lowest = baseCol - lowerBound;
00099 highest = baseCol + upperBound;
00100 startCol = (float)baseCol;
00101 }
00102 else {
00103 lowest = lowerBound;
00104 highest = upperBound;
00105 startCol = 0.0f;
00106 }
00107
00108 memset( segBuffer->data, 0, _mitkIpPicSize(segBuffer) );
00109
00110 PicType value = *((PicType*)src->data+startOfs);
00111 if ( value >=lowest && value <=highest ) {
00112 ofsQueue.push( startOfs );
00113 }
00114
00115 contourOfs = -1;
00116 int testOfs;
00117 mitkIpUInt1_t segVal;
00118 int iteration = 0;
00119 int currentWave = 1;
00120 int nextWave = 0;
00121
00122 while (!ofsQueue.empty() && iteration<=maxIterations) {
00123 int nextOfs = ofsQueue.front();
00124 ofsQueue.pop();
00125 currentWave--;
00126 *((mitkIpUInt1_t*)segBuffer->data+nextOfs) = 1;
00127 if (histBuffer) {
00128 *((mitkIpUInt2_t*)histBuffer->data+nextOfs) = (mitkIpUInt2_t)(iteration+1);
00129 }
00130 if (nextOfs > contourOfs) contourOfs = nextOfs;
00131
00132 testOfs = nextOfs+1;
00133 if (testOfs%line!=0) {
00134 segVal = *((mitkIpUInt1_t*)segBuffer->data+testOfs);
00135 if ( segVal == 0 ) {
00136 value = *((PicType*)src->data+testOfs);
00137 if ( value >=lowest && value <=highest ) {
00138 ofsQueue.push( testOfs );
00139 nextWave++;
00140 *((mitkIpUInt1_t*)segBuffer->data+testOfs) = 2;
00141 }
00142 }
00143 }
00144
00145 testOfs = nextOfs-line;
00146 if (testOfs > 0) {
00147 segVal = *((mitkIpUInt1_t*)segBuffer->data+testOfs);
00148 if ( segVal == 0 ) {
00149 value = *((PicType*)src->data+testOfs);
00150 if ( value >=lowest && value <=highest ) {
00151 ofsQueue.push( testOfs );
00152 nextWave++;
00153 *((mitkIpUInt1_t*)segBuffer->data+testOfs) = 2;
00154 }
00155 }
00156 }
00157
00158 testOfs = nextOfs-1;
00159 if (nextOfs%line!=0) {
00160 segVal = *((mitkIpUInt1_t*)segBuffer->data+testOfs);
00161 if ( segVal == 0 ) {
00162 value = *((PicType*)src->data+testOfs);
00163 if ( value >=lowest && value <=highest ) {
00164 ofsQueue.push( testOfs );
00165 nextWave++;
00166 *((mitkIpUInt1_t*)segBuffer->data+testOfs) = 2;
00167 }
00168 }
00169 }
00170
00171 testOfs = nextOfs+line;
00172 if (testOfs < maxOfs) {
00173 segVal = *((mitkIpUInt1_t*)segBuffer->data+testOfs);
00174 if ( segVal == 0 ) {
00175 value = *((PicType*)src->data+testOfs);
00176 if ( value >=lowest && value <=highest ) {
00177 ofsQueue.push( testOfs );
00178 nextWave++;
00179 *((mitkIpUInt1_t*)segBuffer->data+testOfs) = 2;
00180 }
00181 }
00182 }
00183
00184 if (currentWave == 0) {
00185 currentWave = nextWave;
00186 nextWave = 0;
00187 iteration++;
00188 }
00189 }
00190
00191 return segBuffer;
00192 }
00193
00194
00195 mitkIpPicDescriptor*
00196 ipMITKSegmentationGrowRegion4N( mitkIpPicDescriptor *src, int startOfs, bool relativeBounds, float lowerBound, float upperBound, int maxIterations, mitkIpPicDescriptor *segBuffer, mitkIpPicDescriptor *histBuffer )
00197 {
00198 mitkIpPicDescriptor *result = 0;
00199 int contourOfs;
00200 float startCol;
00201
00202 if (ipMITKSegmentationUndoIsEnabled (segBuffer)) {
00203 ipMITKSegmentationUndoSave (segBuffer);
00204 }
00205
00206 mitkIpPicTypeMultiplexR9( tmGrowRegion4N, src, result, startOfs, relativeBounds, lowerBound, upperBound, maxIterations, segBuffer, contourOfs, startCol, histBuffer );
00207 return result;
00208 }
00209
00210
00211
00212 mitkIpPicDescriptor*
00213 ipMITKSegmentationGrowRegion4N( mitkIpPicDescriptor *src, int startOfs, bool relativeBounds, float lowerBound, float upperBound, int maxIterations, mitkIpPicDescriptor *segBuffer, int &contourOfs, float &startCol, mitkIpPicDescriptor *histBuffer )
00214 {
00215 mitkIpPicDescriptor *result = 0;
00216
00217 if (ipMITKSegmentationUndoIsEnabled (segBuffer)) {
00218 ipMITKSegmentationUndoSave (segBuffer);
00219 }
00220
00221 mitkIpPicTypeMultiplexR9( tmGrowRegion4N, src, result, startOfs, relativeBounds, lowerBound, upperBound, maxIterations, segBuffer, contourOfs, startCol, histBuffer );
00222 return result;
00223 }