ros opencv qt yaml综合运用之滤波

本文是针对前面三篇所写内容:

1、三种方法在ROS中加载Qt库进行GUI设计

2、运用ROS和OpenCV进行简单的图像处理之检测

3、在ROS中处理yaml文件

进行的一个结合,来综合运用ros,opencv,qt和yaml-cpp库。

 

首先用catkin_create_pkg命令新建一个ROS工程,然后CMakeLists.txt文件中,依次包含opencv,qt和yaml-cpp,这个比较容易,前面三篇文章也有说明。

其次是在QtGUI中显示opencv图像,一般是用Label控件。这里涉及到另外一个问题,需将opencv中的图像转换为QImage,QImage支持大部分的图像格式,再用QPixmap显示到控件上。图像编码格式每个库又有每个库自己的标准,因此经常会遇上显示不正常的问题。

比较好的做法是根据图像通道进行判断,关键代码如下:

cv::Mat cvImage;

...  //一些图像处理操作

QImage qImg = QImage(cvImage.cols, cvImage.rows, QImage::Format_RGB32);
unsigned char *ptrQImage = qImg.bits();
if (1 == cvImage.channels())
{
	for(int row = 0; row < cvImage.rows; row++)
	{  
		unsigned char *ptr=(unsigned char*)(cvImage.data + row * cvImage.step1());
		for(int col = 0; col < cvImage.cols; col++)
		{  
			*(ptrQImage) = *(ptr+col);
			*(ptrQImage+1) = *(ptr+col);
			*(ptrQImage+2) = *(ptr+col);
			*(ptrQImage+3) = 0;
			ptrQImage += 4;
		}
	}
}
else if (3 == cvImage.channels())
{
	for(int row = 0; row < cvImage.rows; row++)
	{  
		unsigned char *ptr=(unsigned char*)(cvImage.data + row * cvImage.step1());
		for(int col = 0; col < cvImage.cols; col++)
		{  
			*(ptrQImage) = *(ptr+col*3);
			*(ptrQImage+1) = *(ptr+col*3+1);
			*(ptrQImage+2) = *(ptr+col*3+2);
			*(ptrQImage+3) = 0;
			ptrQImage += 4;
		}
	}
}

ui->label->setPixmap(QPixmap::fromImage(qImg));

QImage中的format有如下:

QImage::Format_Invalid 图像无效
QImage::Format_Mono 存储使用1位每像素的图像,字节填充最重要位第一
QImage::Format_MonoLSB 存储使用1位每像素的图像,字节填充不显著位第一
QImage::Format_Indexed8 图像存储使用8位指标转化成Colormap
QImage::Format_RGB32 存储使用32位RGB格式的图像(0xffrrggbb)
QImage::Format_ARGB32 存储使用32为ARGB格式的图像(0xaarrggbb)
QImage::Format_ARGB32_Premultiplied 图像存储使用一个自左乘32位ARGB格式
QImage::Format_RGB16 图像存储使用5-6-5 16位RGB格式
QImage::Format_ARGB8565_Premultiplied 图像存储使用一个自左乘24位ARGB格式8-5-6-5
QImage::Format_RGB666 图像存储使用6-6-6 24位RGB格式,未使用的最重要的位总是为零
QImage::Format_ARGB6666_Premultiplied 图像存储使用一个自左乘24位ARGB格式6-6-6-6
QImage::Format_RGB555 图像存储使用16位RGB格式(5-5-5),位置用的最重要的始终为零
QImage::Format_ARGB8555_Premultiplied 图像存储使用一个自左乘24位ARGB格式8-5-5-5
QImage::Format_RGB888 图像存储使用8-8-8 24位RGB格式
QImage::Format_RGB444 图像存储使用16位RGB格式(4-4-4)未使用的位始终为零
QImage::Format_ARGB4444_Premultiplied 图像存储使用一个自左乘16位ARGB格式4-4-4-4
QImage::Format_RGBX8888 图像存储使用32位字节命令RGB(x)格式8-8-8-8
QImage::Format_RGBA8888 存储使用32位字节命令RGBA格式(8-8-8-8)的的图像
QImage::Format_RGBA8888_Premultiplied 图像存储使用一个自左乘32位字节命令RGBA格式8-8-8-8
QImage::Format_BGR30 存储使用32位BGR格式(x-10-10-10)的的图像
QImage::Format_A2BGR30_Premultiplied 图像存储使用32位自左乘abgr格式2-10-10-10
QImage::Format_RGB30 存储使用32位RGB格式(x-10-10-10)的的图像
QImage::Format_A2RGB30_Premultiplied 图像存储使用2-10-10-10 32位自左乘ARGB格式
QImage::Format_Alpha8 该图像是使用一个8位的阿尔法格式存储

QImage::Format_Grayscale8 图像是使用一个8位灰度格式存储

不同Qt版本,这个Format枚举类型还略有点不同,不过常用的基本都包含了。实在不行,可以用opencv库转成常用的8-8-8 24位RGB格式。

关于图像滤波,是很常见和基础的图像处理,opencv中有现成的库可以调用,本示例给出了三种滤波方式(方框滤波,均值滤波和高斯滤波):

ros opencv qt yaml综合运用之滤波_第1张图片

该工程具备的基本功能为:打开并选择图像,选择滤波类型,调节滑动条可观察滤波效果。点击Save可将滤波类型和调节的参数。下次再打开图像时,会直接读取该参数并进行滤波。

此外,图像会以为ros topic的形式发布出来,可用rosrun rqt_image_view rqt_image_view查看。

opencv图像转换为ros图像和qt格式的图像代码如下:

    cv::Mat matImg;
    sensor_msgs::ImagePtr msg;
    msg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", matImg).toImageMsg();  //ros中的图像编码格式'bgr8'
    m_pub.publish(msg);

    cv::Mat showImg;
    cv::cvtColor(matImg, showImg, CV_BGR2RGB);      //BGR图像转换为RGB格式
    m_qImg = QImage((const unsigned char*)(showImg.data), showImg.cols, showImg.rows, QImage::Format_RGB888);
    ui->label->setPixmap(QPixmap::fromImage(m_qImg));

 

工程源码下载地址:

 

https://github.com/WelinLee/ros_cv_qt_gui

Enjoy!

你可能感兴趣的:(ros,opencv,qt)