效果
头文件GrayVirsual.h
#pragma once
#include <QtWidgets/QMainWindow>
#include <QVTKOpenGLNativeWidget.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <vtkImageData.h>
#include <vtkImageDataGeometryFilter.h>
#include <vtkWarpScalar.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/visualization/cloud_viewer.h>
class GrayVirsual : public QMainWindow
{
Q_OBJECT
public:
GrayVirsual(QWidget* parent = nullptr);
~GrayVirsual();
private:
pcl::visualization::PCLVisualizer::Ptr grayViewer;
pcl::PointCloud<pcl::PointXYZRGB>::Ptr grayCloud;
pcl::visualization::PCLVisualizer::Ptr hsvViewer;
pcl::PointCloud<pcl::PointXYZRGB>::Ptr hsvCloud;
pcl::visualization::PCLVisualizer::Ptr hViewer;
pcl::PointCloud<pcl::PointXYZRGB>::Ptr hCloud;
pcl::visualization::PCLVisualizer::Ptr vViewer;
pcl::PointCloud<pcl::PointXYZRGB>::Ptr vCloud;
QWidget* centralWidget;
QVTKOpenGLNativeWidget* vtkWidget;
void loadImage(const QString& fileName);
};
实现GrayVirsual.cpp
#include "GrayVirsual.h"
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QMessageBox>
#include <vtkInformation.h>
#include <vtkAxesActor.h>
#include <vtkNamedColors.h>
#include <vtkProperty.h>
#include <vtkRenderer.h>
#include <vtkRendererCollection.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkAxesActor.h>
#include <vtkOBJReader.h>
#include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>
#include <pcl/io/vtk_io.h>
#include <pcl/filters/statistical_outlier_removal.h>
#include <pcl/filters/passthrough.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/segmentation/extract_clusters.h>
#include <pcl/search/kdtree.h>
#include <pcl/features/normal_3d.h>
#include <pcl/common/transforms.h>
#include <pcl/surface/gp3.h>
#include <pcl/surface/poisson.h>
#include <pcl/surface/mls.h>
#include <pcl/surface/marching_cubes_hoppe.h>
#include <pcl/surface/marching_cubes_rbf.h>
GrayVirsual::GrayVirsual(QWidget* parent)
: QMainWindow(parent)
{
centralWidget = new QWidget(this);
vtkWidget = new QVTKOpenGLNativeWidget(this);
this->resize(600, 400);
this->setCentralWidget(centralWidget);
QVBoxLayout* vbox = new QVBoxLayout(this);
QHBoxLayout* hBoxLayout = new QHBoxLayout(this);
QLabel* label = new QLabel(this);
label->setText("路径:");
QLineEdit* pathEdit = new QLineEdit(this);
pathEdit->setMaximumHeight(30);
QPushButton* pushButton = new QPushButton(this);
pushButton->setText("加载");
connect(pushButton, &QPushButton::clicked, [this, pathEdit = pathEdit]() {
loadImage(pathEdit->text());
});
hBoxLayout->addWidget(label);
hBoxLayout->addWidget(pathEdit);
hBoxLayout->addWidget(pushButton);
hBoxLayout->setSpacing(10);
hBoxLayout->setSizeConstraint(QLayout::SetMaximumSize);
hBoxLayout->addStretch(0);
vbox->addLayout(hBoxLayout);
vbox->addWidget(vtkWidget);
vtkWidget->setMinimumSize({ 400,300 });
centralWidget->setLayout(vbox);
grayCloud.reset(new pcl::PointCloud<pcl::PointXYZRGB>);
hsvCloud.reset(new pcl::PointCloud<pcl::PointXYZRGB>);
hCloud.reset(new pcl::PointCloud<pcl::PointXYZRGB>);
vCloud.reset(new pcl::PointCloud<pcl::PointXYZRGB>);
auto renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
auto grayRenderer = vtkSmartPointer<vtkRenderer>::New();
grayViewer = pcl::visualization::PCLVisualizer::Ptr(new pcl::visualization::PCLVisualizer(
grayRenderer
, renderWindow, "", false));
grayViewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "grayCloud");
grayViewer->addPointCloud(grayCloud, "grayCloud");
grayRenderer->SetViewport(0, 0, .5, .5);
auto hsvRenderer = vtkSmartPointer<vtkRenderer>::New();
hsvViewer = pcl::visualization::PCLVisualizer::Ptr(new pcl::visualization::PCLVisualizer(
hsvRenderer
, renderWindow, "", false));
hsvViewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "hsvCloud");
hsvViewer->addPointCloud(hsvCloud, "hsvCloud");
hsvRenderer->SetViewport(.5, 0, 1, .5);
auto hViewerRenderer = vtkSmartPointer<vtkRenderer>::New();
hViewer = pcl::visualization::PCLVisualizer::Ptr(new pcl::visualization::PCLVisualizer(
hViewerRenderer
, renderWindow, "", false));
hViewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "hViewer");
hViewer->addPointCloud(hCloud, "hCloud");
hViewerRenderer->SetViewport(0, .5, .5, 1);
auto vViewerRenderer = vtkSmartPointer<vtkRenderer>::New();
vViewer = pcl::visualization::PCLVisualizer::Ptr(new pcl::visualization::PCLVisualizer(
vViewerRenderer
, renderWindow, "", false));
vViewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "vViewer");
vViewer->addPointCloud(vCloud, "vCloud");
vViewerRenderer->SetViewport(.5, .5, 1, 1);
vtkWidget->setRenderWindow(renderWindow);
grayViewer->setupInteractor(vtkWidget->interactor(), vtkWidget->renderWindow());
hsvViewer->setupInteractor(vtkWidget->interactor(), vtkWidget->renderWindow());
hViewer->setupInteractor(vtkWidget->interactor(), vtkWidget->renderWindow());
vViewer->setupInteractor(vtkWidget->interactor(), vtkWidget->renderWindow());
vtkNew<vtkAxesActor> grayAxes, hsvAxes, hAxes, vAxes;
grayAxes->SetTotalLength(1, 1, 1);
hsvAxes->SetTotalLength(1, 1, 1);
hAxes->SetTotalLength(1, 1, 1);
vAxes->SetTotalLength(1, 1, 1);
grayRenderer->AddActor(grayAxes);
hsvRenderer->AddActor(hsvAxes);
hViewerRenderer->AddActor(hAxes);
vViewerRenderer->AddActor(vAxes);
renderWindow->AddRenderer(grayRenderer);
renderWindow->AddRenderer(hsvRenderer);
renderWindow->AddRenderer(hViewerRenderer);
renderWindow->AddRenderer(vViewerRenderer);
}
GrayVirsual::~GrayVirsual()
{}
void GrayVirsual::loadImage(const QString& fileName)
{
cv::Mat image = cv::imread(fileName.toStdString());
if (image.empty())
{
QMessageBox::information(this, "提示", "加载图片失败");
return;
}
cv::Mat grayImage;
cv::cvtColor(image, grayImage, cv::COLOR_BGR2GRAY);
grayCloud.reset(new pcl::PointCloud<pcl::PointXYZRGB>);
for (int i = 0; i < grayImage.rows; i++)
{
for (int j = 0; j < grayImage.cols; j++)
{
grayCloud->push_back({ static_cast<float>(i),
static_cast<float>(j),
static_cast<float>(grayImage.at<uchar>(i, j)),
255,255,255 });
}
}
for (int i = 0; i < grayCloud->size(); i++)
{
grayCloud->points[i].x /= 255;
grayCloud->points[i].y /= 255;
grayCloud->points[i].z /= 255;
}
grayViewer->updatePointCloud(grayCloud, "grayCloud");
cv::Mat vImg;
cv::Mat vKernel = (cv::Mat_<float>(3, 3) << -1, 0, 1, -1, 0, 1, -1, 0, 1);
cv::filter2D(grayImage, vImg, image.depth(), vKernel);
vCloud.reset(new pcl::PointCloud<pcl::PointXYZRGB>);
for (int i = 0; i < vImg.rows; i++)
{
for (int j = 0; j < vImg.cols; j++)
{
vCloud->push_back({ static_cast<float>(i),
static_cast<float>(j),
static_cast<float>(vImg.at<uchar>(i, j)),
255,255,255 });
}
}
for (int i = 0; i < vCloud->size(); i++)
{
vCloud->points[i].x /= 255;
vCloud->points[i].y /= 255;
vCloud->points[i].z /= 255;
}
vViewer->updatePointCloud(vCloud, "vCloud");
cv::Mat hImg;
cv::Mat hKernel = (cv::Mat_<float>(3, 3) << -1, -1, -1, 0, 0, 0, 1, 1, 1);
cv::filter2D(grayImage, hImg, image.depth(), hKernel);
hCloud.reset(new pcl::PointCloud<pcl::PointXYZRGB>);
for (int i = 0; i < hImg.rows; i++)
{
for (int j = 0; j < hImg.cols; j++)
{
hCloud->push_back({ static_cast<float>(i),
static_cast<float>(j),
static_cast<float>(hImg.at<uchar>(i, j)),
255,255,255 });
}
}
for (int i = 0; i < hCloud->size(); i++)
{
hCloud->points[i].x /= 255;
hCloud->points[i].y /= 255;
hCloud->points[i].z /= 255;
}
hViewer->updatePointCloud(hCloud, "hCloud");
cv::Mat hsv;
cv::cvtColor(image, hsv, cv::COLOR_BGR2HSV);
cv::Mat mask;
cv::inRange(hsv, cv::Scalar{ 40, 70, 46 }, cv::Scalar{ 77, 255, 255 }, mask);
cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
cv::erode(mask, mask, element);
cv::Mat mask_and;
cv::bitwise_and(image, image, mask_and, mask);
cv::medianBlur(mask_and, image, 3);
cv::cvtColor(image, grayImage, cv::COLOR_BGR2GRAY);
hsvCloud.reset(new pcl::PointCloud<pcl::PointXYZRGB>);
for (int i = 0; i < grayImage.rows; i++)
{
for (int j = 0; j < grayImage.cols; j++)
{
hsvCloud->push_back({ static_cast<float>(i),
static_cast<float>(j),
static_cast<float>(grayImage.at<uchar>(i, j)),
255,255,255 });
}
}
for (int i = 0; i < hsvCloud->size(); i++)
{
hsvCloud->points[i].x /= 255;
hsvCloud->points[i].y /= 255;
hsvCloud->points[i].z /= 255;
}
hsvViewer->updatePointCloud(hsvCloud, "hsvCloud");
}
跪求优雅的图片转点云的方式!!!