void mitk::PicFileReader::ConvertHandedness(mitkIpPicDescriptor* pic) { //left to right handed conversion if(pic->dim>=3) { mitkIpPicDescriptor* slice=mitkIpPicCopyHeader(pic, NULL); slice->dim=2; size_t size=_mitkIpPicSize(slice); slice->data=malloc(size); size_t v, volumes = (pic->dim>3? pic->n[3] : 1); size_t volume_size = size*pic->n[2]; for(v=0; v<volumes; ++v) { unsigned char *p_first=(unsigned char *)pic->data; unsigned char *p_last=(unsigned char *)pic->data; p_first+=v*volume_size; p_last+=size*(pic->n[2]-1)+v*volume_size; size_t i, smid=pic->n[2]/2; for(i=0; i<smid;++i,p_last-=size, p_first+=size) { memcpy(slice->data, p_last, size); memcpy(p_last, p_first, size); memcpy(p_first, slice->data, size); } } mitkIpPicFree(slice); } }
void mitk::PicFileReader::FillImage(Image::Pointer output) { mitkIpPicDescriptor *outputPic = mitkIpPicNew(); outputPic = CastToIpPicDescriptor(output, nullptr, outputPic); mitkIpPicDescriptor *pic = mitkIpPicGet(const_cast<char *>(this->GetLocalFileName().c_str()), outputPic); // comes upside-down (in MITK coordinates) from PIC file ConvertHandedness(pic); mitkIpPicTSV_t *tsv; if ((tsv = mitkIpPicQueryTag(pic, "SOURCE HEADER")) != NULL) { if (tsv->n[0] > 1e+06) { mitkIpPicTSV_t *tsvSH; tsvSH = mitkIpPicDelTag(pic, "SOURCE HEADER"); mitkIpPicFreeTag(tsvSH); } } if ((tsv = mitkIpPicQueryTag(pic, "ICON80x80")) != NULL) { mitkIpPicTSV_t *tsvSH; tsvSH = mitkIpPicDelTag(pic, "ICON80x80"); mitkIpPicFreeTag(tsvSH); } if ((tsv = mitkIpPicQueryTag(pic, "VELOCITY")) != NULL) { mitkIpPicDescriptor *header = mitkIpPicCopyHeader(pic, NULL); header->data = tsv->value; ConvertHandedness(header); output->SetChannel(header->data, 1); header->data = NULL; mitkIpPicFree(header); mitkIpPicDelTag(pic, "VELOCITY"); } // Copy the memory to avoid mismatches of malloc() and delete[]. // mitkIpPicGet will always allocate a new memory block with malloc(), // but MITK Images delete the data via delete[]. output->SetImportChannel(pic->data, 0, Image::CopyMemory); pic->data = nullptr; mitkIpPicFree(pic); }
mitkIpPicDescriptor *mitkIpFuncRank ( mitkIpPicDescriptor *pic_old, mitkIpUInt4_t rank, mitkIpUInt4_t mask_dim, mitkIpUInt4_t mask_size, mitkIpFuncFlagI_t border ) { mitkIpPicDescriptor *pic_new; /* pointer to transformed image */ mitkIpInt4_t i; /* loop index */ mitkIpInt4_t offset; /* offset of image */ mitkIpInt4_t ind[_mitkIpPicNDIM]; /* loop index vector */ mitkIpInt4_t *off_vekt; /* pointer to offset vector */ mitkIpInt4_t begin; /* 0.5 * mask_size */ mitkIpUInt4_t size[_mitkIpPicNDIM]; /* */ mitkIpInt4_t n[_mitkIpPicNDIM]; /* size of each dimension */ mitkIpUInt4_t no_elem; /* number of elements in mask */ mitkIpUInt4_t len; /* length of offset vector */ /* calculate number of elements in mask */ no_elem = mask_size; for ( i = 1; i < mask_dim; i++ ) no_elem = no_elem * mask_size; /* check whether data are correct */ if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); if ( mask_dim < 1 || mask_dim > pic_old->dim ) { _mitkIpFuncSetErrno ( mitkIpFuncDIMMASC_ERROR ); return ( mitkIpFuncERROR ); } if ( rank > no_elem ) { _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); return ( mitkIpFuncERROR ); } if ( mask_size % 2 != 1 ) { _mitkIpFuncSetErrno ( mitkIpFuncSIZE_ERROR ); return ( mitkIpFuncERROR ); } /* initialize vectors and variables */ size[0] = 1; for ( i = 1; i < _mitkIpPicNDIM; i++ ) size[i] = size[i-1] * pic_old->n[i-1]; len = 0; begin = mask_size / 2; for ( i = 0; i < mask_dim; i++ ) n[i] = begin + 1; for ( i = mask_dim; i < _mitkIpPicNDIM; i++ ) n[i] = 1 - begin; /* allocate image structure */ if ( border == mitkIpFuncBorderOld ) pic_new = mitkIpPicClone ( pic_old ); else if ( border == mitkIpFuncBorderZero ) { pic_new = mitkIpPicCopyHeader ( pic_old, 0 ); pic_new->data = calloc ( _mitkIpPicElements ( pic_new ), pic_new->bpe/8 ); } else { _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); return ( mitkIpFuncERROR ); } if ( pic_new == NULL ) { _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); return ( mitkIpFuncERROR ); } /* allocate offset vector */ off_vekt = malloc ( no_elem * sizeof ( mitkIpUInt4_t ) ); if ( off_vekt == NULL ) { _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); return ( mitkIpFuncERROR ); } /* calculate offset vector */ for ( ind[0] = -begin; ind[0] < n[0]; ind[0]++ ) for ( ind[7] = -begin; ind[7] < n[7]; ind[7]++ ) for ( ind[6] = -begin; ind[6] < n[6]; ind[6]++ ) for ( ind[5] = -begin; ind[5] < n[5]; ind[5]++ ) for ( ind[4] = -begin; ind[4] < n[4]; ind[4]++ ) for ( ind[3] = -begin; ind[3] < n[3]; ind[3]++ ) for ( ind[2] = -begin; ind[2] < n[2]; ind[2]++ ) for ( ind[1] = -begin; ind[1] < n[1]; ind[1]++ ) { offset = 0; for ( i = 0; i < pic_old->dim; i++ ) offset = offset + ind[i] * size[i]; off_vekt[len] = offset; len++; } if ( rank == 0 ) rank = no_elem / 2 + 1; mitkIpPicFORALL_4 ( RANK, pic_old, begin, no_elem, size, rank ); free ( off_vekt ); /* Copy Tags */ mitkIpFuncCopyTags(pic_new, pic_old); return ( pic_new ); }
void mitk::PicFileReader::GenerateData() { Image::Pointer output = this->GetOutput(); // Check to see if we can read the file given the name or prefix // if ( m_FileName == "" && m_FilePrefix == "" ) { throw itk::ImageFileReaderException(__FILE__, __LINE__, "One of FileName or FilePrefix must be non-empty"); } if( m_FileName != "") { mitkIpPicDescriptor* outputPic = mitkIpPicNew(); outputPic = CastToIpPicDescriptor(output, outputPic); mitkIpPicDescriptor* pic=MITKipPicGet(const_cast<char *>(m_FileName.c_str()), outputPic); // comes upside-down (in MITK coordinates) from PIC file ConvertHandedness(pic); mitkIpPicTSV_t *tsv; if ( (tsv = mitkIpPicQueryTag( pic, "SOURCE HEADER" )) != NULL) { if(tsv->n[0]>1e+06) { mitkIpPicTSV_t *tsvSH; tsvSH = mitkIpPicDelTag( pic, "SOURCE HEADER" ); mitkIpPicFreeTag(tsvSH); } } if ( (tsv = mitkIpPicQueryTag( pic, "ICON80x80" )) != NULL) { mitkIpPicTSV_t *tsvSH; tsvSH = mitkIpPicDelTag( pic, "ICON80x80" ); mitkIpPicFreeTag(tsvSH); } if ( (tsv = mitkIpPicQueryTag( pic, "VELOCITY" )) != NULL) { mitkIpPicDescriptor* header = mitkIpPicCopyHeader(pic, NULL); header->data = tsv->value; ConvertHandedness(header); output->SetChannel(header->data, 1); header->data = NULL; mitkIpPicFree(header); mitkIpPicDelTag( pic, "VELOCITY" ); } //slice-wise reading //currently much too slow. //else //{ // int sstart, smax; // int tstart, tmax; // sstart=output->GetRequestedRegion().GetIndex(2); // smax=sstart+output->GetRequestedRegion().GetSize(2); // tstart=output->GetRequestedRegion().GetIndex(3); // tmax=tstart+output->GetRequestedRegion().GetSize(3); // int s,t; // for(s=sstart; s<smax; ++s) // { // for(t=tstart; t<tmax; ++t) // { // mitkIpPicDescriptor* pic=mitkIpPicGetSlice(const_cast<char *>(m_FileName.c_str()), NULL, t*smax+s+1); // output->SetPicSlice(pic,s,t); // } // } //} } else { int position; mitkIpPicDescriptor* pic=NULL; int zDim=(output->GetDimension()>2?output->GetDimensions()[2]:1); printf("\n zdim is %u \n",zDim); for (position = 0; position < zDim; ++position) { char fullName[1024]; sprintf(fullName, m_FilePattern.c_str(), m_FilePrefix.c_str(), m_StartFileIndex+position); pic=MITKipPicGet(fullName, pic); if(pic==NULL) { itkDebugMacro("Pic file '" << fullName << "' does not exist."); } /* FIXME else if(output->SetPicSlice(pic, position)==false) { itkDebugMacro("Image '" << fullName << "' could not be added to Image."); }*/ } if(pic!=NULL) mitkIpPicFree(pic); } }
void mitk::CylindricToCartesianFilter::GenerateData() { mitk::Image::ConstPointer input = this->GetInput(); mitk::Image::Pointer output = this->GetOutput(); mitk::ImageTimeSelector::Pointer timeSelector=mitk::ImageTimeSelector::New(); timeSelector->SetInput(input); mitkIpPicDescriptor* pic_transformed=NULL; pic_transformed = mitkIpPicNew(); pic_transformed->dim=3; pic_transformed->bpe = output->GetPixelType().GetBpe(); //pic_transformed->type = output->GetPixelType().GetType(); pic_transformed->n[0] = output->GetDimension(0); pic_transformed->n[1] = output->GetDimension(1); pic_transformed->n[2] = output->GetDimension(2); pic_transformed->data=malloc(_mitkIpPicSize(pic_transformed)); int nstart, nmax; int tstart, tmax; tstart=output->GetRequestedRegion().GetIndex(3); nstart=output->GetRequestedRegion().GetIndex(4); tmax=tstart+output->GetRequestedRegion().GetSize(3); nmax=nstart+output->GetRequestedRegion().GetSize(4); if(zt==NULL) { timeSelector->SetChannelNr(nstart); timeSelector->SetTimeNr(tstart); buildTransformShortCuts(input->GetDimension(0),input->GetDimension(1), input->GetDimension(2), output->GetDimension(0), rt_pic, phit_pic, fr_pic, fphi_pic, zt, fz); // query the line limiting the sector a=b=0; mitk::FloatProperty::Pointer prop; prop = dynamic_cast<mitk::FloatProperty*>(input->GetProperty("SECTOR LIMITING LINE SLOPE").GetPointer()); if (prop.IsNotNull() ) a = prop->GetValue(); prop = dynamic_cast<mitk::FloatProperty*>(input->GetProperty("SECTOR LIMITING LINE OFFSET").GetPointer()); if (prop.IsNotNull() ) b = prop->GetValue(); buildConeCutOffShortCut(input->GetDimension(0),input->GetDimension(1), rt_pic, fr_pic, a, b, coneCutOff_pic); // mitkIpPicPut("C:\\temp\\rt_90.pic",rt_pic); //mitkIpPicPut("C:\\temp\\coneCutOff.pic", coneCutOff_pic); } int n,t; for(n=nstart;n<nmax;++n)//output->GetNumberOfChannels();++n) { timeSelector->SetChannelNr(n); for(t=tstart;t<tmax;++t) { timeSelector->SetTimeNr(t); timeSelector->Update(); // Cast to pic descriptor for the timeSelector image mitkIpPicDescriptor* timeSelectorPic = mitkIpPicNew(); CastToIpPicDescriptor( timeSelector->GetOutput(), timeSelectorPic ); _mitkIpPicFreeTags(pic_transformed->info->tags_head); pic_transformed->info->tags_head = _mitkIpPicCloneTags(timeSelectorPic->info->tags_head); if(input->GetDimension(2)>1) { mitkIpPicTypeMultiplex9(_transform, timeSelectorPic , pic_transformed, m_OutsideValue, (float*)fr_pic->data, (float*)fphi_pic->data, fz, (short *)rt_pic->data, (unsigned int *)phit_pic->data, zt, coneCutOff_pic); // mitkIpPicPut("1trf.pic",pic_transformed); } else { mitkIpPicDescriptor *doubleSlice = mitkIpPicCopyHeader( timeSelectorPic , NULL); doubleSlice->dim=3; doubleSlice->n[2]=2; doubleSlice->data=malloc(_mitkIpPicSize(doubleSlice)); memcpy(doubleSlice->data, timeSelectorPic->data, _mitkIpPicSize(doubleSlice)/2); mitkIpPicTypeMultiplex9(_transform, doubleSlice, pic_transformed, m_OutsideValue, (float*)fr_pic->data, (float*)fphi_pic->data, fz, (short *)rt_pic->data, (unsigned int *)phit_pic->data, zt, coneCutOff_pic); mitkIpPicFree(doubleSlice); } output->SetVolume(pic_transformed->data, t, n); } } //mitkIpPicPut("outzzzzzzzz.pic",pic_transformed); mitkIpPicFree(pic_transformed); m_TimeOfHeaderInitialization.Modified(); }
mitkIpPicDescriptor *mitkIpFuncScale ( mitkIpPicDescriptor *pic_old, mitkIpFloat8_t sc_fact[_mitkIpPicNDIM], mitkIpFuncFlagI_t sc_kind ) { mitkIpUInt4_t i; /* loop index */ mitkIpPicDescriptor *pic_new; /* pointer to scaled image */ char is_color=0; /* check whether data are correct */ if(pic_old->bpe==24) { pic_old->bpe=8; is_color=1; } if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); if(is_color) pic_old->bpe=24; /* allocate pic_new */ pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); if ( pic_new == NULL ) { _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); return ( mitkIpFuncERROR ); } /* copy scaling information to header of pic_new */ pic_new->dim = pic_old->dim; for ( i = 0; i < pic_old->dim; i++ ) pic_new->n[i] = ( sc_fact[i] == 0 ) ? pic_old->n[i] : ( mitkIpUInt4_t ) ( sc_fact[i] * pic_old->n[i] ); /* call scaling routines */ if ( sc_kind == mitkIpFuncScaleNN ) pic_new = _mitkIpFuncScNN ( pic_old, pic_new ); else if ( sc_kind == mitkIpFuncScaleBl ) { pic_new = _mitkIpFuncScBL ( pic_old, pic_new ); /*printf("using NN due to error in _mitkIpFuncScaleBL ... "); pic_new = _mitkIpFuncScNN ( pic_old, pic_new );*/ } else { mitkIpPicFree ( pic_new ); _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); return ( mitkIpFuncERROR ); } /* Copy Tags */ mitkIpFuncCopyTags(pic_new, pic_old); return( pic_new ); }
mitkIpPicDescriptor *mitkIpFuncSubC ( mitkIpPicDescriptor *pic_old, mitkIpFloat8_t value, mitkIpFuncFlagI_t keep, mitkIpPicDescriptor *pic_return ) { mitkIpPicDescriptor *pic_new; /* pointer to new image */ mitkIpFloat8_t max_gv; /* max. possible greyvalue */ mitkIpFloat8_t min_gv; /* min. possible greyvalue */ mitkIpFloat8_t min1, max1; /* extreme greyvalues of 1. image */ mitkIpFloat8_t smin, smax; /* product of extreme greyvalues */ /* check image data */ if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); /* check value */ if ( value == 0. ) return ( pic_old ); /* else if ( value == 0. ) { _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); return ( mitkIpFuncERROR ); } */ /* calculate max. and min. possible greyvalues for data type of images*/ if ( _mitkIpFuncExtT ( pic_old->type, pic_old->bpe, &min_gv, &max_gv ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); /* find out data type of new iamge */ if ( keep == mitkIpFuncKeep ) { pic_new = _mitkIpFuncMalloc ( pic_old, pic_return, mitkIpOVERWRITE ); if ( pic_new == NULL ) return ( mitkIpFuncERROR ); } else if ( keep == mitkIpFuncNoKeep ) { /* calculate max. and min. greyvalues of both images */ if ( mitkIpFuncExtr ( pic_old, &min1, &max1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); smax = max1 - value; smin = min1 - value; /* change image type of images of type mitkIpPicInt */ if ( pic_old->type == mitkIpPicInt ) { if ( smax < max_gv && smin > min_gv ) { pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); } else { pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); pic_new->type = mitkIpPicFloat; pic_new->bpe = 64; _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); } } /* change image type of images of type mitkIpPicUInt */ else if ( pic_old->type == mitkIpPicUInt ) { if ( smax < max_gv && smin > min_gv ) { pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); } else { pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); pic_new->type = mitkIpPicInt; pic_new->bpe = 16; _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); if ( smax > max_gv || smin < min_gv ) { pic_new->type = mitkIpPicFloat; pic_new->bpe = 64; _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); } } } /* change image type of images of type mitkIpPicUInt */ else if ( pic_old->type == mitkIpPicFloat ) { pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); } else { _mitkIpFuncSetErrno ( mitkIpFuncTYPE_ERROR ); return ( mitkIpFuncERROR ); } } else { _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); return ( mitkIpFuncERROR ); } if ( pic_new == NULL ) { _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); return ( mitkIpFuncERROR ); } if ( keep == mitkIpFuncNoKeep ) pic_new->data = malloc ( _mitkIpPicSize ( pic_new ) ); if ( pic_new->data == NULL ) { mitkIpPicFree ( pic_new ); _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); return ( mitkIpFuncERROR ); } /* macro to invert the picture (for all data types) */ if ( keep == mitkIpFuncNoKeep ) mitkIpPicFORALL_2 ( SUBC, pic_old, pic_new, value ) if ( keep == mitkIpFuncKeep ) mitkIpPicFORALL_2 ( SUBC3, pic_old, pic_new, value ) /* Copy Tags */ mitkIpFuncCopyTags(pic_new, pic_old); return pic_new; }
mitkIpPicDescriptor* ipMITKSegmentationCreateGrowerHistory( mitkIpPicDescriptor *seg, int startOfs, mitkIpPicDescriptor *histBuffer ) { std::queue<int> ofsQueue; if (!seg) return 0; if (!histBuffer) { histBuffer = mitkIpPicCopyHeader( seg, histBuffer ); histBuffer->type = mitkIpPicUInt; histBuffer->bpe = 16; mitkIpUInt4_t size = _mitkIpPicSize( histBuffer ); histBuffer->data = malloc( size ); memset( histBuffer->data, 0, size ); // clear buffer } else { // check if dimension of histBuffer is valid, if not: change it! if (histBuffer->n[0] != seg->n[0] || histBuffer->n[1] != seg->n[1]) { histBuffer->n[0] = seg->n[0]; histBuffer->n[1] = seg->n[1]; mitkIpUInt4_t size = _mitkIpPicSize( histBuffer ); histBuffer->data = realloc( histBuffer->data, size ); if (histBuffer->data == 0) return 0; memset( histBuffer->data, 0, size ); // clear buffer } } // create a clear buffer to check wether a point has already been visited // (seg cannot be modifier and histBuffer can contain any value) mitkIpPicDescriptor *flagBuffer = mitkIpPicCopyHeader( seg, 0 ); mitkIpUInt4_t size = _mitkIpPicSize( flagBuffer ); flagBuffer->data = malloc( size ); memset( flagBuffer->data, 0, size ); *((mitkIpUInt1_t*)flagBuffer->data+startOfs) = 1; // flag pixel as visited int line = seg->n[0]; int maxOfs = (int)(line * seg->n[1]); int testOfs; mitkIpUInt1_t segVal, flagVal; int iteration = 0; int currentWave = 1; int nextWave = 0; ofsQueue.push( startOfs ); while (!ofsQueue.empty()) { int nextOfs = ofsQueue.front(); ofsQueue.pop(); currentWave--; *((mitkIpUInt2_t*)histBuffer->data+nextOfs) = (mitkIpUInt2_t)(iteration+1); // seed point should get history = 1 // check right: testOfs = nextOfs+1; if (testOfs%line!=0) { segVal = *((mitkIpUInt1_t*)seg->data+testOfs); flagVal = *((mitkIpUInt1_t*)flagBuffer->data+testOfs); if ( segVal != 0 && flagVal == 0) { ofsQueue.push( testOfs ); *((mitkIpUInt1_t*)flagBuffer->data+testOfs) = 1; // flag pixel as visited nextWave++; } } // check top: testOfs = nextOfs-line; if (testOfs > 0) { segVal = *((mitkIpUInt1_t*)seg->data+testOfs); flagVal = *((mitkIpUInt1_t*)flagBuffer->data+testOfs); if ( segVal != 0 && flagVal == 0) { ofsQueue.push( testOfs ); *((mitkIpUInt1_t*)flagBuffer->data+testOfs) = 1; // flag pixel as visited nextWave++; } } // check left: testOfs = nextOfs-1; if (nextOfs%line!=0) { segVal = *((mitkIpUInt1_t*)seg->data+testOfs); flagVal = *((mitkIpUInt1_t*)flagBuffer->data+testOfs); if ( segVal != 0 && flagVal == 0) { ofsQueue.push( testOfs ); *((mitkIpUInt1_t*)flagBuffer->data+testOfs) = 1; // flag pixel as visited nextWave++; } } // check bottom: testOfs = nextOfs+line; if (testOfs < maxOfs) { segVal = *((mitkIpUInt1_t*)seg->data+testOfs); flagVal = *((mitkIpUInt1_t*)flagBuffer->data+testOfs); if ( segVal != 0 && flagVal == 0) { ofsQueue.push( testOfs ); *((mitkIpUInt1_t*)flagBuffer->data+testOfs) = 1; // flag pixel as visited nextWave++; } } // check for number of iterations: if (currentWave == 0) { currentWave = nextWave; nextWave = 0; iteration++; } } mitkIpPicFree( flagBuffer ); return histBuffer; }
mitkIpPicDescriptor* tmGrowRegion4N( mitkIpPicDescriptor *src, int startOfs, bool relativeBounds, float lowerBoundFlt, float upperBoundFlt, int maxIterations, mitkIpPicDescriptor *segBuffer, int &contourOfs, float &startCol, mitkIpPicDescriptor *histBuffer ) { PicType lowerBound = static_cast<PicType>(lowerBoundFlt); PicType upperBound = static_cast<PicType>(upperBoundFlt); std::queue<int> ofsQueue; if (maxIterations <= 0) maxIterations = 32000; if (!src) return 0; if (!segBuffer) { segBuffer = mitkIpPicCopyHeader( src, segBuffer ); segBuffer->type = mitkIpPicUInt; segBuffer->bpe = 8; mitkIpUInt4_t size = _mitkIpPicSize( segBuffer ); segBuffer->data = malloc( size ); } else { // check if dimension of segBuffer is valid, if not: change it! if (segBuffer->n[0] != src->n[0] || segBuffer->n[1] != src->n[1]) { segBuffer->n[0] = src->n[0]; segBuffer->n[1] = src->n[1]; mitkIpUInt4_t size = _mitkIpPicSize( segBuffer ); segBuffer->data = realloc( segBuffer->data, size ); if (segBuffer->data == 0) return 0; } } if (histBuffer) { // check if dimension of histBuffer is valid, if not: change it! if (histBuffer->n[0] != src->n[0] || histBuffer->n[1] != src->n[1]) { histBuffer->n[0] = src->n[0]; histBuffer->n[1] = src->n[1]; mitkIpUInt4_t size = _mitkIpPicSize( histBuffer ); histBuffer->data = realloc( histBuffer->data, size ); if (histBuffer->data == 0) return 0; memset( histBuffer->data, 0, size ); // clear buffer } } int line = segBuffer->n[0]; int maxOfs = (int)(line * segBuffer->n[1]); //PicType *start = ((PicType*)src->data) + startOfs; // init borders: PicType lowest, highest; if (relativeBounds) { // average base color from 3x3 block: // check for edges of image int offset; int numberOfValidOffsets = 0; int baseCol = 0; offset = startOfs; if ( (offset >= 0) && (offset < (int)(src->n[0] * src->n[1])) ) { baseCol += *((PicType*)(src->data)+offset); ++numberOfValidOffsets; } offset = startOfs+1; if ( (offset >= 0) && (offset < (int)(src->n[0] * src->n[1])) ) { baseCol += *((PicType*)(src->data)+offset); ++numberOfValidOffsets; } offset = startOfs+1-line; if ( (offset >= 0) && (offset < (int)(src->n[0] * src->n[1])) ) { baseCol += *((PicType*)(src->data)+offset); ++numberOfValidOffsets; } offset = startOfs-line; if ( (offset >= 0) && (offset < (int)(src->n[0] * src->n[1])) ) { baseCol += *((PicType*)(src->data)+offset); ++numberOfValidOffsets; } offset = startOfs-1-line; if ( (offset >= 0) && (offset < (int)(src->n[0] * src->n[1])) ) { baseCol += *((PicType*)(src->data)+offset); ++numberOfValidOffsets; } offset = startOfs-1; if ( (offset >= 0) && (offset < (int)(src->n[0] * src->n[1])) ) { baseCol += *((PicType*)(src->data)+offset); ++numberOfValidOffsets; } offset = startOfs-1+line; if ( (offset >= 0) && (offset < (int)(src->n[0] * src->n[1])) ) { baseCol += *((PicType*)(src->data)+offset); ++numberOfValidOffsets; } offset = startOfs+line; if ( (offset >= 0) && (offset < (int)(src->n[0] * src->n[1])) ) { baseCol += *((PicType*)(src->data)+offset); ++numberOfValidOffsets; } offset = startOfs+1+line; if ( (offset >= 0) && (offset < (int)(src->n[0] * src->n[1])) ) { baseCol += *((PicType*)(src->data)+offset); ++numberOfValidOffsets; } if ( numberOfValidOffsets > 0 ) baseCol = (PicType)( (float)baseCol / (float)numberOfValidOffsets ); lowest = baseCol - lowerBound; highest = baseCol + upperBound; startCol = (float)baseCol; } else { lowest = lowerBound; highest = upperBound; startCol = 0.0f; } memset( segBuffer->data, 0, _mitkIpPicSize(segBuffer) ); // clear buffer PicType value = *((PicType*)src->data+startOfs); if ( value >=lowest && value <=highest ) { ofsQueue.push( startOfs ); } contourOfs = -1; int testOfs; mitkIpUInt1_t segVal; int iteration = 0; int currentWave = 1; int nextWave = 0; while (!ofsQueue.empty() && iteration<=maxIterations) { int nextOfs = ofsQueue.front(); ofsQueue.pop(); currentWave--; *((mitkIpUInt1_t*)segBuffer->data+nextOfs) = 1; if (histBuffer) { *((mitkIpUInt2_t*)histBuffer->data+nextOfs) = (mitkIpUInt2_t)(iteration+1); // seed point should get history = 1 } if (nextOfs > contourOfs) contourOfs = nextOfs; // check right: testOfs = nextOfs+1; if (testOfs%line!=0) { segVal = *((mitkIpUInt1_t*)segBuffer->data+testOfs); if ( segVal == 0 ) { value = *((PicType*)src->data+testOfs); if ( value >=lowest && value <=highest ) { ofsQueue.push( testOfs ); nextWave++; *((mitkIpUInt1_t*)segBuffer->data+testOfs) = 2; } } } // check top: testOfs = nextOfs-line; if (testOfs > 0) { segVal = *((mitkIpUInt1_t*)segBuffer->data+testOfs); if ( segVal == 0 ) { value = *((PicType*)src->data+testOfs); if ( value >=lowest && value <=highest ) { ofsQueue.push( testOfs ); nextWave++; *((mitkIpUInt1_t*)segBuffer->data+testOfs) = 2; } } } // check left: testOfs = nextOfs-1; if (nextOfs%line!=0) { segVal = *((mitkIpUInt1_t*)segBuffer->data+testOfs); if ( segVal == 0 ) { value = *((PicType*)src->data+testOfs); if ( value >=lowest && value <=highest ) { ofsQueue.push( testOfs ); nextWave++; *((mitkIpUInt1_t*)segBuffer->data+testOfs) = 2; } } } // check bottom: testOfs = nextOfs+line; if (testOfs < maxOfs) { segVal = *((mitkIpUInt1_t*)segBuffer->data+testOfs); if ( segVal == 0 ) { value = *((PicType*)src->data+testOfs); if ( value >=lowest && value <=highest ) { ofsQueue.push( testOfs ); nextWave++; *((mitkIpUInt1_t*)segBuffer->data+testOfs) = 2; } } } // check for number of iterations: if (currentWave == 0) { currentWave = nextWave; nextWave = 0; iteration++; } } return segBuffer; }
mitkIpPicDescriptor *mitkIpFuncSubI ( mitkIpPicDescriptor *pic_1, mitkIpPicDescriptor *pic_2, mitkIpFuncFlagI_t keep, mitkIpPicDescriptor *pic_return ) { mitkIpPicDescriptor *pic_new; /* pointer to new image */ mitkIpUInt4_t i; /* loop index */ mitkIpFloat8_t max_gv; /* max. possible greyvalue */ mitkIpFloat8_t min_gv; /* min. possible greyvalue */ mitkIpFloat8_t min1, max1; /* extreme greyvalues of 1. image */ mitkIpFloat8_t min2, max2; /* extreme greyvalues of 2. image */ mitkIpFloat8_t smin, smax; /* product of extreme greyvalues */ /* ckeck whether data are correct */ if ( _mitkIpFuncError ( pic_1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); if ( _mitkIpFuncError ( pic_2 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); /* check whether images have the same size */ if ( ( pic_1->type != pic_2->type ) || ( pic_1->bpe != pic_2->bpe ) ) { _mitkIpFuncSetErrno ( mitkIpFuncUNFIT_ERROR ); return NULL; } if ( pic_1->dim == pic_2->dim ) for ( i = 0; i < _mitkIpPicNDIM; i++ ) { if ( pic_1->n[i] != pic_2->n[i] ) { _mitkIpFuncSetErrno ( mitkIpFuncUNFIT_ERROR ); return NULL; } } else { _mitkIpFuncSetErrno ( mitkIpFuncUNFIT_ERROR ); return NULL; } /* calculate max. and min. possible greyvalues for data type of images*/ if ( _mitkIpFuncExtT ( pic_1->type, pic_1->bpe, &min_gv, &max_gv ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); /* find out data type of new iamge */ if ( keep == mitkIpFuncKeep ) { pic_new = _mitkIpFuncMalloc ( pic_1, pic_return, mitkIpOVERWRITE ); if ( pic_new == NULL ) return ( mitkIpFuncERROR ); } else if ( keep == mitkIpFuncNoKeep ) { /* calculate max. and min. greyvalues of both images */ if ( mitkIpFuncExtr ( pic_1, &min1, &max1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); if ( mitkIpFuncExtr ( pic_2, &min2, &max2 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); smax = max1 - max2; smin = min1 - min2; /* change image type of images of type mitkIpPicInt */ if ( pic_1->type == mitkIpPicInt ) { if ( smax < max_gv && smin > min_gv ) { pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); } else { pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); pic_new->type = mitkIpPicFloat; pic_new->bpe = 64; _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); } } /* change image type of images of type mitkIpPicUInt */ else if ( pic_1->type == mitkIpPicUInt ) { if ( smax < max_gv && smin > min_gv ) { pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); } else { pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); pic_new->type = mitkIpPicInt; pic_new->bpe = 16; _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); if ( smax > max_gv || smin < min_gv ) { pic_new->type = mitkIpPicFloat; pic_new->bpe = 64; _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); } } } /* change image type of images of type mitkIpPicUInt */ else if ( pic_1->type == mitkIpPicFloat ) { pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); } else { _mitkIpFuncSetErrno ( mitkIpFuncTYPE_ERROR ); return ( mitkIpFuncERROR ); } } else { _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); return ( mitkIpFuncERROR ); } if ( pic_new == NULL ) { _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); return ( mitkIpFuncERROR ); } if ( keep == mitkIpFuncNoKeep ) pic_new->data = malloc ( _mitkIpPicSize ( pic_new ) ); if ( pic_new->data == NULL ) { mitkIpPicFree ( pic_new ); _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); return ( mitkIpFuncERROR ); } /* macro to invert the picture (for all data types) */ if ( keep == mitkIpFuncNoKeep ) mitkIpPicFORALL_2 ( SUBI, pic_1, pic_2, pic_new ) else if ( keep == mitkIpFuncKeep ) mitkIpPicFORALL_2 ( SUBI3, pic_1, pic_2, pic_new ) /* Copy Tags */ mitkIpFuncCopyTags(pic_new, pic_1); return pic_new; }