diff --git a/Modules/Bundles/org.mitk.gui.qt.toftutorial/src/internal/QmitkToFTutorialView.cpp b/Modules/Bundles/org.mitk.gui.qt.toftutorial/src/internal/QmitkToFTutorialView.cpp index d0093cb9bb..b7db784681 100644 --- a/Modules/Bundles/org.mitk.gui.qt.toftutorial/src/internal/QmitkToFTutorialView.cpp +++ b/Modules/Bundles/org.mitk.gui.qt.toftutorial/src/internal/QmitkToFTutorialView.cpp @@ -1,193 +1,193 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ // Blueberry #include #include // Qmitk #include "QmitkToFTutorialView.h" #include "QmitkStdMultiWidget.h" // Qt #include // mitk includes +#include // class holding the intrinsic parameters of the according camera #include // MITK-ToF related includes #include // configuration file holding e.g. plugin paths or path to test file directory #include // filter from module ToFProcessing that calculates a surface from the given range image #include // creator class that provides pre-configured ToFCameraDevices #include // allows access to images provided by the ToF camera -#include // class representing a pinhole camera and holding the intrinsic parameters of the according camera const std::string QmitkToFTutorialView::VIEW_ID = "org.mitk.views.toftutorial"; QmitkToFTutorialView::QmitkToFTutorialView() : QmitkFunctionality() , m_Controls( 0 ) , m_MultiWidget( NULL ) { } QmitkToFTutorialView::~QmitkToFTutorialView() { } void QmitkToFTutorialView::CreateQtPartControl( QWidget *parent ) { // build up qt view, unless already done if ( !m_Controls ) { // create GUI widgets from the Qt Designer's .ui file m_Controls = new Ui::QmitkToFTutorialViewControls; m_Controls->setupUi( parent ); connect( m_Controls->step1Button, SIGNAL(clicked()), this, SLOT(OnStep1()) ); connect( m_Controls->step2Button, SIGNAL(clicked()), this, SLOT(OnStep2()) ); } } void QmitkToFTutorialView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; } void QmitkToFTutorialView::StdMultiWidgetNotAvailable() { m_MultiWidget = NULL; } void QmitkToFTutorialView::OnStep1() { // clean up data storage RemoveAllNodesFromDataStorage(); // use ToFImageGrabber to create instance of ToFImageGrabber that holds a ToFCameraMITKPlayerDevice for playing ToF data mitk::ToFImageGrabber::Pointer tofImageGrabber = mitk::ToFImageGrabberCreator::GetInstance()->GetMITKPlayerImageGrabber(); // set paths to test data std::string distanceFileName = MITK_TOF_DATA_DIR; distanceFileName.append("/PMDCamCube2_MF0_IT0_20Images_DistanceImage.pic"); std::string amplitudeFileName = MITK_TOF_DATA_DIR; amplitudeFileName.append("/PMDCamCube2_MF0_IT0_20Images_AmplitudeImage.pic"); std::string intensityFileName = MITK_TOF_DATA_DIR; intensityFileName.append("/PMDCamCube2_MF0_IT0_20Images_IntensityImage.pic"); // set file name property in image grabber. This will be propagated to the corresponding device and controller class tofImageGrabber->SetProperty("DistanceImageFileName",mitk::StringProperty::New(distanceFileName)); tofImageGrabber->SetProperty("AmplitudeImageFileName",mitk::StringProperty::New(amplitudeFileName)); tofImageGrabber->SetProperty("IntensityImageFileName",mitk::StringProperty::New(intensityFileName)); // connect to device if (tofImageGrabber->ConnectCamera()) { //// start camera (internally starts thread that continuously grabs images from the camera) tofImageGrabber->StartCamera(); // update image grabber which itself represents the source of a MITK filter pipeline tofImageGrabber->Update(); // grab distance image mitk::Image::Pointer distanceImage = tofImageGrabber->GetOutput(0); // grab amplitude image mitk::Image::Pointer amplitudeImage = tofImageGrabber->GetOutput(1); // grab intensity image mitk::Image::Pointer intensityImage = tofImageGrabber->GetOutput(2); //add distance image to data storage mitk::DataNode::Pointer distanceNode = mitk::DataNode::New(); distanceNode->SetName("Distance Image"); distanceNode->SetData(distanceImage); this->GetDefaultDataStorage()->Add(distanceNode); //add amplitude image to data storage mitk::DataNode::Pointer amplitudeNode = mitk::DataNode::New(); amplitudeNode->SetName("Amplitude Image"); amplitudeNode->SetData(amplitudeImage); this->GetDefaultDataStorage()->Add(amplitudeNode); //add intensity image to data storage mitk::DataNode::Pointer intensityNode = mitk::DataNode::New(); intensityNode->SetName("Intensity Image"); intensityNode->SetData(intensityImage); this->GetDefaultDataStorage()->Add(intensityNode); // stop camera (terminate internally used thread) tofImageGrabber->StopCamera(); // disconnect from camera tofImageGrabber->DisconnectCamera(); // adjust views to new data in DataStorage mitk::RenderingManager::GetInstance()->InitializeViews(distanceImage->GetGeometry()); } else { MITK_ERROR<<"Connection to ToF camera could not be established"; } } void QmitkToFTutorialView::OnStep2() { // Check if distance image is available mitk::DataNode::Pointer distanceNode = this->GetDefaultDataStorage()->GetNamedNode("Distance Image"); if (distanceNode.IsNotNull()) { // get distance image from node and check if node contains image mitk::Image::Pointer distanceImage = dynamic_cast(distanceNode->GetData()); if (distanceImage.IsNotNull()) { - // create pinhole camera model that holds intrinsic parameters of the ToF camera - mitk::PinholeCameraModel::Pointer cameraIntrinsics = mitk::PinholeCameraModel::New(); + // create object of CameraIntrinsics that holds intrinsic parameters of the ToF camera + mitk::CameraIntrinsics::Pointer cameraIntrinsics = mitk::CameraIntrinsics::New(); // change focal length and use defaults for other parameters such as inter pixel distance or principal point - cameraIntrinsics->SetFocalLength(13.3); + cameraIntrinsics->SetFocalLength(13.3,13.3); // set up filter for surface calculation mitk::ToFDistanceImageToSurfaceFilter::Pointer surfaceFilter = mitk::ToFDistanceImageToSurfaceFilter::New(); // apply intrinsic parameters to filter - surfaceFilter->SetCameraModel(cameraIntrinsics); + surfaceFilter->SetCameraIntrinsics(cameraIntrinsics); // set distance image as input surfaceFilter->SetInput(distanceImage); // update the filter surfaceFilter->Update(); // get surface from filter mitk::Surface::Pointer surface = surfaceFilter->GetOutput(); // add surface to data storage mitk::DataNode::Pointer surfaceNode = mitk::DataNode::New(); surfaceNode->SetName("ToF surface"); surfaceNode->SetData(surface); this->GetDefaultDataStorage()->Add(surfaceNode); // adjust views to new data in DataStorage mitk::RenderingManager::GetInstance()->InitializeViews(surface->GetGeometry()); mitk::RenderingManager::GetInstance()->InitializeViews(surface->GetGeometry()); } else { QMessageBox::warning(NULL,"ToF Tutorial","Node 'Distance Image' contains no image"); } } else { QMessageBox::warning(NULL,"ToF Tutorial","Perform Step 1 first to acquire a distance image"); } } void QmitkToFTutorialView::RemoveAllNodesFromDataStorage() { mitk::DataStorage::SetOfObjects::ConstPointer allNodes = this->GetDefaultDataStorage()->GetAll(); this->GetDefaultDataStorage()->Remove(allNodes); } diff --git a/Modules/ToFProcessing/CMakeLists.txt b/Modules/ToFProcessing/CMakeLists.txt index bc2090729c..d1df90e238 100644 --- a/Modules/ToFProcessing/CMakeLists.txt +++ b/Modules/ToFProcessing/CMakeLists.txt @@ -1,13 +1,13 @@ MITK_CREATE_MODULE(mitkToFProcessing SUBPROJECTS MITK-ToF - DEPENDS Mitk MitkExt + DEPENDS Mitk MitkExt mitkCameraCalibration PACKAGE_DEPENDS OpenCV PROVIDES mitkToFProcessing ) IF(BUILD_TESTING) ADD_SUBDIRECTORY(Testing) ENDIF(BUILD_TESTING) diff --git a/Modules/ToFProcessing/Testing/mitkToFDistanceImageToPointSetFilterTest.cpp b/Modules/ToFProcessing/Testing/mitkToFDistanceImageToPointSetFilterTest.cpp index 6225b3652b..ec880a2ed3 100644 --- a/Modules/ToFProcessing/Testing/mitkToFDistanceImageToPointSetFilterTest.cpp +++ b/Modules/ToFProcessing/Testing/mitkToFDistanceImageToPointSetFilterTest.cpp @@ -1,248 +1,231 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: $ Version: $Revision: $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include #include -#include #include #include /**Documentation * test for the class "ToFDistanceImageToPointSetFilter". */ mitk::PointSet::Pointer CreateTestPointSet() { mitk::PointSet::Pointer subSet = mitk::PointSet::New(); mitk::Point3D point; point[0] = 10; point[1] = 20; point[2] = 0; subSet->InsertPoint(0,point); point[0] = 100; point[1] = 150; point[2] = 0; subSet->InsertPoint(1,point); point[0] = 110; point[1] = 30; point[2] = 0; subSet->InsertPoint(2,point); point[0] = 40; point[1] = 200; point[2] = 0; subSet->InsertPoint(3,point); return subSet; } inline static mitk::Image::Pointer CreateTestImageWithPointSet(mitk::ScalarType pixelValue, unsigned int dimX, unsigned int dimY, mitk::PointSet::Pointer subSet) { typedef itk::Image ItkImageType2D; typedef itk::ImageRegionIterator ItkImageRegionIteratorType2D; ItkImageType2D::Pointer image = ItkImageType2D::New(); ItkImageType2D::IndexType start; start[0] = 0; start[1] = 0; ItkImageType2D::SizeType size; size[0] = dimX; size[1] = dimY; ItkImageType2D::RegionType region; region.SetSize(size); region.SetIndex( start); ItkImageType2D::SpacingType spacing; spacing[0] = 1.0; spacing[1] = 1.0; image->SetRegions( region ); image->SetSpacing ( spacing ); image->Allocate(); //Obtaining image data from ToF camera// //Correlate inten values to PixelIndex// ItkImageRegionIteratorType2D imageIterator(image,image->GetLargestPossibleRegion()); imageIterator.GoToBegin(); while (!imageIterator.IsAtEnd()) { imageIterator.Set(pixelValue); ++imageIterator; } // distances varying from pixelValue std::vector distances; distances.push_back(50); distances.push_back(500); distances.push_back(2050); distances.push_back(300); // set the pixel values for the subset for (unsigned int i=0; iGetSize(); i++) { mitk::Point3D point = subSet->GetPoint(i); ItkImageType2D::IndexType index; index[0] = point[0]; index[1] = point[1]; mitk::ScalarType distance = distances.at(i); image->SetPixel(index,distance); } mitk::Image::Pointer mitkImage = mitk::Image::New(); mitk::CastToMitkImage(image,mitkImage); return mitkImage; } int mitkToFDistanceImageToPointSetFilterTest(int /* argc */, char* /*argv*/[]) { MITK_TEST_BEGIN("ToFDistanceImageToPointSetFilter"); mitk::ToFDistanceImageToPointSetFilter::Pointer filter = mitk::ToFDistanceImageToPointSetFilter::New(); //create test sub set MITK_INFO<<"Create test pointset"; mitk::PointSet::Pointer subSet = CreateTestPointSet(); //create test image unsigned int dimX = 204; unsigned int dimY = 204; MITK_INFO<<"Create test image"; mitk::Image::Pointer image = CreateTestImageWithPointSet(1000.0f,dimX,dimY,subSet); //initialize intrinsic parameters - mitk::ScalarType focalLength = 10; - mitk::Point2D interPixelDistance; - interPixelDistance[0] = 0.05; - interPixelDistance[1] = 0.05; - mitk::Point2D principalPoint; - principalPoint[0] = 100; - principalPoint[1] = 100; - - mitk::PinholeCameraModel::Pointer camera = mitk::PinholeCameraModel::New(); - camera->SetFocalLength(focalLength); - camera->SetPrincipalPoint(principalPoint); - camera->SetInterPixelDistance(interPixelDistance); - - - // test setter/getter of intrinsic parameters - filter->SetCameraModel(camera); - MITK_TEST_CONDITION_REQUIRED((focalLength==filter->GetCameraModel()->GetFocalLength()),"Testing Set/GetFocalLength()"); -// filter->SetInterPixelDistance(interPixelDistance); - MITK_TEST_CONDITION_REQUIRED((interPixelDistance==filter->GetCameraModel()->GetInterPixelDistance()),"Testing Set/GetInterPixelDistance()"); -// filter->SetPrincipalPoint(principalPoint); - mitk::Point2D pp = filter->GetCameraModel()->GetPrincipalPoint(); - MITK_TEST_CONDITION_REQUIRED(mitk::Equal(principalPoint,pp),"Testing Set/GetPrincipalPoint()"); - // test SetIntrinsicParameters() - mitk::PinholeCameraModel::Pointer cameraIntrinics = mitk::PinholeCameraModel::New(); - mitk::Point2D imageArea; - imageArea[0] = dimX*interPixelDistance[0]; - imageArea[1] = dimY*interPixelDistance[1]; - cameraIntrinics->SetImageArea(imageArea); - cameraIntrinics->SetFocalLength(10); - mitk::Point2D pixelSize; - pixelSize[0] = interPixelDistance[0]; - pixelSize[1] = interPixelDistance[1]; - cameraIntrinics->SetInterPixelDistance(pixelSize); - mitk::Point2D imageShift; - imageShift[0] = (principalPoint[0] - dimX/2)*interPixelDistance[0]; - imageShift[1] = (principalPoint[1] - dimX/2)*interPixelDistance[1]; - cameraIntrinics->SetImageShift(imageShift); - filter->SetCameraModel(cameraIntrinics); - MITK_TEST_CONDITION_REQUIRED((focalLength==filter->GetCameraModel()->GetFocalLength()),"Testing SetIntrinsicParameters() - focal length"); - MITK_TEST_CONDITION_REQUIRED((interPixelDistance==filter->GetCameraModel()->GetInterPixelDistance()),"Testing SetIntrinsicParameters() - inter pixel distance"); - pp = camera->GetPrincipalPoint(); - MITK_TEST_CONDITION_REQUIRED(mitk::Equal(principalPoint,pp),"Testing SetIntrinsicParameters() - principal point"); + //initialize intrinsic parameters with some arbitrary values + mitk::ToFProcessingCommon::ToFPoint2D interPixelDistance; + interPixelDistance[0] = 0.04564; + interPixelDistance[1] = 0.0451564; + mitk::ToFProcessingCommon::ToFScalarType focalLengthX = 295.78960; + mitk::ToFProcessingCommon::ToFScalarType focalLengthY = 296.348535; + mitk::ToFProcessingCommon::ToFScalarType focalLength = (focalLengthX*interPixelDistance[0]+focalLengthY*interPixelDistance[1])/2.0; + mitk::ToFProcessingCommon::ToFScalarType k1=-0.36,k2=-0.14,p1=0.001,p2=-0.00; + mitk::ToFProcessingCommon::ToFPoint2D principalPoint; + principalPoint[0] = 103.576546; + principalPoint[1] = 100.1532; + mitk::CameraIntrinsics::Pointer cameraIntrinsics = mitk::CameraIntrinsics::New(); + cameraIntrinsics->SetFocalLength(focalLengthX,focalLengthY); + cameraIntrinsics->SetPrincipalPoint(principalPoint[0],principalPoint[1]); + cameraIntrinsics->SetDistorsionCoeffs(k1,k2,p1,p2); + // test SetCameraIntrinsics() + filter->SetCameraIntrinsics(cameraIntrinsics); + MITK_TEST_CONDITION_REQUIRED((focalLengthX==filter->GetCameraIntrinsics()->GetFocalLengthX()),"Testing SetCameraIntrinsics with focalLength"); + mitk::ToFProcessingCommon::ToFPoint2D pp; + pp[0] = filter->GetCameraIntrinsics()->GetPrincipalPointX(); + pp[1] = filter->GetCameraIntrinsics()->GetPrincipalPointY(); + MITK_TEST_CONDITION_REQUIRED(mitk::Equal(principalPoint,pp),"Testing SetCameraIntrinsics with principalPoint()"); + // test SetInterPixelDistance() + + filter->SetInterPixelDistance(interPixelDistance); + mitk::ToFProcessingCommon::ToFPoint2D ipD = filter->GetInterPixelDistance(); + MITK_TEST_CONDITION_REQUIRED(mitk::Equal(ipD,interPixelDistance),"Testing Set/GetInterPixelDistance()"); // test Set/GetInput() filter->SetInput(image); MITK_TEST_CONDITION_REQUIRED((image==filter->GetInput()),"Testing Set/GetInput()"); // test filter without subset MITK_INFO<<"Test filter without subset"; mitk::PointSet::Pointer expectedResult = mitk::PointSet::New(); unsigned int counter = 0; for (unsigned int i=0; iGetPixelValueByIndex(index); - mitk::Point3D coordinate = mitk::ToFProcessingCommon::IndexToCartesianCoordinates(i,j,distance,cameraIntrinics->GetFocalLength(),cameraIntrinics->GetInterPixelDistance(), - cameraIntrinics->GetPrincipalPoint()); + mitk::Point3D coordinate = mitk::ToFProcessingCommon::IndexToCartesianCoordinates(i,j,distance,focalLength,interPixelDistance,principalPoint); expectedResult->InsertPoint(counter,coordinate); counter++; } } filter->Update(); mitk::PointSet::Pointer result = filter->GetOutput(); MITK_TEST_CONDITION_REQUIRED((expectedResult->GetSize()==result->GetSize()),"Test if point set size is equal"); bool pointSetsEqual = true; for (unsigned int i=0; iGetSize(); i++) { mitk::Point3D expectedPoint = expectedResult->GetPoint(i); mitk::Point3D resultPoint = result->GetPoint(i); if (!mitk::Equal(expectedPoint,resultPoint)) { - MITK_INFO << "erwartet " << expectedPoint; - MITK_INFO << "result " << resultPoint; + //MITK_INFO << "erwartet " << expectedPoint; + //MITK_INFO << "result " << resultPoint; pointSetsEqual = false; } } MITK_TEST_CONDITION_REQUIRED(pointSetsEqual,"Testing filter without subset"); // test filter with subset MITK_INFO<<"Test filter with subset"; filter = mitk::ToFDistanceImageToPointSetFilter::New(); filter->SetInput(image); - filter->SetCameraModel(cameraIntrinics); + filter->SetInterPixelDistance(interPixelDistance); + filter->SetCameraIntrinsics(cameraIntrinsics); expectedResult = mitk::PointSet::New(); counter = 0; for (unsigned int i=0; iGetSize(); i++) { mitk::Point3D point = subSet->GetPoint(i); mitk::Index3D index; index[0] = point[0]; index[1] = point[1]; index[2] = 0; mitk::ScalarType distance = image->GetPixelValueByIndex(index); mitk::Point3D coordinate = mitk::ToFProcessingCommon::IndexToCartesianCoordinates(point[0],point[1], - distance,cameraIntrinics->GetFocalLength(),cameraIntrinics->GetInterPixelDistance(), - cameraIntrinics->GetPrincipalPoint()); + distance,focalLength,interPixelDistance,principalPoint); expectedResult->InsertPoint(counter,coordinate); counter++; } filter->SetSubset(subSet); filter->Modified(); filter->Update(); result = filter->GetOutput(); MITK_TEST_CONDITION_REQUIRED((expectedResult->GetSize()==result->GetSize()),"Test if point set size is equal"); pointSetsEqual = true; for (unsigned int i=0; iGetSize(); i++) { mitk::Point3D expectedPoint = expectedResult->GetPoint(i); mitk::Point3D resultPoint = result->GetPoint(i); if (!mitk::Equal(expectedPoint,resultPoint)) { pointSetsEqual = false; } } MITK_TEST_CONDITION_REQUIRED(pointSetsEqual,"Testing filter without subset"); MITK_TEST_END(); } diff --git a/Modules/ToFProcessing/Testing/mitkToFDistanceImageToSurfaceFilterTest.cpp b/Modules/ToFProcessing/Testing/mitkToFDistanceImageToSurfaceFilterTest.cpp index 0c2e118ce9..7a1a4845c2 100644 --- a/Modules/ToFProcessing/Testing/mitkToFDistanceImageToSurfaceFilterTest.cpp +++ b/Modules/ToFProcessing/Testing/mitkToFDistanceImageToSurfaceFilterTest.cpp @@ -1,246 +1,221 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: $ Version: $Revision: $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include //#include #include #include #include #include #include //#include //#include //#include #include #include #include /**Documentation * test for the class "ToFDistanceImageToSurfaceFilter". */ typedef mitk::ToFProcessingCommon::ToFPoint2D ToFPoint2D; typedef mitk::ToFProcessingCommon::ToFPoint3D ToFPoint3D; typedef mitk::ToFProcessingCommon::ToFScalarType ToFScalarType; int mitkToFDistanceImageToSurfaceFilterTest(int /* argc */, char* /*argv*/[]) { MITK_TEST_BEGIN("ToFDistanceImageToSurfaceFilter"); mitk::ToFDistanceImageToSurfaceFilter::Pointer filter = mitk::ToFDistanceImageToSurfaceFilter::New(); // create test image unsigned int dimX =204; unsigned int dimY =204; mitk::Image::Pointer image = mitk::ToFTestingCommon::CreateTestImage(dimX,dimY); //initialize intrinsic parameters with some arbitrary values - ToFScalarType focalLength = 13.654368; - ToFPoint2D interPixelDistance; - interPixelDistance[0] = 0.04564; - interPixelDistance[1] = 0.0451564; + ToFScalarType focalLengthX = 295.78960; + ToFScalarType focalLengthY = 296.348535; + ToFScalarType k1=-0.36,k2=-0.14,p1=0.001,p2=-0.00; ToFPoint2D principalPoint; principalPoint[0] = 103.576546; principalPoint[1] = 100.1532; - - mitk::PinholeCameraModel::Pointer camera = mitk::PinholeCameraModel::New(); - camera->SetFocalLength(focalLength); - camera->SetPrincipalPoint(principalPoint); - camera->SetInterPixelDistance(interPixelDistance); - - filter->SetCameraModel(camera); - - MITK_TEST_CONDITION_REQUIRED((focalLength==filter->GetCameraModel()->GetFocalLength()),"Testing Set/GetFocalLength()"); - filter->GetCameraModel()->SetInterPixelDistance(interPixelDistance); - MITK_TEST_CONDITION_REQUIRED((interPixelDistance==filter->GetCameraModel()->GetInterPixelDistance()),"Testing Set/GetInterPixelDistance()"); - filter->GetCameraModel()->SetPrincipalPoint(principalPoint); - ToFPoint2D pp = filter->GetCameraModel()->GetPrincipalPoint(); - MITK_TEST_CONDITION_REQUIRED(mitk::Equal(principalPoint,pp),"Testing Set/GetPrincipalPoint()"); - // test SetIntrinsicParameters() - mitk::PinholeCameraModel::Pointer cameraIntrinics = mitk::PinholeCameraModel::New(); - ToFPoint2D imageArea; - imageArea[0] = dimX*interPixelDistance[0]; - imageArea[1] = dimY*interPixelDistance[1]; - cameraIntrinics->SetImageArea(imageArea); - cameraIntrinics->SetFocalLength(focalLength); - ToFPoint2D pixelSize; - pixelSize[0] = interPixelDistance[0]; - pixelSize[1] = interPixelDistance[1]; - cameraIntrinics->SetInterPixelDistance(pixelSize); - ToFPoint2D imageShift; - imageShift[0] = (principalPoint[0] - dimX/2)*interPixelDistance[0]; - imageShift[1] = (principalPoint[1] - dimX/2)*interPixelDistance[1]; - cameraIntrinics->SetImageShift(imageShift); - cameraIntrinics->SetPrincipalPoint(principalPoint); - filter->SetCameraModel(cameraIntrinics); - MITK_TEST_CONDITION_REQUIRED((focalLength==filter->GetCameraModel()->GetFocalLength()),"Testing SetIntrinsicParameters() - focal length"); - MITK_TEST_CONDITION_REQUIRED((interPixelDistance==filter->GetCameraModel()->GetInterPixelDistance()),"Testing SetIntrinsicParameters() - inter pixel distance"); - pp = filter->GetCameraModel()->GetPrincipalPoint(); - MITK_TEST_CONDITION_REQUIRED(mitk::Equal(principalPoint,pp),"Testing SetIntrinsicParameters() - principal point"); + mitk::CameraIntrinsics::Pointer cameraIntrinsics = mitk::CameraIntrinsics::New(); + cameraIntrinsics->SetFocalLength(focalLengthX,focalLengthY); + cameraIntrinsics->SetPrincipalPoint(principalPoint[0],principalPoint[1]); + cameraIntrinsics->SetDistorsionCoeffs(k1,k2,p1,p2); + // test SetCameraIntrinsics() + filter->SetCameraIntrinsics(cameraIntrinsics); + MITK_TEST_CONDITION_REQUIRED((focalLengthX==filter->GetCameraIntrinsics()->GetFocalLengthX()),"Testing SetCameraIntrinsics with focalLength"); + ToFPoint2D pp; + pp[0] = filter->GetCameraIntrinsics()->GetPrincipalPointX(); + pp[1] = filter->GetCameraIntrinsics()->GetPrincipalPointY(); + MITK_TEST_CONDITION_REQUIRED(mitk::Equal(principalPoint,pp),"Testing SetCameraIntrinsics with principalPoint()"); + // test SetInterPixelDistance() + ToFPoint2D interPixelDistance; + interPixelDistance[0] = 0.04564; + interPixelDistance[1] = 0.0451564; + filter->SetInterPixelDistance(interPixelDistance); + ToFPoint2D ipD = filter->GetInterPixelDistance(); + MITK_TEST_CONDITION_REQUIRED(mitk::Equal(ipD,interPixelDistance),"Testing Set/GetInterPixelDistance()"); // test Set/GetInput() filter->SetInput(image); MITK_TEST_CONDITION_REQUIRED((image==filter->GetInput()),"Testing Set/GetInput()"); // test filter without subset MITK_INFO<<"Test filter "; + // calculate focal length considering inter pixel distance + ToFScalarType focalLength = (focalLengthX*interPixelDistance[0]+focalLengthY*interPixelDistance[1])/2.0; vtkSmartPointer expectedResult = vtkSmartPointer::New(); expectedResult->SetDataTypeToDouble(); unsigned int counter = 0; double* point = new double[3]; // MITK_INFO<<"Test"; // MITK_INFO<<"focal: "<GetPixelValueByIndex(index); ToFPoint3D coordinate = mitk::ToFProcessingCommon::IndexToCartesianCoordinates(i,j,distance,focalLength,interPixelDistance,principalPoint); // if ((i==0)&&(j==0)) // { // MITK_INFO<<"Distance test: "<InsertPoint(pointID,point); } counter++; } } filter->Update(); mitk::Surface::Pointer resultSurface = filter->GetOutput(); vtkSmartPointer result = vtkSmartPointer::New(); result->SetDataTypeToDouble(); result = resultSurface->GetVtkPolyData()->GetPoints(); MITK_TEST_CONDITION_REQUIRED((expectedResult->GetNumberOfPoints()==result->GetNumberOfPoints()),"Test if number of points in surface is equal"); bool pointSetsEqual = true; for (unsigned int i=0; iGetNumberOfPoints(); i++) { double* expected = expectedResult->GetPoint(i); double* res = result->GetPoint(i); ToFPoint3D expectedPoint; expectedPoint[0] = expected[0]; expectedPoint[1] = expected[1]; expectedPoint[2] = expected[2]; ToFPoint3D resultPoint; resultPoint[0] = res[0]; resultPoint[1] = res[1]; resultPoint[2] = res[2]; if (!mitk::Equal(expectedPoint,resultPoint)) { // MITK_INFO << i; MITK_INFO<<"expected: "<GetNumberOfPoints(); i++) { double* expected = expectedResult->GetPoint(i); double* res = result->GetPoint(i); ToFPoint3D expectedPoint; expectedPoint[0] = expected[0]; expectedPoint[1] = expected[1]; expectedPoint[2] = expected[2]; ToFPoint3D resultPoint; resultPoint[0] = res[0]; resultPoint[1] = res[1]; resultPoint[2] = res[2]; ToFPoint3D expectedPointBackward = - mitk::ToFProcessingCommon::CartesianToIndexCoordinates(expectedPoint, - filter->GetCameraModel()->GetFocalLength(), - filter->GetCameraModel()->GetInterPixelDistance(), - filter->GetCameraModel()->GetPrincipalPoint()); + mitk::ToFProcessingCommon::CartesianToIndexCoordinates(expectedPoint,focalLength,interPixelDistance,principalPoint); ToFPoint3D resultPointBackward = - mitk::ToFProcessingCommon::CartesianToIndexCoordinates(resultPoint, - filter->GetCameraModel()->GetFocalLength(), - filter->GetCameraModel()->GetInterPixelDistance(), - filter->GetCameraModel()->GetPrincipalPoint()); + mitk::ToFProcessingCommon::CartesianToIndexCoordinates(resultPoint,focalLength,interPixelDistance,principalPoint); if (!mitk::Equal(expectedPointBackward,resultPointBackward)) { // MITK_INFO << i; // MITK_INFO<<"expected: "<GetNumberOfPoints(); i++) { double* res = result->GetPoint(i); ToFPoint3D resultPoint; resultPoint[0] = res[0]; resultPoint[1] = res[1]; resultPoint[2] = res[2]; ToFPoint3D resultPointBackward = - mitk::ToFProcessingCommon::CartesianToIndexCoordinates(resultPoint, - filter->GetCameraModel()->GetFocalLength(), - filter->GetCameraModel()->GetInterPixelDistance(), - filter->GetCameraModel()->GetPrincipalPoint()); + mitk::ToFProcessingCommon::CartesianToIndexCoordinates(resultPoint,focalLength,interPixelDistance,principalPoint); mitk::Index3D pixelIndex; pixelIndex[0] = (int) (resultPointBackward[0]+0.5); pixelIndex[1] = (int) (resultPointBackward[1]+0.5); pixelIndex[2] = 0; if (!mitk::Equal(image->GetPixelValueByIndex(pixelIndex),resultPointBackward[2])) { // MITK_INFO<<"expected: "<< image->GetPixelValueByIndex(pixelIndex); // MITK_INFO<<"result: "<< resultPoint; compareToInput = false; } } MITK_TEST_CONDITION_REQUIRED(compareToInput,"Testing backward transformation compared to original image"); //clean up delete point; // expectedResult->Delete(); MITK_TEST_END(); } diff --git a/Modules/ToFProcessing/files.cmake b/Modules/ToFProcessing/files.cmake index 752c693643..7b47264987 100644 --- a/Modules/ToFProcessing/files.cmake +++ b/Modules/ToFProcessing/files.cmake @@ -1,10 +1,9 @@ SET(CPP_FILES - mitkPinholeCameraModel.cpp mitkToFCompositeFilter.cpp mitkToFDistanceImageToPointSetFilter.cpp mitkToFDistanceImageToSurfaceFilter.cpp mitkToFProcessingCommon.cpp mitkToFSurfaceVtkMapper3D.cpp mitkToFVisualizationFilter.cpp mitkToFTestingCommon.cpp ) diff --git a/Modules/ToFProcessing/mitkPinholeCameraModel.cpp b/Modules/ToFProcessing/mitkPinholeCameraModel.cpp deleted file mode 100644 index f89d9ac843..0000000000 --- a/Modules/ToFProcessing/mitkPinholeCameraModel.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/*========================================================================= -Program: Medical Imaging & Interaction Toolkit -Module: $RCSfile$ -Language: C++ -Date: $Date: 2009-07-17 15:44:24 +0200 (Fr, 17 Jul 2009) $ -Version: $Revision: 18261 $ - -Copyright (c) German Cancer Research Center, Division of Medical and -Biological Informatics. All rights reserved. -See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. - -This software is distributed WITHOUT ANY WARRANTY; without even -the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -PURPOSE. See the above copyright notices for more information. - -=========================================================================*/ - -#include "mitkPinholeCameraModel.h" - -mitk::PinholeCameraModel::PinholeCameraModel() - : m_FocalLength(12.8), m_MaxDistance(2000.0), m_PrincipalPoint(), m_CameraToWorldTransform_R(), m_ImageArea(), - m_InterPixelDistance(), m_DistanceImageDimension(2), m_DistanceImageDimensions(), m_CameraToWorldTransform_T(), m_ImageShift() -{ - this->InitializeWithDefaultSettings(); -} - -mitk::PinholeCameraModel::~PinholeCameraModel() -{} - -void mitk::PinholeCameraModel::GetCameraToWorldTransform(itk::Matrix& TransformR,itk::Vector& TransformT) -{ - TransformR = m_CameraToWorldTransform_R; - TransformT = m_CameraToWorldTransform_T; -} - -void mitk::PinholeCameraModel::SetCameraToWorldTransform(itk::Matrix TransformR,itk::Vector TransformT) -{ - m_CameraToWorldTransform_R = TransformR; - m_CameraToWorldTransform_T = TransformT; -} - -void mitk::PinholeCameraModel::CalculateImageArea() -{ - m_ImageArea[0] = m_DistanceImageDimensions[0]*m_InterPixelDistance[0]; - m_ImageArea[1] = m_DistanceImageDimensions[1]*m_InterPixelDistance[1]; -} - -void mitk::PinholeCameraModel::SetDistanceImageDimensions(unsigned int* dimensions) -{ - m_DistanceImageDimensions = dimensions; -} - -void mitk::PinholeCameraModel::CalculateImageDimensions() -{ - m_DistanceImageDimensions[0] = (unsigned int)(m_ImageArea[0]/m_InterPixelDistance[0] + 0.5); - m_DistanceImageDimensions[1] = (unsigned int)(m_ImageArea[1]/m_InterPixelDistance[1] + 0.5); -} - -mitk::ToFProcessingCommon::ToFPoint3D mitk::PinholeCameraModel::GetPixelMidPointInWorldCoordinates(unsigned int indexX, unsigned int indexY) -{ - ToFPoint3D returnValue; - //calculate the mid-point of a pixel in world coordinates - //[1] pinhole is in the middle, so we subtract half of the size of the image area - //[2] then we multiplicate with the pixel size to get the coordinates in mm - //[3] next we take account of the image shift (if the pinhole is NOT exactly in the middle) - //[4] last we add half of the size of a pixel to get the middle of each pixel - // [1] [2] [3] [4] - returnValue[0] = ((indexX - m_PrincipalPoint[0])*m_InterPixelDistance[0] + (m_InterPixelDistance[0]/2)); - returnValue[1] = ((indexY - m_PrincipalPoint[1])*m_InterPixelDistance[1] + (m_InterPixelDistance[1]/2)); - returnValue[2] = -m_FocalLength; - return returnValue; -} - -mitk::ToFProcessingCommon::ToFPoint3D mitk::PinholeCameraModel::GetCameraPositionInWorldCoordinates() -{ - ToFPoint3D returnValue; - ToFPoint3D origin; origin[0] = 0; origin[1] = 0; origin[2] = 0; - returnValue = (this->m_CameraToWorldTransform_R * origin) + this->m_CameraToWorldTransform_T; - return returnValue; -} - -void mitk::PinholeCameraModel::InitializeWithDefaultSettings() -{ - ToFPoint2D PrincipalPoint; - PrincipalPoint[0] = 101.5f; - PrincipalPoint[1] = 101.5f; - - ToFPoint2D ImageArea; - ImageArea[0] = 9.18f; - ImageArea[1] = 9.18f; - - ToFPoint2D InterPixelDistance; - InterPixelDistance[0] = 0.045f; - InterPixelDistance[1] = 0.045f; - - ToFPoint2D ImageShift; - ImageShift[0] = 0.0; - ImageShift[1] = 0.0; - - unsigned int* dimensions = new unsigned int[3]; - dimensions[0] = 204; - dimensions[1] = 204; -// dimensions[2] = 1; - - itk::Matrix transR; - transR.Fill(0); transR[0][0] = 1; transR[1][1] = 1; transR[2][2] = 1; - - itk::Vector transT; - transT.Fill(0); - - SetDistanceImageDimensions(dimensions); - SetPrincipalPoint(PrincipalPoint); - SetImageArea(ImageArea); - SetInterPixelDistance(InterPixelDistance); - SetImageShift(ImageShift); - SetCameraToWorldTransform(transR,transT); -} diff --git a/Modules/ToFProcessing/mitkPinholeCameraModel.h b/Modules/ToFProcessing/mitkPinholeCameraModel.h deleted file mode 100644 index d19bd7f1f5..0000000000 --- a/Modules/ToFProcessing/mitkPinholeCameraModel.h +++ /dev/null @@ -1,121 +0,0 @@ -/*========================================================================= - -Program: Medical Imaging & Interaction Toolkit -Module: $RCSfile$ -Language: C++ -Date: $Date: 2009-07-17 15:44:24 +0200 (Fr, 17 Jul 2009) $ -Version: $Revision: 18261 $ - -Copyright (c) German Cancer Research Center, Division of Medical and -Biological Informatics. All rights reserved. -See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. - -This software is distributed WITHOUT ANY WARRANTY; without even -the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -PURPOSE. See the above copyright notices for more information. - -=========================================================================*/ - -#ifndef MITKPINHOLECAMERAMODEL_H_HEADER_INCLUDED_ -#define MITKPINHOLECAMERAMODEL_H_HEADER_INCLUDED_ - -//mitk headers -#include "mitkToFProcessingExports.h" -#include "mitkToFProcessingCommon.h" -#include -#include - - -//itk headers -#include -#include -#include -#include -#include - -namespace mitk { - //##Documentation - //## \brief An object of this class represents an ideal pinhole camera. - - class mitkToFProcessing_EXPORT PinholeCameraModel : public itk::DataObject - { - public: - typedef mitk::ToFProcessingCommon::ToFScalarType ToFScalarType; - typedef mitk::ToFProcessingCommon::ToFPoint2D ToFPoint2D; - typedef mitk::ToFProcessingCommon::ToFPoint3D ToFPoint3D; - - mitkClassMacro(PinholeCameraModel, itk::DataObject); - itkNewMacro(Self); - - //getter - itkGetMacro(FocalLength,ToFScalarType); - /** @return Returns the image area in mm x mm */ - itkGetMacro(ImageArea,ToFPoint2D); - /** @return Returns the size of one pixel in mm x mm */ - itkGetMacro(InterPixelDistance,ToFPoint2D); - /** @return Returns the image shift in relation to the pinhole in mm x mm */ - itkGetMacro(ImageShift,ToFPoint2D); - /** @return Returns the maximum view distance of the camera. (in mm) */ - itkGetMacro(MaxDistance,ToFScalarType); - void GetCameraToWorldTransform(itk::Matrix& TransformR,itk::Vector& TransformT); - /** @return Returns the point of pixel (x|y) on the image area in camera coordinates (mm). */ - ToFPoint3D GetPixelMidPointInWorldCoordinates(unsigned int indexX, unsigned int indexY); - /** @return Returns the pixel position (x|y) principal point of this camera. */ - itkGetMacro(PrincipalPoint,ToFPoint2D); - itkGetMacro(DistanceImageDimension,unsigned int); - /** @brief Sets the image dimension */ - itkGetMacro(DistanceImageDimensions,unsigned int*); - /** @brief Sets the image dimensions */ - - //setter - /** @brief Sets the focal distance in pixels */ - itkSetMacro(FocalLength,ToFScalarType); - /** @brief Sets the size of one pixel in mm x mm */ - itkSetMacro(InterPixelDistance,ToFPoint2D); - /** @brief Sets the image shift in relation to the pinhole in mm x mm */ - itkSetMacro(ImageShift,ToFPoint2D); - /** @brief Sets the maximum view distance of the camera. (in mm) */ - itkSetMacro(MaxDistance,ToFScalarType); - /** @return Returns the camera positon in world coordinates */ - ToFPoint3D GetCameraPositionInWorldCoordinates(); - itkSetMacro(PrincipalPoint,ToFPoint2D); - - itkSetMacro(DistanceImageDimension,unsigned int); - itkSetMacro(ImageArea,ToFPoint2D); - - void SetDistanceImageDimensions(unsigned int* dimensions); - - void SetCameraToWorldTransform(itk::Matrix TransformR,itk::Vector TransformT); - - /** @brief Initializes the camera model with default settings which are needed often. - * (focal length: 12.8 mm; pixel size: 0.045 x 0.045; image area: 9.18 x 9.18; max distance: 2000) - */ - void InitializeWithDefaultSettings(); - /*! - \brief calculate image area in mm from m_DistanceImageDimensions and m_InterPixelDistance - */ - void CalculateImageArea(); - /*! - \brief calculate m_DistanceImageDimensions from m_ImageArea and m_InterPixelDistance - */ - void CalculateImageDimensions(); - - protected: - PinholeCameraModel(); - ~PinholeCameraModel(); - - //########### member variables #################### - ToFScalarType m_FocalLength; ///< focal length in mm - ToFScalarType m_MaxDistance; ///< range of the virtual camera - unsigned int m_DistanceImageDimension; ///< dimension of the distance image - unsigned int* m_DistanceImageDimensions; ///< x-, y-, z- (optional) dimension - ToFPoint2D m_PrincipalPoint; ///< principal point in pixel coordinates - ToFPoint2D m_ImageArea; ///< image area (mm x mm) - ToFPoint2D m_InterPixelDistance; ///< size of one pixel (mm x mm) - ToFPoint2D m_ImageShift; ///< image shift of pinhole in relation to the image center - itk::Matrix m_CameraToWorldTransform_R; ///< rotation matrix of camera to world transform - itk::Vector m_CameraToWorldTransform_T; ///< translation vector of camera to world transform - }; - -} // namespace mitk -#endif /* MITKPINHOLECAMERAMODEL_H_HEADER_INCLUDED_ */ diff --git a/Modules/ToFProcessing/mitkToFDistanceImageToPointSetFilter.cpp b/Modules/ToFProcessing/mitkToFDistanceImageToPointSetFilter.cpp index a8ea197028..89e00f14ee 100644 --- a/Modules/ToFProcessing/mitkToFDistanceImageToPointSetFilter.cpp +++ b/Modules/ToFProcessing/mitkToFDistanceImageToPointSetFilter.cpp @@ -1,167 +1,176 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Module: $RCSfile$ Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkToFDistanceImageToPointSetFilter.h" #include "mitkPointSet.h" #include "mitkToFProcessingCommon.h" mitk::ToFDistanceImageToPointSetFilter::ToFDistanceImageToPointSetFilter() -: m_CameraModel(), m_Subset(NULL) +: m_CameraIntrinsics(), m_Subset(NULL), m_InterPixelDistance() { - m_CameraModel = mitk::PinholeCameraModel::New(); + m_InterPixelDistance.Fill(0.045); + m_CameraIntrinsics = mitk::CameraIntrinsics::New(); + m_CameraIntrinsics->SetFocalLength(295.78960196187319,296.1255427948447); + m_CameraIntrinsics->SetPrincipalPoint(113.29063841714108,97.243216122015184); + m_CameraIntrinsics->SetDistorsionCoeffs(-0.36874385358645773f,-0.14339503290129013,0.0033210108720361795,-0.004277703352074105); } mitk::ToFDistanceImageToPointSetFilter::~ToFDistanceImageToPointSetFilter() { } void mitk::ToFDistanceImageToPointSetFilter::SetInput(const mitk::Image* distanceImage ) { this->SetInput(0,distanceImage); } void mitk::ToFDistanceImageToPointSetFilter::SetInput( unsigned int idx,const mitk::Image* distanceImage ) { if ((distanceImage == NULL) && (idx == this->GetNumberOfInputs() - 1)) // if the last input is set to NULL, reduce the number of inputs by one { this->SetNumberOfInputs(this->GetNumberOfInputs() - 1); } else { this->ProcessObject::SetNthInput(idx, const_cast(distanceImage)); // Process object is not const-correct so the const_cast is required here this->CreateOutputsForAllInputs(); } } mitk::Image* mitk::ToFDistanceImageToPointSetFilter::GetInput() { return this->GetInput(0); } mitk::Image* mitk::ToFDistanceImageToPointSetFilter::GetInput( unsigned int idx ) { if (this->GetNumberOfInputs() < 1) return NULL; return static_cast< mitk::Image*>(this->ProcessObject::GetInput(idx)); } void mitk::ToFDistanceImageToPointSetFilter::SetSubset(std::vector subset) { // check if points of PointSet are inside the input image mitk::Image::Pointer input = this->GetInput(); unsigned int xDim = input->GetDimension(0); unsigned int yDim = input->GetDimension(1); bool pointSetValid = true; for (unsigned int i=0; ixDim||currentIndex[1]<0||currentIndex[1]>yDim) { pointSetValid = false; } } if (pointSetValid) { m_Subset = subset; } else { MITK_ERROR<<"One or more indizes are located outside the image domain"; } } void mitk::ToFDistanceImageToPointSetFilter::SetSubset( mitk::PointSet::Pointer pointSet) { std::vector subset; for (unsigned int i=0; iGetSize(); i++) { mitk::Point3D currentPoint = pointSet->GetPoint(i); mitk::Index3D currentIndex; currentIndex[0] = currentPoint[0]; currentIndex[1] = currentPoint[1]; currentIndex[2] = currentPoint[2]; subset.push_back(currentIndex); } this->SetSubset(subset); } void mitk::ToFDistanceImageToPointSetFilter::GenerateData() { + mitk::ToFProcessingCommon::ToFScalarType focalLength = (m_CameraIntrinsics->GetFocalLengthX()*m_InterPixelDistance[0]+m_CameraIntrinsics->GetFocalLengthY()*m_InterPixelDistance[1])/2.0; + mitk::ToFProcessingCommon::ToFPoint2D principalPoint; + principalPoint[0] = m_CameraIntrinsics->GetPrincipalPointX(); + principalPoint[1] = m_CameraIntrinsics->GetPrincipalPointY(); + mitk::PointSet::Pointer output = this->GetOutput(); assert(output); mitk::Image::Pointer input = this->GetInput(); assert(input); //compute subset of points if input PointSet is defined if (m_Subset.size()!=0) { for (unsigned int i=0; iGetPixelValueByIndex(currentIndex); + mitk::ToFProcessingCommon::ToFScalarType distance = (double)input->GetPixelValueByIndex(currentIndex); + mitk::Point3D currentPoint = - mitk::ToFProcessingCommon::IndexToCartesianCoordinates(currentIndex,distance,m_CameraModel->GetFocalLength(), - m_CameraModel->GetInterPixelDistance(),m_CameraModel->GetPrincipalPoint()); + mitk::ToFProcessingCommon::IndexToCartesianCoordinates(currentIndex,distance,focalLength,m_InterPixelDistance,principalPoint); output->InsertPoint(i,currentPoint); } } else //compute PointSet holding cartesian coordinates for every image point { unsigned int xDimension = input->GetDimension(0); unsigned int yDimension = input->GetDimension(1); int pointCount = 0; for (int i=0; iGetPixelValueByIndex(pixel); + mitk::ToFProcessingCommon::ToFScalarType distance = (double)input->GetPixelValueByIndex(pixel); mitk::Point3D currentPoint = - mitk::ToFProcessingCommon::IndexToCartesianCoordinates(i,j,distance,m_CameraModel->GetFocalLength(),m_CameraModel->GetInterPixelDistance(),m_CameraModel->GetPrincipalPoint()); + mitk::ToFProcessingCommon::IndexToCartesianCoordinates(i,j,distance,focalLength,m_InterPixelDistance,principalPoint); if (distance!=0) { output->InsertPoint( pointCount, currentPoint ); pointCount++; } } } } } void mitk::ToFDistanceImageToPointSetFilter::CreateOutputsForAllInputs() { this->SetNumberOfOutputs(this->GetNumberOfInputs()); // create outputs for all inputs for (unsigned int idx = 0; idx < this->GetNumberOfOutputs(); ++idx) if (this->GetOutput(idx) == NULL) { DataObjectPointer newOutput = this->MakeOutput(idx); this->SetNthOutput(idx, newOutput); } this->Modified(); } void mitk::ToFDistanceImageToPointSetFilter::GenerateOutputInformation() { this->GetOutput(); itkDebugMacro(<<"GenerateOutputInformation()"); } diff --git a/Modules/ToFProcessing/mitkToFDistanceImageToPointSetFilter.h b/Modules/ToFProcessing/mitkToFDistanceImageToPointSetFilter.h index d39a1698ff..f78be3ea64 100644 --- a/Modules/ToFProcessing/mitkToFDistanceImageToPointSetFilter.h +++ b/Modules/ToFProcessing/mitkToFDistanceImageToPointSetFilter.h @@ -1,122 +1,125 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Module: $RCSfile$ Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __mitkToFDistanceImageToPointSetFilter_h #define __mitkToFDistanceImageToPointSetFilter_h +#include #include "mitkImage.h" #include "mitkPointSet.h" #include #include "mitkImageSource.h" -#include +#include #include "mitkToFProcessingExports.h" namespace mitk { /** * @brief Converts a Time-of-Flight (ToF) distance image to a PointSet using the pinhole camera model for coordinate computation. * The intrinsic parameters of the camera (FocalLength, PrincipalPoint, InterPixelDistance) are set via SetIntrinsicParameters(). The * measured distance for each pixel corresponds to the distance between the object point and the corresponding image point on the * image plane. * If a subset of indizes of the image is defined via SetSubset(), the output PointSet will only contain the cartesian coordinates * of the corresponding 3D points. * * Pinhole camera model * Image plane * * @ingroup SurfaceFilters * @ingroup ToFProcessing */ class mitkToFProcessing_EXPORT ToFDistanceImageToPointSetFilter : public PointSetSource { public: - typedef mitk::PinholeCameraModel::ToFScalarType ToFScalarType; mitkClassMacro( ToFDistanceImageToPointSetFilter , PointSetSource ); itkNewMacro( Self ); - itkSetMacro(CameraModel,mitk::PinholeCameraModel::Pointer); + itkSetMacro(CameraIntrinsics,mitk::CameraIntrinsics::Pointer); - itkGetMacro(CameraModel,mitk::PinholeCameraModel::Pointer); + itkGetMacro(CameraIntrinsics,mitk::CameraIntrinsics::Pointer); + itkSetMacro(InterPixelDistance,mitk::ToFProcessingCommon::ToFPoint2D); + itkGetMacro(InterPixelDistance,mitk::ToFProcessingCommon::ToFPoint2D); /*! \brief Sets the input of this filter \param distanceImage input is the distance image of e.g. a ToF camera */ virtual void SetInput(const Image* distanceImage); /*! \brief Sets the input of this filter at idx \param idx number of the current input \param distanceImage input is the distance image of e.g. a ToF camera */ virtual void SetInput(unsigned int idx,const Image* distanceImage); /*! \brief Returns the input of this filter */ Image* GetInput(); /*! \brief Returns the input with id idx of this filter */ Image* GetInput(unsigned int idx); /*! \brief If this subset is defined, the cartesian coordinates are only computed for the contained indizes. Make sure the indizes are contained in the input image \param subset index subset specified in index coordinates. */ void SetSubset( std::vector subset); /*! \brief Sets the subset of indizes used for caluclation of output PointSet as a PointSet. Warning: make sure the points in your PointSet are index coordinates. \param PointSet specified in index coordinates. */ void SetSubset( mitk::PointSet::Pointer pointSet); protected: /*! \brief Standard constructor */ ToFDistanceImageToPointSetFilter(); /*! \brief Standard destructor */ ~ToFDistanceImageToPointSetFilter(); virtual void GenerateOutputInformation(); /*! \brief Method generating the output of this filter. Called in the updated process of the pipeline. This method generates the output of the ToFSurfaceSource: The generated surface of the 3d points */ virtual void GenerateData(); /** * \brief Create an output for each input * * This Method sets the number of outputs to the number of inputs * and creates missing outputs objects. * \warning any additional outputs that exist before the method is called are deleted */ void CreateOutputsForAllInputs(); std::vector m_Subset; ///< If this subset is specified only the contained indizes are converted to cartesian coordinates - mitk::PinholeCameraModel::Pointer m_CameraModel; ///< Pinhole camera model holding the intrinsic parameters needed for PointSet calculation + mitk::CameraIntrinsics::Pointer m_CameraIntrinsics; ///< Member holding the intrinsic parameters needed for PointSet calculation + ToFProcessingCommon::ToFPoint2D m_InterPixelDistance; ///< distance in mm between two adjacent pixels on the ToF camera chip }; } //END mitk namespace #endif diff --git a/Modules/ToFProcessing/mitkToFDistanceImageToSurfaceFilter.cpp b/Modules/ToFProcessing/mitkToFDistanceImageToSurfaceFilter.cpp index f15471756a..c72c759a3c 100644 --- a/Modules/ToFProcessing/mitkToFDistanceImageToSurfaceFilter.cpp +++ b/Modules/ToFProcessing/mitkToFDistanceImageToSurfaceFilter.cpp @@ -1,247 +1,253 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Module: $RCSfile$ Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include -#include -#include #include #include #include #include #include #include #include #include #include #include -mitk::ToFDistanceImageToSurfaceFilter::ToFDistanceImageToSurfaceFilter(): m_CameraModel(), -m_TextureImageWidth(0), m_TextureImageHeight(0), m_IplScalarImage(NULL) +mitk::ToFDistanceImageToSurfaceFilter::ToFDistanceImageToSurfaceFilter(): m_CameraIntrinsics(), +m_TextureImageWidth(0), m_TextureImageHeight(0), m_IplScalarImage(NULL), m_InterPixelDistance() { - m_CameraModel = mitk::PinholeCameraModel::New(); + m_InterPixelDistance.Fill(0.045); + m_CameraIntrinsics = mitk::CameraIntrinsics::New(); + m_CameraIntrinsics->SetFocalLength(295.78960196187319,296.1255427948447); + m_CameraIntrinsics->SetPrincipalPoint(113.29063841714108,97.243216122015184); + m_CameraIntrinsics->SetDistorsionCoeffs(-0.36874385358645773f,-0.14339503290129013,0.0033210108720361795,-0.004277703352074105); } mitk::ToFDistanceImageToSurfaceFilter::~ToFDistanceImageToSurfaceFilter() { } -void mitk::ToFDistanceImageToSurfaceFilter::SetInput( Image* distanceImage, mitk::PinholeCameraModel::Pointer CameraModel ) +void mitk::ToFDistanceImageToSurfaceFilter::SetInput( Image* distanceImage, mitk::CameraIntrinsics::Pointer cameraIntrinsics ) { - this->SetCameraModel(CameraModel); + this->SetCameraIntrinsics(cameraIntrinsics); this->SetInput(0,distanceImage); } -void mitk::ToFDistanceImageToSurfaceFilter::SetInput( unsigned int idx, Image* distanceImage, mitk::PinholeCameraModel::Pointer CameraModel ) +void mitk::ToFDistanceImageToSurfaceFilter::SetInput( unsigned int idx, Image* distanceImage, mitk::CameraIntrinsics::Pointer cameraIntrinsics ) { - this->SetCameraModel(CameraModel); + this->SetCameraIntrinsics(cameraIntrinsics); this->SetInput(idx,distanceImage); } void mitk::ToFDistanceImageToSurfaceFilter::SetInput( mitk::Image* distanceImage ) { this->SetInput(0,distanceImage); } //TODO: braucht man diese Methode? void mitk::ToFDistanceImageToSurfaceFilter::SetInput( unsigned int idx, mitk::Image* distanceImage ) { if ((distanceImage == NULL) && (idx == this->GetNumberOfInputs() - 1)) // if the last input is set to NULL, reduce the number of inputs by one this->SetNumberOfInputs(this->GetNumberOfInputs() - 1); else this->ProcessObject::SetNthInput(idx, distanceImage); // Process object is not const-correct so the const_cast is required here this->CreateOutputsForAllInputs(); } mitk::Image* mitk::ToFDistanceImageToSurfaceFilter::GetInput() { return this->GetInput(0); } mitk::Image* mitk::ToFDistanceImageToSurfaceFilter::GetInput( unsigned int idx ) { if (this->GetNumberOfInputs() < 1) return NULL; //TODO: geeignete exception werfen return static_cast< mitk::Image*>(this->ProcessObject::GetInput(idx)); } void mitk::ToFDistanceImageToSurfaceFilter::GenerateData() { mitk::Surface::Pointer output = this->GetOutput(); assert(output); mitk::Image::Pointer input = this->GetInput(); assert(input); // mesh points unsigned int xDimension = input->GetDimension(0); unsigned int yDimension = input->GetDimension(1); unsigned int size = xDimension*yDimension; //size of the image-array std::vector isPointValid; isPointValid.resize(size); int pointCount = 0; vtkSmartPointer points = vtkSmartPointer::New(); points->SetDataTypeToDouble(); vtkSmartPointer polys = vtkSmartPointer::New(); vtkSmartPointer scalarArray = vtkSmartPointer::New(); vtkSmartPointer textureCoords = vtkSmartPointer::New(); textureCoords->SetNumberOfComponents(2); float textureScaleCorrection1 = 0.0; float textureScaleCorrection2 = 0.0; if (this->m_TextureImageHeight > 0.0 && this->m_TextureImageWidth > 0.0) { textureScaleCorrection1 = float(this->m_TextureImageHeight) / float(this->m_TextureImageWidth); textureScaleCorrection2 = ((float(this->m_TextureImageWidth) - float(this->m_TextureImageHeight))/2) / float(this->m_TextureImageWidth); } float* scalarFloatData = NULL; if (this->m_IplScalarImage) // if scalar image is defined use it for texturing { scalarFloatData = (float*)this->m_IplScalarImage->imageData; } else if ((this->GetNumberOfInputs()>2)&&this->GetInput(2)) // otherwise use intensity image (input(2)) { scalarFloatData = (float*)this->GetInput(2)->GetData(); } float* inputFloatData = (float*)(input->GetSliceData(0, 0, 0)->GetData()); //calculate world coordinates for (int j=0; jGetPixelValueByIndex(pixel); //TODO: float array zugriff + mitk::ToFProcessingCommon::ToFScalarType distance = (double)inputFloatData[pixelID]; + + mitk::ToFProcessingCommon::ToFScalarType focalLength = (m_CameraIntrinsics->GetFocalLengthX()*m_InterPixelDistance[0]+m_CameraIntrinsics->GetFocalLengthY()*m_InterPixelDistance[1])/2.0; + mitk::ToFProcessingCommon::ToFPoint2D principalPoint; + principalPoint[0] = m_CameraIntrinsics->GetPrincipalPointX(); + principalPoint[1] = m_CameraIntrinsics->GetPrincipalPointY(); mitk::ToFProcessingCommon::ToFPoint3D cartesianCoordinates = - mitk::ToFProcessingCommon::IndexToCartesianCoordinates(i,j,distance,m_CameraModel->GetFocalLength(),m_CameraModel->GetInterPixelDistance(),m_CameraModel->GetPrincipalPoint()); + mitk::ToFProcessingCommon::IndexToCartesianCoordinates(i,j,distance,focalLength,m_InterPixelDistance,principalPoint); //TODO: why epsilon here and what value should it have? // if (cartesianCoordinates[2] == 0) if (distance<=mitk::eps) { isPointValid[pointCount] = false; } else { isPointValid[pointCount] = true; points->InsertPoint(pixelID, cartesianCoordinates.GetDataPointer()); if((i >= 1) && (j >= 1)) { vtkIdType xy = i+j*xDimension; vtkIdType x_1y = i-1+j*xDimension; vtkIdType xy_1 = i+(j-1)*xDimension; vtkIdType x_1y_1 = (i-1)+(j-1)*xDimension; if (isPointValid[xy]&&isPointValid[x_1y]&&isPointValid[x_1y_1]&&isPointValid[xy_1]) // check if points of cell are valid { polys->InsertNextCell(3); polys->InsertCellPoint(xy); polys->InsertCellPoint(x_1y); polys->InsertCellPoint(x_1y_1); polys->InsertNextCell(3); polys->InsertCellPoint(xy); polys->InsertCellPoint(x_1y_1); polys->InsertCellPoint(xy_1); } } if (scalarFloatData) { scalarArray->InsertTuple1(pixelID, scalarFloatData[pixel[0]+pixel[1]*xDimension]); } if (this->m_TextureImageHeight > 0.0 && this->m_TextureImageWidth > 0.0) { float xNorm = (((float)pixel[0])/xDimension)*textureScaleCorrection1 + textureScaleCorrection2 ; // correct video texture scale 640 * 480!! float yNorm = 1.0 - ((float)pixel[1])/yDimension; //flip y-axis textureCoords->InsertTuple2(pixelID, xNorm, yNorm); } } pointCount++; } } vtkSmartPointer mesh = vtkSmartPointer::New(); mesh->SetPoints(points); mesh->SetPolys(polys); if (scalarArray->GetNumberOfTuples()>0) { mesh->GetPointData()->SetScalars(scalarArray); if (this->m_TextureImageHeight > 0.0 && this->m_TextureImageWidth > 0.0) { mesh->GetPointData()->SetTCoords(textureCoords); } } output->SetVtkPolyData(mesh); } void mitk::ToFDistanceImageToSurfaceFilter::CreateOutputsForAllInputs() { this->SetNumberOfOutputs(this->GetNumberOfInputs()); // create outputs for all inputs for (unsigned int idx = 0; idx < this->GetNumberOfOutputs(); ++idx) if (this->GetOutput(idx) == NULL) { DataObjectPointer newOutput = this->MakeOutput(idx); this->SetNthOutput(idx, newOutput); } this->Modified(); } void mitk::ToFDistanceImageToSurfaceFilter::GenerateOutputInformation() { this->GetOutput(); itkDebugMacro(<<"GenerateOutputInformation()"); } void mitk::ToFDistanceImageToSurfaceFilter::SetScalarImage(IplImage* iplScalarImage) { this->m_IplScalarImage = iplScalarImage; this->Modified(); } IplImage* mitk::ToFDistanceImageToSurfaceFilter::GetScalarImage() { return this->m_IplScalarImage; } void mitk::ToFDistanceImageToSurfaceFilter::SetTextureImageWidth(int width) { this->m_TextureImageWidth = width; } void mitk::ToFDistanceImageToSurfaceFilter::SetTextureImageHeight(int height) { this->m_TextureImageHeight = height; } diff --git a/Modules/ToFProcessing/mitkToFDistanceImageToSurfaceFilter.h b/Modules/ToFProcessing/mitkToFDistanceImageToSurfaceFilter.h index eb044ba596..88768a5a19 100644 --- a/Modules/ToFProcessing/mitkToFDistanceImageToSurfaceFilter.h +++ b/Modules/ToFProcessing/mitkToFDistanceImageToSurfaceFilter.h @@ -1,144 +1,149 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Module: $RCSfile$ Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __mitkToFDistanceImageToSurfaceFilter_h #define __mitkToFDistanceImageToSurfaceFilter_h #include #include #include -#include "mitkPinholeCameraModel.h" +#include +#include +#include "mitkCameraIntrinsics.h" #include #include namespace mitk { /** * @brief Converts a Time-of-Flight (ToF) distance image to a 3D surface using the pinhole camera model for coordinate computation. * The intrinsic parameters of the camera (FocalLength, PrincipalPoint, InterPixelDistance) are set via SetCameraIntrinsics(). The * measured distance for each pixel corresponds to the distance between the object point and the corresponding image point on the * image plane. * - * Pinhole camera model + * Pinhole camera model * Image plane * * @ingroup SurfaceFilters * @ingroup ToFProcessing */ class mitkToFProcessing_EXPORT ToFDistanceImageToSurfaceFilter : public SurfaceSource { public: - typedef mitk::PinholeCameraModel::ToFScalarType ToFScalarType; mitkClassMacro( ToFDistanceImageToSurfaceFilter , SurfaceSource ); itkNewMacro( Self ); - itkSetMacro(CameraModel, mitk::PinholeCameraModel::Pointer); - itkGetMacro(CameraModel, mitk::PinholeCameraModel::Pointer); + itkSetMacro(CameraIntrinsics, mitk::CameraIntrinsics::Pointer); + itkGetMacro(CameraIntrinsics, mitk::CameraIntrinsics::Pointer); + itkSetMacro(InterPixelDistance,ToFProcessingCommon::ToFPoint2D); + itkGetMacro(InterPixelDistance,ToFProcessingCommon::ToFPoint2D); /*! \brief Set scalar image used as texture of the surface. \param iplScalarImage OpenCV image for texturing */ void SetScalarImage(IplImage* iplScalarImage); /*! \brief Set scalar image used as texture of the surface. \return OpenCV image for texturing */ IplImage* GetScalarImage(); /*! \brief Set width of the scalar image used for texturing the surface \param width width (x-dimension) of the texture image */ void SetTextureImageWidth(int width); /*! \brief Set height of the scalar image used for texturing the surface \param height height (y-dimension) of the texture image */ void SetTextureImageHeight(int height); /*! \brief Sets the input of this filter \param distanceImage input is the distance image of e.g. a ToF camera */ virtual void SetInput( Image* distanceImage); /*! \brief Sets the input of this filter and the intrinsic parameters \param distanceImage input is the distance image of e.g. a ToF camera */ - virtual void SetInput( Image* distanceImage, mitk::PinholeCameraModel::Pointer CameraModel ); + virtual void SetInput( Image* distanceImage, mitk::CameraIntrinsics::Pointer cameraIntrinsics ); /*! \brief Sets the input of this filter at idx \param idx number of the current input \param distanceImage input is the distance image of e.g. a ToF camera */ virtual void SetInput(unsigned int idx, Image* distanceImage); /*! \brief Sets the input of this filter at idx and the intrinsic parameters \param idx number of the current input \param distanceImage input is the distance image of e.g. a ToF camera - \param CameraModel This is the camera model which holds parameters like focal length, pixel size, etc. which are needed for the reconstruction of the surface. + \param cameraIntrinsics This is the camera model which holds parameters like focal length, pixel size, etc. which are needed for the reconstruction of the surface. */ - virtual void SetInput( unsigned int idx, Image* distanceImage, mitk::PinholeCameraModel::Pointer CameraModel ); + virtual void SetInput( unsigned int idx, Image* distanceImage, mitk::CameraIntrinsics::Pointer cameraIntrinsics ); /*! \brief Returns the input of this filter */ Image* GetInput(); /*! \brief Returns the input with id idx of this filter */ Image* GetInput(unsigned int idx); protected: /*! \brief Standard constructor */ ToFDistanceImageToSurfaceFilter(); /*! \brief Standard destructor */ ~ToFDistanceImageToSurfaceFilter(); virtual void GenerateOutputInformation(); /*! \brief Method generating the output of this filter. Called in the updated process of the pipeline. This method generates the output of the ToFSurfaceSource: The generated surface of the 3d points */ virtual void GenerateData(); /** * \brief Create an output for each input * * This Method sets the number of outputs to the number of inputs * and creates missing outputs objects. * \warning any additional outputs that exist before the method is called are deleted */ void CreateOutputsForAllInputs(); IplImage* m_IplScalarImage; ///< Scalar image used for surface texturing - mitk::PinholeCameraModel::Pointer m_CameraModel; ///< Specifies the intrinsic parameters + mitk::CameraIntrinsics::Pointer m_CameraIntrinsics; ///< Specifies the intrinsic parameters + //mitk::CameraIntrinsics::Pointer m_CameraModel; ///< Specifies the intrinsic parameters int m_TextureImageWidth; ///< Width (x-dimension) of the texture image int m_TextureImageHeight; ///< Height (y-dimension) of the texture image + ToFProcessingCommon::ToFPoint2D m_InterPixelDistance; ///< distance in mm between two adjacent pixels on the ToF camera chip }; } //END mitk namespace #endif