Files
project_capture/capture.cc
2024-06-17 22:16:28 +08:00

120 lines
3.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "capture.h"
#include <vector>
#include <thread>
#include <opencv2/core.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include <zmq.hpp>
#include "logc/log.h"
#include <unistd.h>
capture::capture(int camera_index, int zmq_port, int width_set, int height_set, int fps_set, bool _flip)
{
index = camera_index;
port = zmq_port;
width = width_set;
height = height_set;
fps = fps_set;
flip = _flip;
log_info("trying open camera %d", index);
cap = new cv::VideoCapture(index, cv::CAP_V4L2);
cap->set(cv::CAP_PROP_FRAME_WIDTH, width);
cap->set(cv::CAP_PROP_FRAME_HEIGHT, height);
cap->set(cv::CAP_PROP_FPS, fps);
if (!cap->isOpened())
{
log_error("Error opening video stream in %d", index);
status = false;
}
else
{
log_info("Successful opening video stream in %d", index);
status = true;
}
context = new zmq::context_t(1);
socket = new zmq::socket_t(*context, ZMQ_REP);
// int hwm = 10;
// socket->setsockopt(ZMQ_SNDHWM, &hwm, sizeof(hwm));
char zmq_bind_port[10] = {0};
sprintf(zmq_bind_port, "%d", port);
strcat(zmq_bind_addr, zmq_bind_port);
log_info("set camera %d zmq address test %s", index, zmq_bind_addr);
socket->bind(zmq_bind_addr);
}
void capture::start(void)
{
if (this->is_open())
{
log_info("start camera %d capture thread", index);
thread = new std::thread(&capture::run, this);
}
else
{
log_error("camera %d have not been inited, exit", index);
}
}
void capture::run(void)
{
cv::Mat dst;
while (1)
{
zmq::message_t msg_temp;
socket->recv(&msg_temp);
*cap >> frame;
if (frame.empty())
{
log_error("empty frame");
break;
}
// 确保图像是连续的
if (!frame.isContinuous())
{
frame = frame.clone().reshape(1, frame.total());
}
if (flip)
{
cv::flip(frame, frame, -1);
// cv::flip(frame, frame, 1);
}
cv::cvtColor(frame, dst, cv::COLOR_BGR2RGB);
// cv::imshow(zmq_bind_addr, frame);
// 将帧编码后发送
std::vector<uchar>
buff;
cv::imencode(".jpg", dst, buff);
zmq::message_t message(buff.size());
memcpy(message.data(), buff.data(), buff.size());
socket->send(message, zmq::send_flags::none);
// 发送帧的元数据(宽度、高度、类型等)
// 这里简单起见,只发送宽度和高度(假设类型为 CV_8UC3
// zmq::message_t header_msg(sizeof(int) * 2);
// int *header_data = static_cast<int *>(header_msg.data());
// header_data[0] = frame.cols;
// header_data[1] = frame.rows;
// socket.send(header_msg, zmq::send_flags::sndmore);
// 发送帧数据
// zmq::message_t frame_msg((size_t)frame.total() * frame.elemSize());
// memcpy(frame_msg.data(), frame.data, frame.total() * frame.elemSize());
// socket->send(frame_msg, zmq::send_flags::none);
// 在这里添加一些延迟,以控制帧率
cv::waitKey(1);
// usleep(20000);
}
}
bool capture::is_open(void)
{
return status;
}