update
This commit is contained in:
75
capture.cc
75
capture.cc
@@ -27,12 +27,12 @@ capture::capture(int camera_index, int zmq_port, int width_set, int height_set,
|
||||
|
||||
if (!cap->isOpened())
|
||||
{
|
||||
log_error("Error opening video stream in %d", index);
|
||||
log_error("开启摄像头 %d 失败", index);
|
||||
status = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
log_info("Successful opening video stream in %d", index);
|
||||
log_info("开启摄像头 %d 成功", index);
|
||||
status = true;
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ capture::capture(int camera_index, int zmq_port, int width_set, int height_set,
|
||||
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);
|
||||
log_info("设置 %d zmq 地址 %s", index, zmq_bind_addr);
|
||||
socket->bind(zmq_bind_addr);
|
||||
}
|
||||
|
||||
@@ -51,68 +51,73 @@ void capture::start(void)
|
||||
{
|
||||
if (this->is_open())
|
||||
{
|
||||
log_info("start camera %d capture thread", index);
|
||||
thread = new std::thread(&capture::run, this);
|
||||
log_info("开启摄像头 %d 采集和应答线程", index);
|
||||
// FIXME request 启动后若 capture 尚未读取到有效帧,则会断言
|
||||
thread_capture = new std::thread(&capture::get, this);
|
||||
sleep(1);
|
||||
thread_request = new std::thread(&capture::req, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("camera %d have not been inited, exit", index);
|
||||
log_error("摄像头 %d 未成功初始化,跳过", index);
|
||||
}
|
||||
}
|
||||
|
||||
void capture::run(void)
|
||||
void capture::get(void)
|
||||
{
|
||||
cv::Mat dst;
|
||||
while (1)
|
||||
{
|
||||
zmq::message_t msg_temp;
|
||||
socket->recv(&msg_temp);
|
||||
*cap >> frame;
|
||||
if (frame.empty())
|
||||
*cap >> dst;
|
||||
if (dst.empty())
|
||||
{
|
||||
// TODO 尝试返回缓存帧,并重新启动 capture
|
||||
log_error("empty frame");
|
||||
break;
|
||||
log_error("摄像头 %d 读取到空帧,尝试销毁后重启", index);
|
||||
|
||||
cap->release();
|
||||
// delete cap;
|
||||
|
||||
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);
|
||||
|
||||
log_warn("摄像头 %d 重新构造完成\r\n", index);
|
||||
*cap >> dst;
|
||||
}
|
||||
|
||||
// 确保图像是连续的
|
||||
if (!frame.isContinuous())
|
||||
if (!dst.isContinuous())
|
||||
{
|
||||
frame = frame.clone().reshape(1, frame.total());
|
||||
dst = dst.clone().reshape(1, dst.total());
|
||||
}
|
||||
|
||||
// 中心翻转处理
|
||||
if (flip)
|
||||
{
|
||||
cv::flip(frame, frame, -1);
|
||||
cv::flip(dst, dst, -1);
|
||||
}
|
||||
|
||||
// 将图像转换为 rgb
|
||||
cv::cvtColor(frame, dst, cv::COLOR_BGR2RGB);
|
||||
cv::cvtColor(dst, frame, cv::COLOR_BGR2RGB);
|
||||
|
||||
// 在这里添加一些延迟,以控制帧率
|
||||
cv::waitKey(1);
|
||||
}
|
||||
}
|
||||
|
||||
void capture::req(void)
|
||||
{
|
||||
zmq::message_t msg_temp;
|
||||
while (1)
|
||||
{
|
||||
socket->recv(&msg_temp);
|
||||
// 将帧编码后发送
|
||||
std::vector<uchar>
|
||||
buff;
|
||||
cv::imencode(".jpg", dst, buff);
|
||||
cv::imencode(".jpg", frame, 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);
|
||||
}
|
||||
|
||||
log_error("capture exit");
|
||||
|
||||
@@ -18,7 +18,8 @@ public:
|
||||
bool flip = false;
|
||||
char zmq_bind_addr[40] = "tcp://*:";
|
||||
|
||||
std::thread *thread;
|
||||
std::thread *thread_capture;
|
||||
std::thread *thread_request;
|
||||
cv::VideoCapture *cap;
|
||||
cv::Mat frame;
|
||||
zmq::context_t *context;
|
||||
@@ -26,7 +27,8 @@ public:
|
||||
|
||||
capture(int camera_index, int zmq_port, int width_set = 320, int height_set = 240, int fps_set = 20, bool flip = false);
|
||||
void start(void);
|
||||
void run(void);
|
||||
void get(void);
|
||||
void req(void);
|
||||
bool is_open(void);
|
||||
};
|
||||
|
||||
|
||||
53
main.cc
53
main.cc
@@ -48,62 +48,13 @@ int main(int argc, char **argv)
|
||||
|
||||
capture cap0(server_0_index.u.i, server_0_port.u.i);
|
||||
capture cap1(server_1_index.u.i, server_1_port.u.i, 320, 240, 60, true);
|
||||
// capture cap2(server_2_index.u.i, server_2_port.u.i);
|
||||
// capture cap2(server_2_index.u.i, server_2_port.u.i, 640, 480);
|
||||
|
||||
cap0.start();
|
||||
cap1.start();
|
||||
// cap2.start();
|
||||
|
||||
if (cap0.is_open())
|
||||
{
|
||||
cap0.thread->join();
|
||||
}
|
||||
if (cap1.is_open())
|
||||
{
|
||||
cap1.thread->join();
|
||||
}
|
||||
// if (cap2.is_open())
|
||||
// {
|
||||
// cap2.thread->join();
|
||||
// }
|
||||
cap1.thread_request->join();
|
||||
|
||||
// while (true)
|
||||
// {
|
||||
// cap >> frame;
|
||||
// if (frame.empty())
|
||||
// {
|
||||
// std::cerr << "Empty frame" << std::endl;
|
||||
// break;
|
||||
// }
|
||||
|
||||
// // 确保图像是连续的
|
||||
// if (!frame.isContinuous())
|
||||
// {
|
||||
// frame = frame.clone().reshape(1, frame.total());
|
||||
// }
|
||||
|
||||
// // std::cout << frame.cols << ":" << frame.rows << std::endl;
|
||||
|
||||
// // cv::imshow("realtime", frame);
|
||||
|
||||
// // 发送帧的元数据(宽度、高度、类型等)
|
||||
// // 这里简单起见,只发送宽度和高度(假设类型为 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);
|
||||
// }
|
||||
|
||||
// // 关闭视频捕获和 ZMQ 套接字
|
||||
// cap.release();
|
||||
// socket.close();
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user