在RK3588上运行YOLOv5,并使用九点标定法将图中辨认到的坐标转换为实际空间的坐标

[复制链接]
发表于 2026-2-19 11:32:16 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
        在rockchip官方的例程https://github.com/airockchip/rknn_model_zoo/tree/main/examples/yolov5中有最新的rknn格式运行yolov5的例程。本文是基于用多线程yolov5的demohttps://github.com/leafqycc/rknn-cpp-Multithreading运行的。
        在复今世码后,YOLOv5的检测效果经后处理处罚代码的输特殊式依次为:
        name-检测种别名
        box.left-检测框左上角的x坐标
        box.top-检测框左上角的y坐标
        box.right-检测框右下角的x坐标
        box.bottom-检测框右下角的y坐标
        prop-检测框的置信度
        由于实际应用须要将辨认效果的图片坐标转换为实际空间中的二维坐标,因此本文接纳九点标定法对检测效果再举行一步处理处罚。九点标定法的界说不赘述了,大抵标定步调为:
        ①在图片中标志9个点,分布只管匀称,将它们在图片中的坐标存起来
        ②通过实际丈量得到图中九个点在实际空间中的二维坐标,并将这就个坐标也存起来
        ③创建一个映射矩阵拟合这九个点的映射关系
        ④当检测效果为图片中的某一坐标时,将坐标输入到映射矩阵中,得到输出的实际空间坐标
        

        如图,这是一张640×640的图片,图中匀称的分布有九个点,我通过python实现一个简单的九点标定法坐标转换
  1. import numpy as np
  2. import cv2
  3. # 定义图像中的九个圆的像素坐标 (假设这些坐标已知)
  4. pixel_coords = np.array([
  5.     [160, 160], [320, 160], [480, 160],
  6.     [160, 320], [320, 320], [480, 320],
  7.     [160, 480], [320, 480], [480, 480]
  8. ], dtype=np.float32)
  9. # 假设实际空间中的九个圆的坐标 (单位: cm)
  10. actual_coords = np.array([
  11.     [-20, 40], [0, 40], [20, 40],
  12.     [-20, 20], [0, 20], [20, 20],
  13.     [-20, 0], [0, 0], [20, 0]
  14. ], dtype=np.float32)
  15. # 计算映射矩阵
  16. transform_matrix, _ = cv2.findHomography(pixel_coords, actual_coords)
  17. # 定义一个函数将图像中的任意点转换为实际空间坐标
  18. def pixel_to_actual(pixel_point, transform_matrix):
  19.     pixel_point = np.array([pixel_point], dtype=np.float32)
  20.     pixel_point = np.array([pixel_point])
  21.     actual_point = cv2.perspectiveTransform(pixel_point, transform_matrix)
  22.     return actual_point[0][0]
  23. # 选择一个任意点的像素坐标 (例如: [400, 300])
  24. random_pixel = [400, 300]
  25. actual_point = pixel_to_actual(random_pixel, transform_matrix)
  26. print(f"Pixel coordinates: {random_pixel} -> Actual coordinates: {actual_point}")
复制代码
        cv2.findHomography() 是 OpenCV 中的一个函数,用于找到两个图像之间的单应性矩阵(Homography matrix)。在盘算机视觉中,单应性矩阵是一个3x3的矩阵,它形貌了两个平面之间的相对位置关系。运行代码即可以得到映射矩阵transform_matrix,再将预设的坐标点(400,300)输入到映射矩阵中,就能得到转换效果。
  1. Pixel coordinates: [400, 300] -> Actual coordinates: [10.  22.5]
复制代码
        再将这一部门代码移植到YOLOv5的C步调检测代码中,起首界说标定用的图片坐标集和实际坐标集以及映射矩阵。
  1. std::vector<cv::Point2f> srcPoints;
  2. std::vector<cv::Point2f> dstPoints;
  3. cv::Mat homography;
复制代码
        我的输入输入图片巨细为1024×1024,在这个根本上对坐标集初始化。
  1. srcPoints = {
  2.         cv::Point2f(256, 256), cv::Point2f(512, 256), cv::Point2f(768, 256),
  3.         cv::Point2f(256, 512), cv::Point2f(512, 512), cv::Point2f(768, 512),
  4.         cv::Point2f(256, 768), cv::Point2f(512, 768), cv::Point2f(768, 768)
  5.     };
  6. dstPoints = {
  7.         cv::Point2f(0, 0), cv::Point2f(20, 0), cv::Point2f(40, 0),
  8.         cv::Point2f(0, 20), cv::Point2f(20, 20), cv::Point2f(40, 20),
  9.         cv::Point2f(0, 40), cv::Point2f(20, 40), cv::Point2f(40, 40)
  10.     };
复制代码
        起首包罗头文件"opencv2/calib3d.hpp",调用findHomography盘算单应性矩阵,在OpenCV中,调用findHomography()方法时指定cv2.RANSAC参数。
  1. homography = cv::findHomography(srcPoints, dstPoints, cv::RANSAC, 3);
  2. if (homography.empty()) {
  3.     std::cout << "Error: Homography calculation failed." << std::endl;
  4.     return -1;
  5. }
复制代码
        将得到的映射矩阵应用到检测效果的转换中。cv::perspectiveTransform()函数是OpenCV库中用于实行透视变更的函数。它可以将一个坐标点转换为另一个坐标系中的对应点。
  1. int x1 = det_result->box.left;
  2. int y1 = det_result->box.top;
  3. int x2 = det_result->box.right;
  4. int y2 = det_result->box.bottom;
  5. int center_x = (x1 + x2) / 2;
  6. int center_y = (y1 + y2) / 2;
  7. //************坐标转换******************
  8. cv::Point2f imagePoint(center_x, center_y);
  9. std::vector<cv::Point2f> imagePoints = {imagePoint};
  10. std::vector<cv::Point2f> worldPoints;
  11. cv::perspectiveTransform(imagePoints, worldPoints, homography);
  12. sprintf(text_actxy, "Image coordinates: (%d, %d) *** Actual coordinates: (%.2f, %.2f)", center_x, center_y, worldPoints[0].x, worldPoints[0].y);
  13. //************坐标转换******************
  14. //在中心点画一个标记点
  15. circle(orig_img, cv::Point(center_x, center_y), 5, cv::Scalar(0, 0, 255), cv::FILLED);
  16. putText(orig_img, text_actxy, cv::Point(20, 20), cv::FONT_HERSHEY_SIMPLEX, 0.6, cv::Scalar(255, 255, 255));
复制代码

回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表