static void Paint(mitk::Image::Pointer image, itk::Index<3> index, unsigned int timeStep) { // As soon as the ImagePixelWriteAccessor object goes out of scope at the // end of this function, the image will be unlocked again (RAII). mitk::ImagePixelWriteAccessor<T> writeAccessor(image, image->GetVolumeData(timeStep)); writeAccessor.SetPixelByIndex(index, std::numeric_limits<T>::min()); // Don't forget to update the modified time stamp of the image. Otherwise, // everything downstream wouldn't recognize that the image changed, // including the rendering system. image->Modified(); }
// The tests all do the same, only in different directions void testRoutine(mitk::SliceNavigationController::ViewDirection viewDirection) { int dim; switch(viewDirection) { case(mitk::SliceNavigationController::Axial): dim = 2; break; case(mitk::SliceNavigationController::Frontal): dim = 1; break; case(mitk::SliceNavigationController::Sagittal): dim = 0; break; case(mitk::SliceNavigationController::Original): dim = -1; break; // This is just to get rid of a warning } /* Fill segmentation * * 1st slice: 3x3 square segmentation * 2nd slice: empty * 3rd slice: 1x1 square segmentation in corner * -> 2nd slice should become 2x2 square in corner * * put accessor in scope */ itk::Index<3> currentPoint; { mitk::ImagePixelWriteAccessor<mitk::Tool::DefaultSegmentationDataType, 3> writeAccessor(m_SegmentationImage); // Fill 3x3 slice currentPoint[dim] = m_CenterPoint[dim] - 1; for (int i=-1; i<=1; ++i) { for (int j=-1; j<=1; ++j) { currentPoint[(dim+1)%3] = m_CenterPoint[(dim+1)%3] + i; currentPoint[(dim+2)%3] = m_CenterPoint[(dim+2)%3] + j; writeAccessor.SetPixelByIndexSafe(currentPoint, 1); } } // Now i=j=1, set point two slices up currentPoint[dim] = m_CenterPoint[dim] + 1; writeAccessor.SetPixelByIndexSafe(currentPoint, 1); } // mitk::IOUtil::Save(m_SegmentationImage, "SOME PATH"); m_InterpolationController->SetSegmentationVolume(m_SegmentationImage); m_InterpolationController->SetReferenceVolume(m_ReferenceImage); // This could be easier... mitk::SliceNavigationController::Pointer navigationController = mitk::SliceNavigationController::New(); navigationController->SetInputWorldTimeGeometry(m_SegmentationImage->GetTimeGeometry()); navigationController->Update(viewDirection); mitk::Point3D pointMM; m_SegmentationImage->GetTimeGeometry()->GetGeometryForTimeStep(0)->IndexToWorld(m_CenterPoint, pointMM); navigationController->SelectSliceByPoint(pointMM); auto plane = navigationController->GetCurrentPlaneGeometry(); mitk::Image::Pointer interpolationResult = m_InterpolationController->Interpolate(dim, m_CenterPoint[dim], plane, 0); // mitk::IOUtil::Save(interpolationResult, "SOME PATH"); // Write result into segmentation image vtkSmartPointer<mitkVtkImageOverwrite> reslicer = vtkSmartPointer<mitkVtkImageOverwrite>::New(); reslicer->SetInputSlice(interpolationResult->GetSliceData()->GetVtkImageAccessor(interpolationResult)->GetVtkImageData()); reslicer->SetOverwriteMode(true); reslicer->Modified(); mitk::ExtractSliceFilter::Pointer extractor = mitk::ExtractSliceFilter::New(reslicer); extractor->SetInput(m_SegmentationImage); extractor->SetTimeStep(0); extractor->SetWorldGeometry(plane); extractor->SetVtkOutputRequest(true); extractor->SetResliceTransformByGeometry(m_SegmentationImage->GetTimeGeometry()->GetGeometryForTimeStep(0)); extractor->Modified(); extractor->Update(); // mitk::IOUtil::Save(m_SegmentationImage, "SOME PATH"); // Check a 4x4 square, the center of which needs to be filled mitk::ImagePixelReadAccessor<mitk::Tool::DefaultSegmentationDataType, 3> readAccess(m_SegmentationImage); currentPoint = m_CenterPoint; for (int i=-1; i<=2; ++i) { for (int j=-1; j<=2; ++j) { currentPoint[(dim+1)%3] = m_CenterPoint[(dim+1)%3] + i; currentPoint[(dim+2)%3] = m_CenterPoint[(dim+2)%3] + j; if (i == -1 || i == 2 || j == -1 || j == 2) { CPPUNIT_ASSERT_MESSAGE("Have false positive segmentation.", readAccess.GetPixelByIndexSafe(currentPoint) == 0); } else { CPPUNIT_ASSERT_MESSAGE("Have false negative segmentation.", readAccess.GetPixelByIndexSafe(currentPoint) == 1); } } } }
ITK_THREAD_RETURN_TYPE ThreadMethod(void *data) { /* extract data pointer from Thread Info structure */ struct itk::MultiThreader::ThreadInfoStruct *pInfo = (struct itk::MultiThreader::ThreadInfoStruct *)data; // some data validity checking if (pInfo == NULL) { return ITK_THREAD_RETURN_VALUE; } if (pInfo->UserData == NULL) { return ITK_THREAD_RETURN_VALUE; } // obtain user data for processing ThreadData *threadData = (ThreadData *)pInfo->UserData; srand(pInfo->ThreadID); mitk::Image::Pointer im = threadData->data; int nrSlices = im->GetDimension(2); // Create randomly a PixelRead- or PixelWriteAccessor for a slice and access all pixels in it. try { if (rand() % 2) { testMutex.Lock(); mitk::ImageDataItem *iDi = im->GetSliceData(rand() % nrSlices); testMutex.Unlock(); while (!iDi->IsComplete()) { } // MITK_INFO << "pixeltype: " << im->GetPixelType().GetComponentTypeAsString(); if ((im->GetPixelType().GetComponentTypeAsString() == "short") && (im->GetDimension() == 3)) { // Use pixeltype&dimension specific read accessor int xlength = im->GetDimension(0); int ylength = im->GetDimension(1); mitk::ImagePixelReadAccessor<short, 2> readAccessor(im, iDi); itk::Index<2> idx; for (int i = 0; i < xlength; ++i) { for (int j = 0; j < ylength; ++j) { idx[0] = i; idx[1] = j; readAccessor.GetPixelByIndexSafe(idx); } } } else { // use general accessor mitk::ImageReadAccessor *iRA = new mitk::ImageReadAccessor(im, iDi); delete iRA; } } else { testMutex.Lock(); mitk::ImageDataItem *iDi = im->GetSliceData(rand() % nrSlices); testMutex.Unlock(); while (!iDi->IsComplete()) { } if ((im->GetPixelType().GetComponentTypeAsString() == "short") && (im->GetDimension() == 3)) { // Use pixeltype&dimension specific read accessor int xlength = im->GetDimension(0); int ylength = im->GetDimension(1); mitk::ImagePixelWriteAccessor<short, 2> writeAccessor(im, iDi); itk::Index<2> idx; for (int i = 0; i < xlength; ++i) { for (int j = 0; j < ylength; ++j) { idx[0] = i; idx[1] = j; short newVal = rand() % 16000; writeAccessor.SetPixelByIndexSafe(idx, newVal); short val = writeAccessor.GetPixelByIndexSafe(idx); if (val != newVal) { threadData->m_Successful = false; } } } } else { // use general accessor mitk::ImageWriteAccessor iB(im, iDi); void *pointer = iB.GetData(); *((char *)pointer) = 0; } } } catch (mitk::MemoryIsLockedException &e) { threadData->m_Successful = false; e.Print(std::cout); } catch (mitk::Exception &e) { threadData->m_Successful = false; e.Print(std::cout); } // data processing end! threadData->m_Barrier->Wait(); return ITK_THREAD_RETURN_VALUE; }