Package | OpenCV C++ cv::Mat 数据类型type对应的输出值

12 篇文章 3 订阅

 

背景:

在使用OpenCV C++包时,通常需要访问和修改cv::Mat的数据值。要做到点对点的处理,保证程序的正确性,需要先确定cv::Mat的数据类型type,以确定后续访问cv::Mat数据的调用接口。

 

做法:

要确定cv::Mat的数据格式,最直接的做法是调用type API,得到type的输出值。

cv::Mat img;

/*
...
image processing
some data written into 'img'
... 
*/

std::cout << img.type() << std::endl;

我们会得到一些type的整型值,可以通过查表来对应得到数值类型。

原答案:https://stackoverflow.com/questions/10167534/how-to-find-out-what-type-of-a-mat-object-is-with-mattype-in-opencv

 

搬运表格:

+--------+----+----+----+----+------+------+------+------+
|        | C1 | C2 | C3 | C4 | C(5) | C(6) | C(7) | C(8) |
+--------+----+----+----+----+------+------+------+------+
| CV_8U  |  0 |  8 | 16 | 24 |   32 |   40 |   48 |   56 |
| CV_8S  |  1 |  9 | 17 | 25 |   33 |   41 |   49 |   57 |
| CV_16U |  2 | 10 | 18 | 26 |   34 |   42 |   50 |   58 |
| CV_16S |  3 | 11 | 19 | 27 |   35 |   43 |   51 |   59 |
| CV_32S |  4 | 12 | 20 | 28 |   36 |   44 |   52 |   60 |
| CV_32F |  5 | 13 | 21 | 29 |   37 |   45 |   53 |   61 |
| CV_64F |  6 | 14 | 22 | 30 |   38 |   46 |   54 |   62 |
+--------+----+----+----+----+------+------+------+------+

直接查表更方便~

 

要逐个访问Mat的元素,则可以根据Mat的类型,用对应的API,例如img.at<float>/img.at<Vec3b>,来逐一访问。

 

 

 

 

以下是一个C++通过protobuf传输图像数据,并将图像解码为ROS中的sensor_msgs::ImagePtr对象的示例代码: 首先需要安装protobuf库和ROS,可以参考官方文档进行安装。 然后定义一个.proto文件,例如: ```protobuf syntax = "proto3"; package image; message Image { int32 width = 1; int32 height = 2; bytes data = 3; } ``` 这个.proto文件定义了一个名为Image的message,包含图像的宽度、高度和数据。 接着使用protobuf编译器将.proto文件编译成C++代码: ``` protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/image.proto ``` 其中$SRC_DIR是.proto文件所在的目录,$DST_DIR是输出目录。 编译后会生成image.pb.h和image.pb.cc两个文件,在代码中包含头文件image.pb.h即可使用。 下面是一个简单的示例代码: ```c++ #include <iostream> #include <fstream> #include <string> #include <ros/ros.h> #include <sensor_msgs/Image.h> #include <opencv2/opencv.hpp> #include "image.pb.h" using namespace std; using namespace cv; // 将protobuf message解码为ROS的sensor_msgs::ImagePtr对象 sensor_msgs::ImagePtr decode_image(const image::Image& image_msg) { sensor_msgs::ImagePtr image_ptr(new sensor_msgs::Image); image_ptr->header.stamp = ros::Time::now(); image_ptr->header.frame_id = "image"; image_ptr->height = image_msg.height(); image_ptr->width = image_msg.width(); image_ptr->encoding = "bgr8"; image_ptr->step = image_ptr->width * 3; image_ptr->data.resize(image_ptr->height * image_ptr->step); memcpy(image_ptr->data.data(), image_msg.data().data(), image_msg.data().size()); return image_ptr; } int main(int argc, char** argv) { ros::init(argc, argv, "image_publisher"); ros::NodeHandle nh; // 创建一个ROS的publisher,发布sensor_msgs::Image消息 ros::Publisher image_pub = nh.advertise<sensor_msgs::Image>("image_topic", 1); Mat img = imread("test.jpg"); if (img.empty()) { cerr << "Failed to read image" << endl; return -1; } // 构建protobuf message image::Image image_msg; image_msg.set_width(img.cols); image_msg.set_height(img.rows); string data; imencode(".jpg", img, data); image_msg.set_data(data); // 将protobuf message序列化为字符串 string serialized_data = image_msg.SerializeAsString(); // 从字符串中反序列化出protobuf message image::Image received_image_msg; received_image_msg.ParseFromString(serialized_data); // 将protobuf message解码为ROS的sensor_msgs::ImagePtr对象 sensor_msgs::ImagePtr received_image_ptr = decode_image(received_image_msg); // 发布接收到的图像 image_pub.publish(received_image_ptr); ros::spin(); return 0; } ``` 在这个示例中,我们首先创建一个ROS的publisher,发布sensor_msgs::Image消息。然后使用OpenCV读取一张图像,将图像数据存储到protobuf message中,并将protobuf message序列化为字符串。 然后我们从字符串中反序列化出protobuf message,并将protobuf message解码为ROS的sensor_msgs::ImagePtr对象,最后发布接收到的图像。 注意,在实际应用中,需要使用网络传输将序列化后的字符串发送给接收方,这里只是为了演示方便,使用字符串直接传输。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值