修改摄像头分辨率并发布Topic

最近买了个1280x960的黑白摄像头,默认输出640x480,需要调节摄像头参数。

最终代码:

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/nonfree/nonfree.hpp>

#include <sensor_msgs/Image.h>
#include <sensor_msgs/image_encodings.h>
#include <cv_bridge/cv_bridge.h>
#include <ros/ros.h>
#include <image_transport/image_transport.h>
using namespace std;
using namespace cv;

int main(int argc, char** argv)
{


    sensor_msgs::ImagePtr img_msg; // >> message to be sent
    cv::Mat frame;
    ros::init(argc, argv, "cam");
    ros::NodeHandle nh;
    int32_t device_id(0);
    int32_t image_width(1280);
    int32_t image_height(960);
    nh.getParam("device_id",device_id);
    nh.getParam("image_width",image_width);
    nh.getParam("image_height",image_height);
    VideoCapture cap(device_id); // open the default camera

    if(!cap.isOpened())cout<<"Error open cam!"<<endl;
    if(!cap.isOpened())return -1;// check if we succeeded

    cout<<"Camera is open,to topic:cam/image"<<endl;
    bool bsw,bsh;
    if(cap.get(CV_CAP_PROP_FRAME_WIDTH)!=image_width)
    {
        bsw = cap.set(CV_CAP_PROP_FRAME_WIDTH,image_width);
        bsh = cap.set(CV_CAP_PROP_FRAME_HEIGHT,image_height);
    }
    cout<<"Resolution:"<<cap.get(CV_CAP_PROP_FRAME_WIDTH)<<"x"<<cap.get(CV_CAP_PROP_FRAME_HEIGHT)<<endl;

    image_transport::ImageTransport it(nh);
    image_transport::Publisher pub_img = it.advertise("cam/image", 1);
    ros::Rate rate(50);
    while(nh.ok())
    {
        cap >> frame; // get a new frame from camera
        img_msg=cv_bridge::CvImage(std_msgs::Header(), "bgr8", frame).toImageMsg();
        pub_img.publish(img_msg); // ros::Publisher pub_img = node.advertise<sensor_msgs::Image>("topic", queuesize);
        ros::spinOnce();
        rate.sleep();
    }
    return 0;
}

这里有个问题,就是插上摄像头第一次可以调用set进行写入参数,但是第二次就会报错:
HIGHGUI ERROR: V4L: Initial Capture Error: Unable to load initial memory buffers.
现在还没搞清什么原因,我就才去了一个办法:

    if(cap.get(CV_CAP_PROP_FRAME_WIDTH)!=image_width)
    {
        bsw = cap.set(CV_CAP_PROP_FRAME_WIDTH,image_width);
        bsh = cap.set(CV_CAP_PROP_FRAME_HEIGHT,image_height);
    }

就是一般情况不需要频繁调节分辨率,所以先读取现在的分辨率,如果和想要的一致(插上摄像头第一次运行已经配置好了)就不执行set函数了。

然后是launch文件:

<launch>
  <param name="device_id" value="0"/>
  <param name="image_width" value="1280"/>
  <param name="image_height" value="960"/>
  <node pkg="demo" type="cam" name="cam" output="screen">
  </node>
</launch>

还没完,标定时发现没发布camera_info信息。待续

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这个任务需要使用编程语言和相应的库来实现,以下是一个Python示例代码: ```python import cv2 import paho.mqtt.client as mqtt # 设置MQTT连接信息 broker_address = "mqtt.eclipseprojects.io" topic = "camera/stream" # 设置摄像头 cap = cv2.VideoCapture(0) # 创建MQTT客户端实例 client = mqtt.Client() # 连接MQTT服务器 client.connect(broker_address) # 不断读取摄像头帧并发送到MQTT while True: ret, frame = cap.read() if not ret: break # 将图像转换成二进制数据并发布到MQTT img_str = cv2.imencode('.jpg', frame)[1].tostring() client.publish(topic, payload=img_str, qos=0) # 等待一段时间,减少CPU占用 cv2.waitKey(1) # 释放摄像头和MQTT连接 cap.release() client.disconnect() ``` 这段代码使用了OpenCV库来读取USB摄像头的帧,然后将帧转换成二进制数据,并使用paho-mqtt库发布到指定的topic。你需要根据具体的需求修改代码中的MQTT连接信息和topic。 ### 回答2: 要打开USB摄像头并将消息发送到指定的topic,首先需要通过软件或代码来实现这个功能。 首先,我们需要一个可以操作USB摄像头的库或驱动程序。其中一种常用的库是OpenCV。使用OpenCV,我们可以在Python等编程语言中打开和控制USB摄像头。 通过以下代码片段,我们可以使用OpenCV在Python中打开USB摄像头: ``` import cv2 # 打开摄像头 cap = cv2.VideoCapture(0) if not cap.isOpened(): print("无法打开USB摄像头") while True: # 读取摄像头图像 ret, frame = cap.read() # 如果成功读取到图像,则发送到指定的topic if ret: # ... 在这里编写将图像发送到topic的代码 ... # 按下'q'键退出循环 if cv2.waitKey(1) & 0xFF == ord('q'): break # 关闭摄像头 cap.release() cv2.destroyAllWindows() ``` 上述代码中,我们首先通过`cv2.VideoCapture()`函数打开USB摄像头,传入参数0表示使用系统默认的摄像头。在循环中,我们调用`cap.read()`函数来读取摄像头的图像。如果成功读取到图像,我们可以在注释的位置处编写将图像发送到指定topic的代码。 发送图像到指定topic的实现方式取决于你使用的消息传输协议和平台。例如,如果你使用MQTT协议,可以使用Python的paho-mqtt库来连接到指定的MQTT broker,并调用`publish()`函数将图像数据发送到topic。 总结起来,要打开USB摄像头并将消息发送到指定的topic,我们需要用到相应的库或驱动程序控制摄像头,并使用消息传输协议将图像数据发送到指定的topic。 ### 回答3: 要实现将USB摄像头打开并将消息发送到指定的topic,需要进行以下步骤: 首先,需要连接USB摄像头到计算机上,并确保摄像头驱动程序已经正确安装。 接下来,我们可以使用适当的编程语言或者框架,如Python和OpenCV,来实现打开USB摄像头的功能。可以通过使用相关的函数和方法,如cv2.VideoCapture()来访问和控制摄像头。 一旦摄像头被成功打开,我们就可以从摄像头中获取图像数据。可以使用cv2.VideoCapture对象的read()方法来获取图像帧。读取的图像帧可以保存为图像文件,或者进行进一步的处理,如人脸识别等。 要将消息发送到指定的topic,首先需要确定要使用的通信协议,如MQTT或者HTTP。然后,可以使用相应的库或者工具,如paho.mqtt库或者requests库,来实现消息的发送。 如果使用MQTT协议,需要创建一个MQTT客户端,并连接到MQTT代理服务器。然后,可以使用客户端对象的publish()方法来发送消息到指定的topic。 如果使用HTTP协议,可以使用HTTP请求库,如requests库,来发送HTTP请求。可以使用适当的HTTP方法(如POST或PUT)和相应的URL,来发送消息到指定的topic。 在发送消息之前,需要根据需求对消息进行适当的格式化和编码。然后,将消息数据作为参数传递给相应的发送函数,以完成消息的发送操作。 通过以上步骤,我们可以实现打开USB摄像头,并将消息发送到指定的topic。这样就可以实现摄像头图像的获取和消息的传递。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值