void ToFPicImageWriter::Open() { this->CheckForFileExtension(this->m_DistanceImageFileName); this->CheckForFileExtension(this->m_AmplitudeImageFileName); this->CheckForFileExtension(this->m_IntensityImageFileName); this->m_PixelNumber = this->m_CaptureWidth * this->m_CaptureHeight; this->m_ImageSizeInBytes = this->m_PixelNumber * sizeof(float); float* floatData = new float[this->m_PixelNumber]; for(int i=0; i<this->m_PixelNumber; i++) { floatData[i] = i + 0.0; } this->m_MitkImage = Image::New(); unsigned int dimensions[4]; dimensions[0] = this->m_CaptureWidth; dimensions[1] = this->m_CaptureHeight; mitk::PixelType FloatType = MakeScalarPixelType<float>(); if (this->m_ToFImageType == ToFImageWriter::ToFImageType2DPlusT) { dimensions[2] = 1; dimensions[3] = 2; this->m_MitkImage->Initialize( FloatType, 4, dimensions, 1); } else { dimensions[2] = 2; dimensions[3] = 1; this->m_MitkImage->Initialize( FloatType, 3, dimensions, 1); } this->m_MitkImage->SetSlice(floatData, 0, 0, 0); mitkIpPicDescriptor* pic = mitkIpPicNew(); CastToIpPicDescriptor( this->m_MitkImage, pic); if (this->m_DistanceImageSelected) { this->OpenPicFile(&(this->m_DistanceOutfile), this->m_DistanceImageFileName); this->WritePicFileHeader(this->m_DistanceOutfile, pic); } if (this->m_AmplitudeImageSelected) { this->OpenPicFile(&(this->m_AmplitudeOutfile), this->m_AmplitudeImageFileName); this->WritePicFileHeader(this->m_AmplitudeOutfile, pic); } if (this->m_IntensityImageSelected) { this->OpenPicFile(&(this->m_IntensityOutfile), this->m_IntensityImageFileName); this->WritePicFileHeader(this->m_IntensityOutfile, pic); } this->m_NumOfFrames = 0; delete[] floatData; }
void mitk::ContourUtils::FillContourInSlice( ContourModel* projectedContour, unsigned int timeStep, Image* sliceImage, int paintingPixelValue ) { // 1. Use ipSegmentation to draw a filled(!) contour into a new 8 bit 2D image, which will later be copied back to the slice. // We don't work on the "real" working data, because ipSegmentation would restrict us to 8 bit images // convert the projected contour into a ipSegmentation format mitkIpInt4_t* picContour = new mitkIpInt4_t[2 * projectedContour->GetNumberOfVertices(timeStep)]; unsigned int index(0); ContourModel::VertexIterator iter = projectedContour->Begin(timeStep); ContourModel::VertexIterator end = projectedContour->End(timeStep); while( iter != end) { picContour[ 2 * index + 0 ] = static_cast<mitkIpInt4_t>( (*iter)->Coordinates[0] + 1.0 ); // +0.5 wahrscheinlich richtiger picContour[ 2 * index + 1 ] = static_cast<mitkIpInt4_t>( (*iter)->Coordinates[1] + 1.0 ); //MITK_INFO << "mitk 2d [" << (*iter)[0] << ", " << (*iter)[1] << "] pic [" << picContour[ 2*index+0] << ", " << picContour[ 2*index+1] << "]"; iter++; index++; } assert( sliceImage->GetSliceData() ); mitkIpPicDescriptor* originalPicSlice = mitkIpPicNew(); CastToIpPicDescriptor( sliceImage, originalPicSlice); mitkIpPicDescriptor* picSlice = ipMITKSegmentationNew( originalPicSlice ); ipMITKSegmentationClear( picSlice ); assert( originalPicSlice && picSlice ); // here comes the actual contour filling algorithm (from ipSegmentation/Graphics Gems) ipMITKSegmentationCombineRegion ( picSlice, picContour, projectedContour->GetNumberOfVertices(timeStep), NULL, IPSEGMENTATION_OR, 1); // set to 1 delete[] picContour; // 2. Copy the filled contour to the working data slice // copy all pixels that are non-zero to the original image (not caring for the actual type of the working image). perhaps make the replace value a parameter ( -> general painting tool ). // make the pic slice an mitk/itk image (as little ipPic code as possible), call a templated method with accessbyitk, iterate over the original and the modified slice Image::Pointer ipsegmentationModifiedSlice = Image::New(); ipsegmentationModifiedSlice->Initialize( CastToImageDescriptor( picSlice ) ); ipsegmentationModifiedSlice->SetSlice( picSlice->data ); AccessFixedDimensionByItk_2( sliceImage, ItkCopyFilledContourToSlice, 2, ipsegmentationModifiedSlice, paintingPixelValue ); ipsegmentationModifiedSlice = NULL; // free MITK header information ipMITKSegmentationFree( picSlice ); // free actual memory }
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); }
void ToFPicImageWriter::ReplacePicFileHeader(FILE* outfile) { mitkIpPicDescriptor* pic = mitkIpPicNew(); CastToIpPicDescriptor( this->m_MitkImage, pic); if (this->m_ToFImageType == ToFImageWriter::ToFImageType2DPlusT) { pic->dim = 4; pic->n[2] = 1; pic->n[3] = this->m_NumOfFrames; } else { pic->dim = 3; pic->n[2] = this->m_NumOfFrames; pic->n[3] = 1; } fseek ( outfile, 0, SEEK_SET ); this->WritePicFileHeader( outfile, pic ); }
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(); }
/** 1 Determine which slice is clicked into 2 Determine if the user clicked inside or outside of the segmentation 3 Depending on the pixel value under the mouse click position, two different things happen: (separated out into OnMousePressedInside and OnMousePressedOutside) 3.1 Create a skeletonization of the segmentation and try to find a nice cut 3.1.1 Call a ipSegmentation algorithm to create a nice cut 3.1.2 Set the result of this algorithm as the feedback contour 3.2 Initialize region growing 3.2.1 Determine memory offset inside the original image 3.2.2 Determine initial region growing parameters from the level window settings of the image 3.2.3 Perform a region growing (which generates a new feedback contour) */ bool mitk::RegionGrowingTool::OnMousePressed ( StateMachineAction*, InteractionEvent* interactionEvent ) { mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent ); //const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent()); if (!positionEvent) return false; m_LastEventSender = positionEvent->GetSender(); m_LastEventSlice = m_LastEventSender->GetSlice(); //ToolLogger::SetVerboseness(3); MITK_DEBUG << "OnMousePressed" << std::endl; if ( FeedbackContourTool::CanHandleEvent(interactionEvent) > 0.0 ) { MITK_DEBUG << "OnMousePressed: FeedbackContourTool says ok" << std::endl; // 1. Find out which slice the user clicked, find out which slice of the toolmanager's reference and working image corresponds to that if (positionEvent) { MITK_DEBUG << "OnMousePressed: got positionEvent" << std::endl; m_ReferenceSlice = FeedbackContourTool::GetAffectedReferenceSlice( positionEvent ); m_WorkingSlice = FeedbackContourTool::GetAffectedWorkingSlice( positionEvent ); if ( m_WorkingSlice.IsNotNull() ) // can't do anything without the segmentation { MITK_DEBUG << "OnMousePressed: got working slice" << std::endl; // 2. Determine if the user clicked inside or outside of the segmentation const Geometry3D* workingSliceGeometry = m_WorkingSlice->GetGeometry(); Point3D mprojectedPointIn2D; workingSliceGeometry->WorldToIndex( positionEvent->GetPositionInWorld(), mprojectedPointIn2D); itk::Index<2> projectedPointInWorkingSlice2D; projectedPointInWorkingSlice2D[0] = static_cast<int>( mprojectedPointIn2D[0] - 0.5 ); projectedPointInWorkingSlice2D[1] = static_cast<int>( mprojectedPointIn2D[1] - 0.5 ); if ( workingSliceGeometry->IsIndexInside( projectedPointInWorkingSlice2D ) ) { MITK_DEBUG << "OnMousePressed: point " << positionEvent->GetPositionInWorld() << " (index coordinates " << projectedPointInWorkingSlice2D << ") IS in working slice" << std::endl; // Convert to ipMITKSegmentationTYPE (because getting pixels relys on that data type) itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer correctPixelTypeImage; CastToItkImage( m_WorkingSlice, correctPixelTypeImage ); assert (correctPixelTypeImage.IsNotNull() ); // possible bug in CastToItkImage ? // direction maxtrix is wrong/broken/not working after CastToItkImage, leading to a failed assertion in // mitk/Core/DataStructures/mitkSlicedGeometry3D.cpp, 479: // virtual void mitk::SlicedGeometry3D::SetSpacing(const mitk::Vector3D&): Assertion `aSpacing[0]>0 && aSpacing[1]>0 && aSpacing[2]>0' failed // solution here: we overwrite it with an unity matrix itk::Image< ipMITKSegmentationTYPE, 2 >::DirectionType imageDirection; imageDirection.SetIdentity(); correctPixelTypeImage->SetDirection(imageDirection); Image::Pointer temporarySlice = Image::New(); // temporarySlice = ImportItkImage( correctPixelTypeImage ); CastToMitkImage( correctPixelTypeImage, temporarySlice ); mitkIpPicDescriptor* workingPicSlice = mitkIpPicNew(); CastToIpPicDescriptor(temporarySlice, workingPicSlice); int initialWorkingOffset = projectedPointInWorkingSlice2D[1] * workingPicSlice->n[0] + projectedPointInWorkingSlice2D[0]; if ( initialWorkingOffset < static_cast<int>( workingPicSlice->n[0] * workingPicSlice->n[1] ) && initialWorkingOffset >= 0 ) { // 3. determine the pixel value under the last click bool inside = static_cast<ipMITKSegmentationTYPE*>(workingPicSlice->data)[initialWorkingOffset] != 0; m_PaintingPixelValue = inside ? 0 : 1; // if inside, we want to remove a part, otherwise we want to add something if ( m_LastWorkingSeed >= static_cast<int>( workingPicSlice->n[0] * workingPicSlice->n[1] ) || m_LastWorkingSeed < 0 ) { inside = false; } if ( m_ReferenceSlice.IsNotNull() ) { MITK_DEBUG << "OnMousePressed: got reference slice" << std::endl; m_OriginalPicSlice = mitkIpPicNew(); CastToIpPicDescriptor(m_ReferenceSlice, m_OriginalPicSlice); // 3.1. Switch depending on the pixel value if (inside) { OnMousePressedInside( NULL, interactionEvent, workingPicSlice, initialWorkingOffset); } else { OnMousePressedOutside( NULL, interactionEvent); } } } } } } } MITK_DEBUG << "end OnMousePressed" << std::endl; return true; }
void mitk::DopplerToStrainRateFilter::GenerateData() { mitk::Image::ConstPointer input = this->GetInput(); mitk::Image::Pointer output = this->GetOutput(); mitk::Point3iProperty::Pointer pointProp; pointProp = dynamic_cast<mitk::Point3iProperty*>(input->GetProperty("ORIGIN").GetPointer()); if (pointProp.IsNotNull() ) { m_Origin = pointProp->GetValue(); } MITK_INFO << "compute Strain Rate Image .... " << std::endl << " origin[0]=" << m_Origin[0] << " origin[1]=" << m_Origin[1] << " origin[2]=" << m_Origin[2] << std::endl << " distance=" << m_Distance << std::endl << " NoStrainIntervall=" << m_NoStrainInterval << std::endl; const Vector3D & spacing = input->GetSlicedGeometry()->GetSpacing(); // MITK_INFO << " in: xres=" << spacing[0] << " yres=" << spacing[1] << " zres=" << spacing[2] << std::endl; mitk::ImageTimeSelector::Pointer timeSelector=mitk::ImageTimeSelector::New(); timeSelector->SetInput(input); mitkIpPicDescriptor* picStrainRate; picStrainRate = mitkIpPicNew(); picStrainRate->dim=3; picStrainRate->bpe = output->GetPixelType().GetBpe(); //picStrainRate->type = output->GetPixelType().GetType(); picStrainRate->n[0] = output->GetDimension(0); picStrainRate->n[1] = output->GetDimension(1); picStrainRate->n[2] = output->GetDimension(2); picStrainRate->data=malloc(_mitkIpPicSize(picStrainRate)); int xDim = picStrainRate->n[0]; int yDim = picStrainRate->n[1]; int zDim = picStrainRate->n[2]; long slice_size = xDim*yDim; long vol_size = slice_size*zDim; mitkIpPicDescriptor *picDoppler; int x,y,z;//,time; // loop-counter int strainRate; // the computed Strain Rate int v1,v2; // velocity and Point p1 and p2 float alpha; // the beam-angle, angle betwen current point and beam-point float dx=0, dy=0; // projection of this->distance to x- and y-axis int x1; // a square, where the velocity v1 lies in int y1; // the points are used for interpolation int minStrainRate=128, maxStrainRate=128; int n, nmax; int t, tmax; t = output->GetRequestedRegion().GetIndex(3); n = output->GetRequestedRegion().GetIndex(4); MITK_INFO << "t = " <<t << " n = " << n << std::endl; tmax = t + output->GetRequestedRegion().GetSize(3); nmax = n + output->GetRequestedRegion().GetSize(4); MITK_INFO << "tmax = "<< tmax << " nmax = " << nmax << std::endl; if (m_Distance<1) m_Distance=1; for(;n<nmax;n++)//output->GetNumberOfChannels();++n) { timeSelector->SetChannelNr(n); MITK_INFO << "computing chanel n = " << n << std::endl; for(t=0;t<tmax;t++) { MITK_INFO << "computing time slot t = " << t << std::endl; timeSelector->SetTimeNr(t); timeSelector->Update(); // Cast to pic descriptor for the timeSelector image mitkIpPicDescriptor* timeSelectorPic = mitkIpPicNew(); CastToIpPicDescriptor( timeSelector->GetOutput(), timeSelectorPic ); _mitkIpPicFreeTags(picStrainRate->info->tags_head); picStrainRate->info->tags_head = _mitkIpPicCloneTags(timeSelectorPic->info->tags_head); //#define WRITE_ANGLE_PIC #ifdef WRITE_ANGLE_PIC mitkIpPicDescriptor *anglePic; mitkIpBool_t isAnglePicWritten = mitkIpFalse; anglePic = mitkIpPicNew(); anglePic->type = mitkIpPicInt; anglePic->bpe = 8; anglePic->dim = 2; anglePic->n[0] = xDim; anglePic->n[1] = yDim; anglePic->data = (mitkIpInt1_t *)calloc(xDim*yDim,sizeof(mitkIpInt1_t)); #endif picDoppler = timeSelectorPic; picDoppler = mitkIpFuncGausF( picDoppler, 5,2 , mitkIpFuncBorderOld ) ; for (z=0 ; z<zDim ; z++) { for (y=1; y<yDim; y++) { if (y<m_Origin[1]) continue; // cannot compute StrainRate above Transducer-Position for (x=0; x<xDim; x++) { if ((m_Origin[0] - x)==0) { // winkelhalbierende int yDistanceInUnits = (int)( m_Distance/spacing[1]); int yTmp = ( (y-yDistanceInUnits)<0 ) ? 0 : (y-yDistanceInUnits); v1 = ((mitkIpUInt1_t *)picDoppler->data)[z*slice_size + yTmp*xDim + x] ; v2 = ((mitkIpUInt1_t *)picDoppler->data)[z*slice_size + y*xDim + x] ; } else { // compute angle to transducer position // m_Origin is given in units, not in mm alpha = atan( (float) (m_Origin[0] - x) / (float) (m_Origin[1] - y) ); // m_Distance is given in mm dx = -sin(alpha) * m_Distance; dy = -cos(alpha) * m_Distance; // convert to units dx = dx/spacing[0]; dy = dy/spacing[1]; //#define WEIGTHED #ifdef WEIGTHED weightX = dx - floor(dx); weightY = dy - floor(dy); dxFloor = (int) floor(dx); dyFloor = (int) floor(dy); x1 = x + dxFloor; // lower left y1 = y + dyFloor; x2 = x + (dxFloor+1); // lower right y2 = y + dyFloor; x3 = x + (dxFloor+1); // upper right y3 = y + (dyFloor+1); x4 = x + dxFloor; // upper left y4 = y + (dyFloor+1); vTmp1 = ((mitkIpUInt1_t *)picDoppler->data)[z*slice_size + y1*xDim + x1]; vTmp2 = ((mitkIpUInt1_t *)picDoppler->data)[z*slice_size + y2*xDim + x2]; vTmp3 = ((mitkIpUInt1_t *)picDoppler->data)[z*slice_size + y3*xDim + x3]; vTmp4 = ((mitkIpUInt1_t *)picDoppler->data)[z*slice_size + y4*xDim + x4]; v1 = (int) ((1-weightX)*(1-weightY)*vTmp1 + weightX*(1-weightY)*vTmp2 + weightX*weightY*vTmp3 + (1-weightX)*weightY*vTmp4); v2 = ((mitkIpUInt1_t *)picDoppler->data)[z*slice_size + y*xDim + x] ; #else x1 = (int)(x + dx); y1 = (int)(y + dy); if (y1<0) y1=0; #endif v1 = ((mitkIpUInt1_t *)picDoppler->data)[z*slice_size + y1*xDim + x1]; v2 = ((mitkIpUInt1_t *)picDoppler->data)[z*slice_size + y*xDim + x] ; } if (v1==128) { // schaue in Gegenrichtung, falls keine SRI hier berechenbar x1 = (int)(x - dx); y1 = (int)(y - dy); if (y1>yDim) y1=yDim; //swap v1 and v2, otherwise StrainRate is calculate in false direction v1 = v2; v2 = ((mitkIpUInt1_t *)picDoppler->data)[z*slice_size + y1*xDim + x1]; } if ( (v1==0 ) || (v2==0) || // wenn keine Geschwindigkeit vorhanden // oder wenn nur ganz kleine Geschwindigkeit vorhanden (v1>=(128-m_NoStrainInterval) && v1<=(128+m_NoStrainInterval)) || (v2>=(128-m_NoStrainInterval) && v2<=(128+m_NoStrainInterval))) { strainRate = 128; // this means no deformation // this is neccessay due to the Cyl2Cart filter } else { strainRate = (int)( (v1 - v2)/2 + 128 ); if (strainRate==128) strainRate=129; } if (strainRate < minStrainRate && strainRate > 0 ) minStrainRate = strainRate; if (strainRate > maxStrainRate) maxStrainRate = strainRate; if (strainRate<0 ) { //strainRate = -strainRate; MITK_INFO << " error: neg. strainRate ... exit() " << std::endl << " x=" << x << " y=" << y << " z=" << z << std::endl << " v1=" << v1 << " v2=" << v2 << " dist=" << m_Distance << std::endl << " sr=" << strainRate << std::endl; exit(0); } ((mitkIpUInt1_t *)picStrainRate->data)[t*vol_size + z*slice_size + y*xDim + x]=strainRate; // cout << "z: " << z << " y: " << y << " x: " << x << " strainrate: " << strainRate << endl; #ifdef WRITE_ANGLE_PIC // if (!isAnglePicWritten) // ((mitkIpInt1_t *)anglePic->data)[y*xDim + x] = (int) ( (alpha/1.6)*128); if (!isAnglePicWritten) ((mitkIpInt1_t *)anglePic->data)[y*xDim + x] = (int) ( dx); #endif } // x } // y //isAnglePicWritten = mitkIpTrue; } // z //isStrainComputed = mitkIpTrue; std::string filenameD; filenameD ="doppler.pic"; mitkIpPicPut(const_cast<char *>(filenameD.c_str()),picDoppler); #define WRITE_STRAIN_PIC #ifdef WRITE_STRAIN_PIC char tmpfilename[100]; sprintf(tmpfilename,"strain%d.pic",t);; mitkIpPicPut(tmpfilename,picStrainRate); #endif #ifdef WRITE_ANGLE_PIC std::string filename2; filename2="angle.pic"; mitkIpPicPut(const_cast<char *>(filename2.c_str()),anglePic); #endif ((mitkIpUInt1_t *)picStrainRate->data)[0]=0; ((mitkIpUInt1_t *)picStrainRate->data)[1]=255; output->SetVolume(picStrainRate->data, t, n); } } mitkIpPicFree(picStrainRate); #define WRITE_STRAIN_PIC #ifdef WRITE_STRAIN_PIC // Get the StrainRate ipPic descriptor picStrainRate = mitkIpPicNew(); CastToIpPicDescriptor( output, picStrainRate ); std::string filename; filename ="strain.pic"; mitkIpPicPut(const_cast<char *>(filename.c_str()),picStrainRate); #endif MITK_INFO << "Strain Rate Image computed.... " << std::endl << " minStrainRate: " << minStrainRate << std::endl << " maxStrainRate: " << maxStrainRate << std::endl; }
bool mitk::SetRegionTool::OnMousePressed ( StateMachineAction*, InteractionEvent* interactionEvent ) { mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent ); //const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent()); if (!positionEvent) return false; m_LastEventSender = positionEvent->GetSender(); m_LastEventSlice = m_LastEventSender->GetSlice(); int timeStep = positionEvent->GetSender()->GetTimeStep(); // 1. Get the working image Image::Pointer workingSlice = FeedbackContourTool::GetAffectedWorkingSlice( positionEvent ); if ( workingSlice.IsNull() ) return false; // can't do anything without the segmentation // if click was outside the image, don't continue const BaseGeometry* sliceGeometry = workingSlice->GetGeometry(); itk::Index<2> projectedPointIn2D; sliceGeometry->WorldToIndex( positionEvent->GetPositionInWorld(), projectedPointIn2D ); if ( !sliceGeometry->IsIndexInside( projectedPointIn2D ) ) { MITK_ERROR << "point apparently not inside segmentation slice" << std::endl; return false; // can't use that as a seed point } // Convert to ipMITKSegmentationTYPE (because ipMITKSegmentationGetContour8N relys on that data type) itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer correctPixelTypeImage; CastToItkImage( workingSlice, correctPixelTypeImage ); assert (correctPixelTypeImage.IsNotNull() ); // possible bug in CastToItkImage ? // direction maxtrix is wrong/broken/not working after CastToItkImage, leading to a failed assertion in // mitk/Core/DataStructures/mitkSlicedGeometry3D.cpp, 479: // virtual void mitk::SlicedGeometry3D::SetSpacing(const mitk::Vector3D&): Assertion `aSpacing[0]>0 && aSpacing[1]>0 && aSpacing[2]>0' failed // solution here: we overwrite it with an unity matrix itk::Image< ipMITKSegmentationTYPE, 2 >::DirectionType imageDirection; imageDirection.SetIdentity(); correctPixelTypeImage->SetDirection(imageDirection); Image::Pointer temporarySlice = Image::New(); // temporarySlice = ImportItkImage( correctPixelTypeImage ); CastToMitkImage( correctPixelTypeImage, temporarySlice ); // check index positions mitkIpPicDescriptor* originalPicSlice = mitkIpPicNew(); CastToIpPicDescriptor( temporarySlice, originalPicSlice ); int m_SeedPointMemoryOffset = projectedPointIn2D[1] * originalPicSlice->n[0] + projectedPointIn2D[0]; if ( m_SeedPointMemoryOffset >= static_cast<int>( originalPicSlice->n[0] * originalPicSlice->n[1] ) || m_SeedPointMemoryOffset < 0 ) { MITK_ERROR << "Memory offset calculation if mitk::SetRegionTool has some serious flaw! Aborting.." << std::endl; return false; } // 2. Determine the contour that surronds the selected "piece of the image" // find a contour seed point unsigned int oneContourOffset = static_cast<unsigned int>( m_SeedPointMemoryOffset ); // safe because of earlier check if m_SeedPointMemoryOffset < 0 /** * The logic of finding a starting point for the contour is the following: * * - If the initial seed point is 0, we are either inside a hole or outside of every segmentation. * We move to the right until we hit a 1, which must be part of a contour. * * - If the initial seed point is 1, then ... * we now do the same (running to the right) until we hit a 1 * * In both cases the found contour point is used to extract a contour and * then a test is applied to find out if the initial seed point is contained * in the contour. If this is the case, filling should be applied, otherwise * nothing is done. */ unsigned int size = originalPicSlice->n[0] * originalPicSlice->n[1]; /* unsigned int rowSize = originalPicSlice->n[0]; */ ipMITKSegmentationTYPE* data = static_cast<ipMITKSegmentationTYPE*>(originalPicSlice->data); if ( data[oneContourOffset] == 0 ) // initial seed 0 { for ( ; oneContourOffset < size; ++oneContourOffset ) { if ( data[oneContourOffset] > 0 ) break; } } else if ( data[oneContourOffset] == 1 ) // initial seed 1 { unsigned int lastValidPixel = size-1; // initialization, will be changed lateron bool inSeg = true; // inside segmentation? for ( ; oneContourOffset < size; ++oneContourOffset ) { if ( ( data[oneContourOffset] == 0 ) && inSeg ) // pixel 0 and inside-flag set: this happens at the first pixel outside a filled region { inSeg = false; lastValidPixel = oneContourOffset - 1; // store the last pixel position inside a filled region break; } else // pixel 1, inside-flag doesn't matter: this happens while we are inside a filled region { inSeg = true; // first iteration lands here } } oneContourOffset = lastValidPixel; } else { MITK_ERROR << "Fill/Erase was never intended to work with other than binary images." << std::endl; m_FillContour = false; return false; } if (oneContourOffset == size) // nothing found until end of slice { m_FillContour = false; return false; } int numberOfContourPoints( 0 ); int newBufferSize( 0 ); //MITK_INFO << "getting contour from offset " << oneContourOffset << " ("<<oneContourOffset%originalPicSlice->n[0]<<","<<oneContourOffset/originalPicSlice->n[0]<<")"<<std::endl; float* contourPoints = ipMITKSegmentationGetContour8N( originalPicSlice, oneContourOffset, numberOfContourPoints, newBufferSize ); // memory allocated with malloc //MITK_INFO << "contourPoints " << contourPoints << " (N="<<numberOfContourPoints<<")"<<std::endl; assert(contourPoints == NULL || numberOfContourPoints > 0); bool cursorInsideContour = ipMITKSegmentationIsInsideContour( contourPoints, numberOfContourPoints, projectedPointIn2D[0], projectedPointIn2D[1]); // decide if contour should be filled or not m_FillContour = cursorInsideContour; if (m_FillContour) { // copy point from float* to mitk::Contour ContourModel::Pointer contourInImageIndexCoordinates = ContourModel::New(); contourInImageIndexCoordinates->Expand(timeStep + 1); contourInImageIndexCoordinates->SetClosed(true, timeStep); Point3D newPoint; for (int index = 0; index < numberOfContourPoints; ++index) { newPoint[0] = contourPoints[ 2 * index + 0 ] - 0.5; newPoint[1] = contourPoints[ 2 * index + 1] - 0.5; newPoint[2] = 0; contourInImageIndexCoordinates->AddVertex(newPoint, timeStep); } m_SegmentationContourInWorldCoordinates = FeedbackContourTool::BackProjectContourFrom2DSlice( workingSlice->GetGeometry(), contourInImageIndexCoordinates, true ); // true, correct the result from ipMITKSegmentationGetContour8N // 3. Show the contour FeedbackContourTool::SetFeedbackContour( *m_SegmentationContourInWorldCoordinates ); FeedbackContourTool::SetFeedbackContourVisible(true); mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow()); } // always generate a second contour, containing the whole image (used when CTRL is pressed) { // copy point from float* to mitk::Contour ContourModel::Pointer contourInImageIndexCoordinates = ContourModel::New(); contourInImageIndexCoordinates->Expand(timeStep + 1); contourInImageIndexCoordinates->SetClosed(true, timeStep); Point3D newPoint; newPoint[0] = 0; newPoint[1] = 0; newPoint[2] = 0.0; contourInImageIndexCoordinates->AddVertex( newPoint, timeStep ); newPoint[0] = originalPicSlice->n[0]; newPoint[1] = 0; newPoint[2] = 0.0; contourInImageIndexCoordinates->AddVertex( newPoint, timeStep ); newPoint[0] = originalPicSlice->n[0]; newPoint[1] = originalPicSlice->n[1]; newPoint[2] = 0.0; contourInImageIndexCoordinates->AddVertex( newPoint, timeStep ); newPoint[0] = 0; newPoint[1] = originalPicSlice->n[1]; newPoint[2] = 0.0; contourInImageIndexCoordinates->AddVertex( newPoint, timeStep ); m_WholeImageContourInWorldCoordinates = FeedbackContourTool::BackProjectContourFrom2DSlice( workingSlice->GetGeometry(), contourInImageIndexCoordinates, true ); // true, correct the result from ipMITKSegmentationGetContour8N // 3. Show the contour FeedbackContourTool::SetFeedbackContour( *m_SegmentationContourInWorldCoordinates ); FeedbackContourTool::SetFeedbackContourVisible(true); mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow()); } free(contourPoints); return true; }