2024-05-24 19:10:41 +08:00
|
|
|
|
#include "capture.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
#include <thread>
|
2024-05-27 16:00:05 +08:00
|
|
|
|
#include <opencv2/core.hpp>
|
|
|
|
|
|
#include <opencv2/opencv.hpp>
|
2024-05-24 19:10:41 +08:00
|
|
|
|
#include <opencv2/highgui.hpp>
|
|
|
|
|
|
#include <zmq.hpp>
|
|
|
|
|
|
#include "logc/log.h"
|
2024-05-27 16:00:05 +08:00
|
|
|
|
#include <unistd.h>
|
2024-05-24 19:10:41 +08:00
|
|
|
|
|
|
|
|
|
|
capture::capture(int camera_index, int zmq_port, int width_set, int height_set, int fps_set)
|
|
|
|
|
|
{
|
|
|
|
|
|
index = camera_index;
|
|
|
|
|
|
port = zmq_port;
|
|
|
|
|
|
width = width_set;
|
|
|
|
|
|
height = height_set;
|
|
|
|
|
|
fps = fps_set;
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
2024-05-29 21:51:28 +08:00
|
|
|
|
socket = new zmq::socket_t(*context, ZMQ_REP);
|
|
|
|
|
|
// int hwm = 10;
|
|
|
|
|
|
// socket->setsockopt(ZMQ_SNDHWM, &hwm, sizeof(hwm));
|
2024-05-24 19:10:41 +08:00
|
|
|
|
char zmq_bind_port[10] = {0};
|
|
|
|
|
|
sprintf(zmq_bind_port, "%d", port);
|
|
|
|
|
|
strcat(zmq_bind_addr, zmq_bind_port);
|
2024-05-29 21:51:28 +08:00
|
|
|
|
log_info("set camera %d zmq address test %s", index, zmq_bind_addr);
|
2024-05-24 19:10:41 +08:00
|
|
|
|
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)
|
|
|
|
|
|
{
|
2024-05-27 16:00:05 +08:00
|
|
|
|
cv::Mat dst;
|
2024-05-24 19:10:41 +08:00
|
|
|
|
while (1)
|
|
|
|
|
|
{
|
2024-05-29 21:51:28 +08:00
|
|
|
|
zmq::message_t msg_temp;
|
|
|
|
|
|
socket->recv(&msg_temp);
|
2024-05-24 19:10:41 +08:00
|
|
|
|
*cap >> frame;
|
|
|
|
|
|
if (frame.empty())
|
|
|
|
|
|
{
|
|
|
|
|
|
log_error("empty frame");
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 确保图像是连续的
|
|
|
|
|
|
if (!frame.isContinuous())
|
|
|
|
|
|
{
|
|
|
|
|
|
frame = frame.clone().reshape(1, frame.total());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-27 16:00:05 +08:00
|
|
|
|
cv::cvtColor(frame, dst, cv::COLOR_BGR2RGB);
|
|
|
|
|
|
|
2024-05-24 19:10:41 +08:00
|
|
|
|
// cv::imshow(zmq_bind_addr, frame);
|
|
|
|
|
|
|
|
|
|
|
|
// 将帧编码后发送
|
2024-05-27 16:00:05 +08:00
|
|
|
|
std::vector<uchar>
|
|
|
|
|
|
buff;
|
|
|
|
|
|
cv::imencode(".jpg", dst, buff);
|
2024-05-24 19:10:41 +08:00
|
|
|
|
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);
|
2024-05-27 16:00:05 +08:00
|
|
|
|
// usleep(20000);
|
2024-05-24 19:10:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool capture::is_open(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
return status;
|
|
|
|
|
|
}
|