C++下使用PCL库和OpenCV库查看图像的色彩分布情况
在学习彩色图像处理的过程中看到许多对图像中像素rgb颜色分布的可视化处理,于是借助OpenCV库和PCL点云库进行了一个类似的效果生成。特此记录相关代码以备查用。
如何安装OpenCV和PCL库csdn都有很多教程,此处不在赘述。
话不多说,直接上代码。
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <opencv2/opencv.hpp>
using namespace cv;
void draw_line(pcl::PointCloud<pcl::PointXYZRGB>::Ptr& cloud, Mat src);
int main() {
// 创建点云对象彩色RGB类型
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
Mat src = imread("book.jpg");//你要显示的图像
//显示书本图像,名称你可以修改
imshow("book", src);
//由于点云显示是RGB的,所以色彩空间需要转化一下
cvtColor(src, src, COLOR_BGR2RGB);
// 设置点云大小
int n_points = src.cols*src.rows+256*12;//总的像素数目 增加了外框256*12个点
cloud->width = n_points;
cloud->height = 1;
cloud->points.resize(n_points);
// 根据RGB确定坐标
for (int i = 0; i < src.rows; i++)
for (int j = 0; j < src.cols;j++)
{
//设置点的XYZ坐标
cloud->points[i* src.cols+j].x = src.at<Vec3b>(i,j)[0];
cloud->points[i * src.cols + j].y = src.at<Vec3b>(i, j)[1];
cloud->points[i * src.cols + j].z = src.at<Vec3b>(i, j)[2];
//设置点的RGB颜色
cloud->points[i * src.cols + j].r = src.at<Vec3b>(i, j)[0];
cloud->points[i * src.cols + j].g = src.at<Vec3b>(i, j)[1];
cloud->points[i * src.cols + j].b = src.at<Vec3b>(i, j)[2];
}
draw_line(cloud, src);
// 创建可视化对象
pcl::visualization::PCLVisualizer viewer("RGB Viewer");
//设置背景为白色
viewer.setBackgroundColor(1.0, 1.0, 1.0);
// 设置点云颜色
pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgb(cloud);
// 添加点云到可视化窗口
viewer.addPointCloud<pcl::PointXYZRGB>(cloud, rgb, "random_cloud");
// 设置点云渲染属性,数字表示显示的点的大小
viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "random_cloud");
// 启动可视化窗口
while (!viewer.wasStopped()) {
viewer.spinOnce();
}
waitKey(0);
// 保存点云为pcd文件,注释掉就不保存了,名称你要可以修改
pcl::io::savePCDFileASCII("book.pcd", *cloud);
destroyAllWindows();
return 0;
}
//绘制边缘的彩色线,可以选择不运行这个函数
void draw_line(pcl::PointCloud<pcl::PointXYZRGB>::Ptr& cloud,Mat src)
{
//绘制12条彩色边线
for (int i = 0; i < 256; i++)
{
cloud->points[src.cols * src.rows + i].x = 0;
cloud->points[src.cols * src.rows + i].y = 0;
cloud->points[src.cols * src.rows + i].z = i;
cloud->points[src.cols * src.rows + i].r = 0;
cloud->points[src.cols * src.rows + i].g = 0;
cloud->points[src.cols * src.rows + i].b = i;
}
for (int i = 0; i < 256; i++)
{
cloud->points[src.cols * src.rows + i+256].x = i;
cloud->points[src.cols * src.rows + i+256].y = 0;
cloud->points[src.cols * src.rows + i+256].z = 0;
cloud->points[src.cols * src.rows + i + 256].r = i;
cloud->points[src.cols * src.rows + i + 256].g = 0;
cloud->points[src.cols * src.rows + i + 256].b = 0;
}
for (int i = 0; i < 256; i++)
{
cloud->points[src.cols * src.rows + i+256*2].x = 0;
cloud->points[src.cols * src.rows + i + 256 * 2].y = i;
cloud->points[src.cols * src.rows + i + 256 * 2].z = 0;
cloud->points[src.cols * src.rows + i + 256 * 2].r = 0;
cloud->points[src.cols * src.rows + i + 256 * 2].g = i;
cloud->points[src.cols * src.rows + i + 256 * 2].b = 0;
}
for (int i = 0; i < 256; i++)
{
cloud->points[src.cols * src.rows + i + 256 * 2].x = 0;
cloud->points[src.cols * src.rows + i + 256 * 2].y = i;
cloud->points[src.cols * src.rows + i + 256 * 2].z = 0;
cloud->points[src.cols * src.rows + i + 256 * 2].r = 0;
cloud->points[src.cols * src.rows + i + 256 * 2].g = i;
cloud->points[src.cols * src.rows + i + 256 * 2].b = 0;
}
for (int i = 0; i < 256; i++)
{
cloud->points[src.cols * src.rows + i + 256 * 3].x = i;
cloud->points[src.cols * src.rows + i + 256 * 3].y = 255;
cloud->points[src.cols * src.rows + i + 256 * 3].z = 255;
cloud->points[src.cols * src.rows + i + 256 * 3].r = i;
cloud->points[src.cols * src.rows + i + 256 * 3].g = 255;
cloud->points[src.cols * src.rows + i + 256 * 3].b = 255;
}
for (int i = 0; i < 256; i++)
{
cloud->points[src.cols * src.rows + i + 256 * 4].x = 255;
cloud->points[src.cols * src.rows + i + 256 * 4].y = i;
cloud->points[src.cols * src.rows + i + 256 * 4].z = 255;
cloud->points[src.cols * src.rows + i + 256 * 4].r = 255;
cloud->points[src.cols * src.rows + i + 256 * 4].g = i;
cloud->points[src.cols * src.rows + i + 256 * 4].b = 255;
}
for (int i = 0; i < 256; i++)
{
cloud->points[src.cols * src.rows + i + 256 * 5].x = 255;
cloud->points[src.cols * src.rows + i + 256 * 5].y = 255;
cloud->points[src.cols * src.rows + i + 256 * 5].z = i;
cloud->points[src.cols * src.rows + i + 256 * 5].r = 255;
cloud->points[src.cols * src.rows + i + 256 * 5].g = 255;
cloud->points[src.cols * src.rows + i + 256 * 5].b = i;
}
for (int i = 0; i < 256; i++)
{
cloud->points[src.cols * src.rows + i + 256 * 6].x = 0;
cloud->points[src.cols * src.rows + i + 256 * 6].y = 255;
cloud->points[src.cols * src.rows + i + 256 * 6].z = i;
cloud->points[src.cols * src.rows + i + 256 * 6].r = 0;
cloud->points[src.cols * src.rows + i + 256 * 6].g = 255;
cloud->points[src.cols * src.rows + i + 256 * 6].b = i;
}
for (int i = 0; i < 256; i++)
{
cloud->points[src.cols * src.rows + i + 256 * 7].x = 255;
cloud->points[src.cols * src.rows + i + 256 * 7].y = 0;
cloud->points[src.cols * src.rows + i + 256 * 7].z = i;
cloud->points[src.cols * src.rows + i + 256 * 7].r = 255;
cloud->points[src.cols * src.rows + i + 256 * 7].g = 0;
cloud->points[src.cols * src.rows + i + 256 * 7].b = i;
}
for (int i = 0; i < 256; i++)
{
cloud->points[src.cols * src.rows + i + 256 * 8].x = i;
cloud->points[src.cols * src.rows + i + 256 * 8].y = 0;
cloud->points[src.cols * src.rows + i + 256 * 8].z = 255;
cloud->points[src.cols * src.rows + i + 256 * 8].r = i;
cloud->points[src.cols * src.rows + i + 256 * 8].g = 0;
cloud->points[src.cols * src.rows + i + 256 * 8].b = 255;
}
for (int i = 0; i < 256; i++)
{
cloud->points[src.cols * src.rows + i + 256 * 9].x = i;
cloud->points[src.cols * src.rows + i + 256 * 9].y = 255;
cloud->points[src.cols * src.rows + i + 256 * 9].z = 0;
cloud->points[src.cols * src.rows + i + 256 * 9].r = i;
cloud->points[src.cols * src.rows + i + 256 * 9].g = 255;
cloud->points[src.cols * src.rows + i + 256 * 9].b = 0;
}
for (int i = 0; i < 256; i++)
{
cloud->points[src.cols * src.rows + i + 256 * 10].x = 0;
cloud->points[src.cols * src.rows + i + 256 * 10].y = i;
cloud->points[src.cols * src.rows + i + 256 * 10].z = 255;
cloud->points[src.cols * src.rows + i + 256 * 10].r = 0;
cloud->points[src.cols * src.rows + i + 256 * 10].g = i;
cloud->points[src.cols * src.rows + i + 256 * 10].b = 255;
}
for (int i = 0; i < 256; i++)
{
cloud->points[src.cols * src.rows + i + 256 * 11].x = 255;
cloud->points[src.cols * src.rows + i + 256 * 11].y = i;
cloud->points[src.cols * src.rows + i + 256 * 11].z = 0;
cloud->points[src.cols * src.rows + i + 256 * 11].r = 255;
cloud->points[src.cols * src.rows + i + 256 * 11].g = i;
cloud->points[src.cols * src.rows + i + 256 * 11].b = 0;
}
}
效果图如下(注意,在显示的点云框中可以旋转观察点云):