forked from floratest1/SpireCV
fix veri
This commit is contained in:
140
samples/demo/udp_detection_info_receiver_by_airborne.cpp
Normal file
140
samples/demo/udp_detection_info_receiver_by_airborne.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
#include <iostream>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#define PORT 12346 // UDP端口号
|
||||
|
||||
// 枚举定义消息类型
|
||||
enum MessageType {
|
||||
TIMESTAMP = 0x00,
|
||||
CLICK_COORDINATES = 0x01,
|
||||
TARGET_BOX_COORDINATES = 0x02,
|
||||
CLICK_COORDINATES_FRAME_ID = 0x03,
|
||||
TARGET_BOX_COORDINATES_FRAME_ID = 0x04
|
||||
};
|
||||
|
||||
// 定义消息结构体
|
||||
#pragma pack(1) // 使用1字节对齐方式
|
||||
struct Message {
|
||||
unsigned char header[2]; // 帧头
|
||||
unsigned char type; // 消息类型
|
||||
unsigned char reserved; // 保留字段
|
||||
unsigned int requestID; // 请求ID
|
||||
unsigned int dataLength; // 数据长度
|
||||
unsigned char* data; // 数据段
|
||||
};
|
||||
#pragma pack() // 恢复默认对齐方式
|
||||
|
||||
// 解析时间戳消息
|
||||
void parseTimestampMessage(unsigned char* data) {
|
||||
unsigned short year = ntohs(*reinterpret_cast<unsigned short*>(data));
|
||||
unsigned char month = *(data + 2);
|
||||
unsigned char day = *(data + 3);
|
||||
unsigned char hour = *(data + 4);
|
||||
unsigned char minute = *(data + 5);
|
||||
unsigned char second = *(data + 6);
|
||||
unsigned short millisecond = ntohs(*reinterpret_cast<unsigned short*>(data + 7));
|
||||
|
||||
std::cout << "Timestamp: " << static_cast<int>(year) << "-" << static_cast<int>(month)
|
||||
<< "-" << static_cast<int>(day) << " " << static_cast<int>(hour) << ":"
|
||||
<< static_cast<int>(minute) << ":" << static_cast<int>(second) << "."
|
||||
<< static_cast<int>(millisecond) << std::endl;
|
||||
}
|
||||
|
||||
// 解析点击坐标消息
|
||||
void parseClickCoordinatesMessage(unsigned char* data) {
|
||||
float x = *reinterpret_cast<float*>(data);
|
||||
float y = *reinterpret_cast<float*>(data + 4);
|
||||
|
||||
std::cout << "Click coordinates: (" << x << ", " << y << ")" << std::endl;
|
||||
}
|
||||
|
||||
// 解析目标框坐标消息
|
||||
void parseTargetBoxCoordinatesMessage(unsigned char* data) {
|
||||
float x1 = *reinterpret_cast<float*>(data);
|
||||
float y1 = *reinterpret_cast<float*>(data + 4);
|
||||
float x2 = *reinterpret_cast<float*>(data + 8);
|
||||
float y2 = *reinterpret_cast<float*>(data + 12);
|
||||
|
||||
std::cout << "Target box coordinates: (" << x1 << ", " << y1 << ") - ("
|
||||
<< x2 << ", " << y2 << ")" << std::endl;
|
||||
}
|
||||
|
||||
// 解析UDP数据包
|
||||
void parseUDPData(unsigned char* buffer, int length) {
|
||||
if (length < 13) {
|
||||
std::cout << "Invalid UDP data format" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
Message message;
|
||||
memcpy(&message, buffer, sizeof(Message));
|
||||
|
||||
// 解析消息类型
|
||||
MessageType messageType = static_cast<MessageType>(message.type);
|
||||
|
||||
// 根据消息类型处理数据
|
||||
switch (messageType) {
|
||||
case TIMESTAMP:
|
||||
if (length != 9) {
|
||||
std::cout << "Invalid timestamp message length" << std::endl;
|
||||
return;
|
||||
}
|
||||
parseTimestampMessage(message.data);
|
||||
break;
|
||||
case CLICK_COORDINATES:
|
||||
if (length != 13) {
|
||||
std::cout << "Invalid click coordinates message length" << std::endl;
|
||||
return;
|
||||
}
|
||||
parseClickCoordinatesMessage(message.data);
|
||||
break;
|
||||
case TARGET_BOX_COORDINATES:
|
||||
if (length != 21) {
|
||||
std::cout << "Invalid target box coordinates message length" << std::endl;
|
||||
return;
|
||||
}
|
||||
parseTargetBoxCoordinatesMessage(message.data);
|
||||
break;
|
||||
default:
|
||||
std::cout << "Unsupported message type" << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
int sockfd;
|
||||
struct sockaddr_in servaddr, cliaddr;
|
||||
unsigned char buffer[4096];
|
||||
|
||||
// 创建UDP套接字
|
||||
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
memset(&servaddr, 0, sizeof(servaddr));
|
||||
memset(&cliaddr, 0, sizeof(cliaddr));
|
||||
|
||||
servaddr.sin_family = AF_INET;
|
||||
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
servaddr.sin_port = htons(PORT);
|
||||
|
||||
// 绑定UDP套接字到端口
|
||||
bind(sockfd, (const struct sockaddr*)&servaddr, sizeof(servaddr));
|
||||
|
||||
while (true) {
|
||||
socklen_t len = sizeof(cliaddr);
|
||||
|
||||
// 接收UDP数据包
|
||||
ssize_t n = recvfrom(sockfd, buffer, sizeof(buffer), MSG_WAITALL,
|
||||
(struct sockaddr*)&cliaddr, &len);
|
||||
|
||||
// 解析UDP数据包
|
||||
parseUDPData(buffer, n);
|
||||
}
|
||||
|
||||
close(sockfd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -5,41 +5,85 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
// 打开摄像头
|
||||
struct node
|
||||
{
|
||||
double x, y;
|
||||
};
|
||||
|
||||
node p1;
|
||||
|
||||
// 框选到的矩形
|
||||
cv::Rect rect_sel;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// 实例化 框选目标跟踪类
|
||||
sv::VeriDetector veri;
|
||||
// 手动导入相机参数,如果使用Amov的G1等吊舱或相机,则可以忽略该步骤,将自动下载相机参数文件
|
||||
veri.loadCameraParams(sv::get_home() + "/SpireCV/calib_webcam_640x480.yaml");
|
||||
|
||||
cv::VideoCapture cap1("/home/amov/Videos/com/FlyVideo_2023-09-02_11-36-00.avi");
|
||||
cv::VideoCapture cap2("/home/amov/Videos/com/FlyVideo_2023-09-02_11-41-55.avi");
|
||||
sv::CommonObjectDetector cod;
|
||||
cod.loadCameraParams(sv::get_home() + "/SpireCV/calib_webcam_640x480.yaml");
|
||||
|
||||
// 打开摄像头
|
||||
sv::Camera cap;
|
||||
// cap.setWH(640, 480);
|
||||
// cap.setFps(30);
|
||||
//cap.open(sv::CameraType::WEBCAM, 0); // CameraID 0
|
||||
cap.open(sv::CameraType::WEBCAM, 0); // CameraID 0
|
||||
// 实例化OpenCV的Mat类,用于内存单帧图像
|
||||
|
||||
|
||||
cv::Mat img1,img2;
|
||||
cv::Mat img;
|
||||
int frame_id = 0;
|
||||
while (1)
|
||||
{
|
||||
|
||||
// 实例化SpireCV的 单帧检测结果 接口类 TargetsInFrame
|
||||
sv::TargetsInFrame tgts(frame_id++);
|
||||
|
||||
// 读取一帧图像到img
|
||||
cap1.read(img1);
|
||||
cap2.read(img2);
|
||||
cap.read(img);
|
||||
cv::resize(img, img, cv::Size(cod.image_width, cod.image_height));
|
||||
|
||||
cv::resize(img1, img1, cv::Size(224, 224));
|
||||
cv::resize(img2, img2, cv::Size(224, 224));
|
||||
// 执行通用目标检测
|
||||
cod.detect(img, tgts);
|
||||
|
||||
veri.detect(img1, img2, tgts);
|
||||
// 可视化检测结果,叠加到img上
|
||||
sv::drawTargetsInFrame(img, tgts);
|
||||
|
||||
|
||||
// 控制台打印通用目标检测结果
|
||||
printf("Frame-[%d]\n", frame_id);
|
||||
// 打印当前检测的FPS
|
||||
printf(" FPS = %.2f\n", tgts.fps);
|
||||
// 打印当前相机的视场角(degree)
|
||||
printf(" FOV (fx, fy) = (%.2f, %.2f)\n", tgts.fov_x, tgts.fov_y);
|
||||
for (int i = 0; i < tgts.targets.size(); i++)
|
||||
{
|
||||
printf("Frame-[%d], Object-[%d]\n", frame_id, i);
|
||||
// 打印每个目标的中心位置,cx,cy的值域为[0, 1]
|
||||
printf(" Object Center (cx, cy) = (%.3f, %.3f)\n", tgts.targets[i].cx, tgts.targets[i].cy);
|
||||
// 打印每个目标的外接矩形框的宽度、高度,w,h的值域为(0, 1]
|
||||
printf(" Object Size (w, h) = (%.3f, %.3f)\n", tgts.targets[i].w, tgts.targets[i].h);
|
||||
// 打印每个目标的置信度
|
||||
printf(" Object Score = %.3f\n", tgts.targets[i].score);
|
||||
// 打印每个目标的类别,字符串类型
|
||||
printf(" Object Category = %s, Category ID = [%d]\n", tgts.targets[i].category.c_str(), tgts.targets[i].category_id);
|
||||
// 打印每个目标的视线角,跟相机视场相关
|
||||
printf(" Object Line-of-sight (ax, ay) = (%.3f, %.3f)\n", tgts.targets[i].los_ax, tgts.targets[i].los_ay);
|
||||
// 打印每个目标的3D位置(在相机坐标系下),跟目标实际长宽、相机参数相关
|
||||
printf(" Object Position = (x, y, z) = (%.3f, %.3f, %.3f)\n", tgts.targets[i].px, tgts.targets[i].py, tgts.targets[i].pz);
|
||||
|
||||
// 显示img
|
||||
// cv::imshow("img", img);
|
||||
// cv::waitKey(10);
|
||||
if (tgts.targets[i].category_id == 2)
|
||||
{
|
||||
p1.x = tgts.targets[i].cx * tgts.width - tgts.targets[i].w * tgts.width / 2;
|
||||
p1.y = tgts.targets[i].cy * tgts.height - tgts.targets[i].h * tgts.height / 2;
|
||||
rect_sel = cv::Rect(p1.x, p1.y, tgts.targets[i].w * tgts.width, tgts.targets[i].h * tgts.height);
|
||||
veri.detect(img, rect_sel, tgts.targets[i]);
|
||||
// 打印每个目标的CosineSimilarity
|
||||
printf(" CosineSimilarity Score = %.3f\n", tgts.targets[i].sim_score);
|
||||
}
|
||||
}
|
||||
|
||||
// 显示检测结果img
|
||||
cv::imshow("img", img);
|
||||
cv::waitKey(10);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user