1.配准效果图
2.LandMarker配准代码
#include <QCoreApplication>
#include <QDebug>
#include <iostream>
#include <sstream>
#include <QtCore>
#include "ndi_capi.h"
#include "pointclouddata.h"
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "tempframe.h"
#include "tempdataprocessor.h"
#include "tempdatarepository.h"
#include "tempthread001.h"
#include "registrationpointcloud.h"
#include <QMainWindow>
#include <QWidget>
#include <QGuiApplication>
#include <QQuickView>
#include <QtQml>
#include <QQmlApplicationEngine>
//vtk
#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkCylinderSource.h>
#include <vtkNamedColors.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <array>
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkRenderingFreeType);
VTK_MODULE_INIT(vtkInteractionStyle);
#include <vtkSmartPointer.h>
#include <vtkPolyDataReader.h>
#include <vtkPolyData.h>
#include <vtkTransform.h>
#include <vtkTransformPolyDataFilter.h>
#include <vtkVertexGlyphFilter.h>
#include <vtkIterativeClosestPointTransform.h>
#include <vtkLandmarkTransform.h>
#include <vtkTransformPolyDataFilter.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkAxesActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkOrientationMarkerWidget.h> //坐标系交互
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
qmlRegisterType<TempFrame>("qian.qml.TempInterface", 1, 0, "TempFrame");
qmlRegisterType<Tool>("qian.qml.TempInterface", 1, 0, "Tool");
qmlRegisterType<MyStrayMarker>("qian.qml.TempInterface", 1, 0, "MyStrayMarker");
QGuiApplication app(argc, argv);
// QObject *w= new QObject();
// TempThread001 *m_tempThread;
// m_tempThread = new TempThread001(w);
// TempDataProcessor *m_tempDataProcessor=new TempDataProcessor();
// TempDataRepository *m_tempDataRepository=new TempDataRepository();
// m_tempDataProcessor->setTempDataRepository(m_tempDataRepository);
// m_tempThread->setTempDataProcessor(m_tempDataProcessor);
// m_tempThread->start();
// QQmlApplicationEngine engine;
// engine.rootContext()->setContextProperty("NDI_DataRepository",m_tempDataRepository);
// engine.rootContext()->setContextProperty("NDI_DataProcessor",m_tempDataProcessor);
// engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
// if (engine.rootObjects().isEmpty())
// return -1;
vtkSmartPointer<vtkPoints> sourcePoints =
vtkSmartPointer<vtkPoints>::New();
double sourcePoint1[3] = { 0.5, 0, 0 };
sourcePoints->InsertNextPoint(sourcePoint1);
double sourcePoint2[3] = { 0, 0.5, 0 };
sourcePoints->InsertNextPoint(sourcePoint2);
double sourcePoint3[3] = { 0, 0, 0.5 };
sourcePoints->InsertNextPoint(sourcePoint3);
vtkSmartPointer<vtkPoints> targetPoints =
vtkSmartPointer<vtkPoints>::New();
double targetPoint1[3] = { 0.0, 0.0, 0.55 };
targetPoints->InsertNextPoint(targetPoint1);
double targetPoint2[3] = { 0.0, 0.55, 0.0 };
targetPoints->InsertNextPoint(targetPoint2);
double targetPoint3[3] = { -0.55, 0.0, 0.0 };
targetPoints->InsertNextPoint(targetPoint3);
//利用Landmark算法求变换矩阵
vtkSmartPointer<vtkLandmarkTransform> landmarkTransform =
vtkSmartPointer<vtkLandmarkTransform>::New();
landmarkTransform->SetSourceLandmarks(sourcePoints);
landmarkTransform->SetTargetLandmarks(targetPoints);
landmarkTransform->SetModeToRigidBody(); //执行刚体配准
landmarkTransform->Update();
构造PolyData类型 进行图形可视化
vtkSmartPointer<vtkPolyData> source =
vtkSmartPointer<vtkPolyData>::New();
source->SetPoints(sourcePoints);
vtkSmartPointer<vtkPolyData> target =
vtkSmartPointer<vtkPolyData>::New();
target->SetPoints(targetPoints);
/
vtkSmartPointer<vtkVertexGlyphFilter> sourceGlyphFilter =
vtkSmartPointer<vtkVertexGlyphFilter>::New();
sourceGlyphFilter->SetInputData(source);
sourceGlyphFilter->Update();
vtkSmartPointer<vtkVertexGlyphFilter> targetGlyphFilter =
vtkSmartPointer<vtkVertexGlyphFilter>::New();
targetGlyphFilter->SetInputData(target);
targetGlyphFilter->Update();
源数据施加配准变换矩阵
vtkSmartPointer<vtkTransformPolyDataFilter> transformFilter =
vtkSmartPointer<vtkTransformPolyDataFilter>::New();
transformFilter->SetInputData(sourceGlyphFilter->GetOutput());
transformFilter->SetTransform(landmarkTransform);
transformFilter->Update();
/
vtkSmartPointer<vtkPolyDataMapper> sourceMapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
sourceMapper->SetInputConnection(sourceGlyphFilter->GetOutputPort());
vtkSmartPointer<vtkActor> sourceActor =
vtkSmartPointer<vtkActor>::New();
sourceActor->SetMapper(sourceMapper);
sourceActor->GetProperty()->SetColor(1, 1, 0);
sourceActor->GetProperty()->SetPointSize(6);
vtkSmartPointer<vtkPolyDataMapper> targetMapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
targetMapper->SetInputConnection(targetGlyphFilter->GetOutputPort());
vtkSmartPointer<vtkActor> targetActor =
vtkSmartPointer<vtkActor>::New();
targetActor->SetMapper(targetMapper);
targetActor->GetProperty()->SetColor(0, 1, 0);
targetActor->GetProperty()->SetPointSize(6);
vtkSmartPointer<vtkPolyDataMapper> solutionMapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
solutionMapper->SetInputConnection(transformFilter->GetOutputPort());
vtkSmartPointer<vtkActor> solutionActor =
vtkSmartPointer<vtkActor>::New();
solutionActor->SetMapper(solutionMapper);
solutionActor->GetProperty()->SetColor(1, 0, 0);
solutionActor->GetProperty()->SetPointSize(6);
vtkSmartPointer<vtkRenderer> render =
vtkSmartPointer<vtkRenderer>::New();
render->AddActor(sourceActor);
render->AddActor(targetActor);
render->AddActor(solutionActor);
render->SetBackground(0, 0, 0);
vtkSmartPointer<vtkRenderWindow> rw =
vtkSmartPointer<vtkRenderWindow>::New();
rw->AddRenderer(render);
rw->SetSize(480, 480);
rw->SetWindowName("Regisration by Landmark");
//设置坐标系显示功能
vtkSmartPointer<vtkAxesActor> axes =
vtkSmartPointer<vtkAxesActor>::New();
axes->SetScale(10);
render->AddActor(axes);
vtkSmartPointer<vtkRenderWindowInteractor> rwi =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
rwi->SetRenderWindow(rw);
/************************************************************/
vtkSmartPointer<vtkOrientationMarkerWidget> widget =
vtkSmartPointer<vtkOrientationMarkerWidget>::New();
widget->SetOutlineColor(0.9300, 0.5700, 0.1300);
widget->SetOrientationMarker(axes);
widget->SetInteractor(rwi); //加入鼠标交互
widget->SetViewport(0.0, 0.0, 0.3, 0.3); //设置显示位置
widget->SetEnabled(1);
widget->InteractiveOn();//开启鼠标交互
/************************************************************/
render->ResetCamera();
rw->Render();
rwi->Initialize();
rwi->Start();
return app.exec();
}
3.camke文件
cmake_minimum_required(VERSION 3.0.0)
project(capi_test VERSION 0.1 LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
find_package(Qt5Core)
find_package(Qt5Quick REQUIRED)
find_package(Qt5Widgets REQUIRED)
find_package(Qt5Qml REQUIRED)
find_package(Qt5QuickControls2 REQUIRED)
find_package(Qt5QuickWidgets REQUIRED)
find_package(VTK 8.1 REQUIRED NO_MODULE)
#find_package(VTK COMPONENTS
# vtkCommonColor
# vtkCommonCore
# vtkFiltersSources
# vtkInteractionStyle
# vtkRenderingContextOpenGL2
# vtkRenderingCore
# vtkRenderingFreeType
# vtkRenderingGL2PSOpenGL2
# vtkRenderingOpenGL2 QUIET)
if (NOT VTK_FOUND)
message("Skipping CylinderExample: ${VTK_NOT_FOUND_MESSAGE}")
return ()
endif()
message (STATUS "VTK_VERSION: ${VTK_VERSION}")
#添加source和inc
include_directories("./*.h")
set(project_SOURCES main.cpp ndi_capi.cpp pointclouddata.cpp tempframe.cpp tempthread001.cpp tempdataprocessor.cpp tempdatarepository.cpp registrationpointcloud.cpp )
# Set the output directory structure
set(BUILD_OUTPUT_DIRECTORY build-output)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${BUILD_OUTPUT_DIRECTORY})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${BUILD_OUTPUT_DIRECTORY})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${BUILD_OUTPUT_DIRECTORY})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${BUILD_OUTPUT_DIRECTORY})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${BUILD_OUTPUT_DIRECTORY})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${BUILD_OUTPUT_DIRECTORY})
# Set the preprocessor flag we need when creating the library
add_definitions(-DCAPICOMMON_EXPORTS)
# Include the header files
include_directories("CAPIcommon/include" "CAPIcommon/src/include")
# Set the $SOURCES_NDLINK variable using file(GLOB...) with wildcards
file(GLOB SOURCES_CAPICOMMON "CAPIcommon/src/*.cpp")
# Generate a shared library from the sources
add_library(CAPIcommon SHARED ${SOURCES_CAPICOMMON})
# ${PROJECT_NAME} 为生成的可执行文件名字
#add_executable(${PROJECT_NAME} ${project_SOURCES} "qml.qrc")
#target_link_libraries(${PROJECT_NAME} Qt5::Core CAPIcommon Qt5::Quick Qt5::Widgets Qt5::Qml Qt5::QuickControls2 Qt5::QuickWidgets)
if (VTK_VERSION VERSION_LESS "8.90.0")
# old system
include(${VTK_USE_FILE})
add_executable(${PROJECT_NAME} MACOSX_BUNDLE ${project_SOURCES})
target_link_libraries(${PROJECT_NAME} ${VTK_LIBRARIES} Qt5::Core CAPIcommon Qt5::Quick Qt5::Widgets Qt5::Qml Qt5::QuickControls2 Qt5::QuickWidgets )
else ()
# include all components
add_executable(${PROJECT_NAME} MACOSX_BUNDLE )
target_link_libraries(${PROJECT_NAME} ${VTK_LIBRARIES})
# vtk_module_autoinit is needed
vtk_module_autoinit(
TARGETS ${PROJECT_NAME}
MODULES ${VTK_LIBRARIES}
)
endif ()
#添加SerialPort模块 下面整句添加
qt5_use_modules(${PROJECT_NAME} Core SerialPort)
# Copy .rom files so the built binaries can use them
file(COPY sroms DESTINATION ${BUILD_OUTPUT_DIRECTORY})