当前位置:网站首页>Qt+VTK+PCL图片转灰度图且以灰度为Y轴显示
Qt+VTK+PCL图片转灰度图且以灰度为Y轴显示
2022-07-22 21:36:00 【windSnowLi】
效果

头文件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 });
}
}
// 点坐标同除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 });
}
}
// 点坐标同除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 });
}
}
// 点坐标同除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;
// 转为 HSV
cv::cvtColor(image, hsv, cv::COLOR_BGR2HSV);
cv::Mat mask;
// HSV 筛选掩膜
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 });
}
}
// 点坐标同除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");
}
跪求优雅的图片转点云的方式!!!
边栏推荐
- scala 主构造器_Scala主构造器深度
- 2022年暑假ACM热身练习4(总结)
- Inside the hard core of LAN SDN technology - evpn implementation of 16 three from thing to person user roaming in the park
- “蔚来杯“2022牛客暑期多校训练营1 (部分题目总结)
- Uniapp switches the tab bar to display different pages, remembers the page location and pulls up to get new data
- Problems encountered in punching
- Classes and objects (1)
- JVM监控工具介绍jstack, jconsole, jinfo, jmap, jdb, jstat
- 初出茅庐的小李第111篇博客之中英文点阵字符显示原理
- FTXUI基础笔记(hello world)
猜你喜欢

Alibaba Cloud Security Center's best practices for vulnerability repair

FTXUI基础笔记(hello world)

Uniapp switches the tab bar to display different pages, remembers the page location and pulls up to get new data

(五)数电——公式化简法

93. (leaflet chapter) leaflet situation plotting - modification of attack direction

沃尔沃xc90的安全性如何?一起来看看吧
![[record of question brushing] 18. Sum of four numbers](/img/51/1be89efe609572a8b71f2f7c386711.png)
[record of question brushing] 18. Sum of four numbers

大厂底层必修:“应用程序与 AMS 的通讯实现”

Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE)

scala idea提示函数参数
随机推荐
局域网SDN技术硬核内幕 5 虚拟化网络的实现
ETL tool (data synchronization)
“蔚来杯“2022牛客暑期多校训练营1 (部分题目总结)
RN底层原理 -- 1. Component和PureComponent解析
局域网SDN技术硬核内幕 8 从二层交换到三层路由
93. (leaflet chapter) leaflet situation plotting - modification of attack direction
主题域模型
百度搜索打击盗版网文站点:互联网内容侵权现象为何屡禁不止
我是如何在一周内拿到4份offer的?
网络安全之ARP欺骗防护
Kubernetes deployment strategy
不会吧?钉钉都下载了,你还不知道可以这样玩?
Information system project managers must recite the core examination points (49) contract law
About redis, do you update the database first or the cache first?
Talking about performance optimization: analysis and optimization of APP startup process
驱动页面性能优化的3个有效策略
模拟Not All Endpoints Registered异常及解决方案
2022年暑假ACM热身练习4(总结)
2022 employment season surprise! The genuine Adobe software can finally be used for nothing
How to use the order flow analysis tool (Part 2)