首页 > 其他分享 >点云_图像--坐标中心和角点

点云_图像--坐标中心和角点

时间:2024-08-08 17:52:12浏览次数:4  
标签:roi -- sum 角点 sqrt np boxes 点云 math

图像2D框

bounding box

目标框(bounding box)来描述目标的位置,目标框是矩形的。
    由矩形左上角的坐标(x1,y1)以及右下角的坐标(x2,y2)进行表示。
    另外,还可以采用边界框矩形的中心坐标(xc,yc)以及宽高(w,h)进行表示
(1)"左上-右下"转换为"中心-宽高"
def box_corner_to_center(boxes):
    """从(左上,右下)转换到(中间,宽度,高度)"""
    x1, y1, x2, y2 = boxes[:, 0], boxes[:, 1], boxes[:, 2], boxes[:, 3]
    cx = (x1 + x2) / 2
    cy = (y1 + y2) / 2
    w = x2 - x1
    h = y2 - y1
    boxes = torch.stack((cx, cy, w, h), axis=-1)
    return boxes
(2)"中心-宽高"转换为"左上-右下"

def box_center_to_corner(boxes):
    """从(中间,宽度,高度)转换到(左上,右下)"""
    cx, cy, w, h = boxes[:, 0], boxes[:, 1], boxes[:, 2], boxes[:, 3]
    x1 = cx - 0.5 * w
    y1 = cy - 0.5 * h
    x2 = cx + 0.5 * w
    y2 = cy + 0.5 * h
    boxes = torch.stack((x1, y1, x2, y2), axis=-1)
    return boxes
(3)画出目标框(dog_bbox采用绿色,cat_bbox采用红色)

def bbox_to_rect(bbox, color):
    # 将边界框(左上x,左上y,右下x,右下y)格式转换成matplotlib格式:
    # ((左上x,左上y),宽,高)
    return plt.Rectangle(
        xy=(bbox[0], bbox[1]), width=bbox[2]-bbox[0], height=bbox[3]-bbox[1],
        fill=False, edgecolor=color, linewidth=2)
img = plt.imread('1.jpg')
fig = plt.imshow(img)
fig.axes.add_patch(bbox_to_rect(dog_bbox, 'blue'))
fig.axes.add_patch(bbox_to_rect(cat_bbox, 'red'))
plt.show()

点云3D框

 一个3D边界框可以由7个参数决定:位置(x,y,z)、尺寸(l w h)以及朝向角/偏航角/旋转角 。
将与物体朝向平行的棱的长度记为边界框长度l,竖直方向棱的长度记为边界框高度h,余下一组棱的长度记为边界框宽度w	 

box2corner

    '''
    bboxes: shape=(n, 7)
    return: shape=(n, 8, 3)
           ^ z   x            8 ------ 7
           |   /             / |     / |
           |  /-l/2,w/2,h/2)5 -|---- 6 |(-l/2,-w/2,h/2)   
    y      | /              |  |     | | 
    <------|o               | 4 -----| 3(l/2,-w/2,-h/2)
                            |/   o   |/    
            (-l/2,w/2,-h/2) 1 ------ 2  (-l/2,-w/2,-h/2)
    x: front, y: left, z: top
    '''
def box2corner(box):
    x = box[0]
    y = box[1]
    z = box[2]
    l = box[3]  # dx
    w = box[4]  # dy
    h = box[5]  # dz
    yaw = box[6]
    Box = np.array(
        [
            [-l / 2, -l / 2, l / 2, l / 2, -l / 2, -l / 2, l / 2, l / 2],
            [w / 2, -w / 2, -w / 2, w / 2, w / 2, -w / 2, -w / 2, w / 2],
            [-h / 2, -h / 2, -h / 2, -h / 2, h / 2, h / 2, h / 2, h / 2],
        ]
    )
    # 先旋转再平移
    R = rotz(yaw)
    corners_3d = np.dot(R, Box)  # corners_3d: (3, 8)
    corners_3d[0, :] = corners_3d[0, :] + x
    corners_3d[1, :] = corners_3d[1, :] + y
    corners_3d[2, :] = corners_3d[2, :] + z
    return np.transpose(corners_3d)	

3dbox

center_to_corner_box3d
    目的是将边界框的位置、尺寸、朝向角参数转换为边界框的8个角点坐标
def bbox3d_center2corners(bboxes):
    '''
    bboxes: shape=(n, 7)
    return: shape=(n, 8, 3)
           ^ z   x            6 ------ 5
           |   /             / |     / |
           |  /             2 -|---- 1 |   
    y      | /              |  |     | | 
    <------|o               | 7 -----| 4
                            |/   o   |/    
                            3 ------ 0 
    x: front, y: left, z: top
    '''
    centers, dims, angles = bboxes[:, :3], bboxes[:, 3:6], bboxes[:, 6]
    # # 1.generate bbox corner coordinates, clockwise from minimal point   
    bboxes_corners =np.array([[-0.5, 0.5, 0], [-0.5, -0.5, 0],   [0.5, -0.5, 0],   [0.5, 0.5, 0],
                             [-0.5, 0.5, 1.0],[-0.5, -0.5, 1.0], [0.5, -0.5, 1.0], [0.5, 0.5, 1.0]], 
                               dtype=np.float32)  
    bboxes_corners = bboxes_corners[None, :, :] * dims[:, None, :] # (1, 8, 3) * (n, 1, 3) -> (n, 8, 3)
 
    # # 2. rotate around z axis
    rot_sin ,rot_cos = np.sin(angles),np.cos(angles) 
    ones ,zeros= np.ones_like(rot_cos), np.zeros_like(rot_cos) 
    rot_mat = np.array([[rot_cos, rot_sin, zeros],
                        [-rot_sin, rot_cos, zeros],
                        [zeros, zeros, ones]], 
                        dtype=np.float32) # (3, 3, n)

    rot_mat = np.transpose(rot_mat, (2, 0, 1)) # (n, 3, 3)
    bboxes_corners =  np.matmul(bboxes_corners,rot_mat) # (n, 8, 3)

    # # 3. translate to centers
    bboxes_corners += centers[:, None, :]
 
    return bboxes_corners

corner_to_center_box3d

 # -*- cooing:UTF-8 -*-

# File Name : utils.py
# Purpose :
# Creation Date : 09-12-2017

def angle_in_limit(angle):
    # To limit the angle in -pi/2 - pi/2
    limit_degree = 5
    while angle >= np.pi / 2:
        angle -= np.pi
    while angle < -np.pi / 2:
        angle += np.pi
    if abs(angle + np.pi / 2) < limit_degree / 180 * np.pi:
        angle = np.pi / 2
    return angle
# TODO: 0/90 may be not correct

def corner_to_center_box3d(boxes_corner, coordinate='camera', calib_mat=None):
    # (N, 8, 3) -> (N, 7) x,y,z,h,w,l,ry/z
    if coordinate == 'lidar':
        for idx in range(len(boxes_corner)):
            boxes_corner[idx] = lidar_to_camera_point(boxes_corner[idx], calib_mat=calib_mat)
    ret = []
    for roi in boxes_corner:
        if cfg.CORNER2CENTER_AVG:  # average version
            roi = np.array(roi)
            h = abs(np.sum(roi[:4, 1] - roi[4:, 1]) / 4)
            w = np.sum(
                np.sqrt(np.sum((roi[0, [0, 2]] - roi[3, [0, 2]])**2)) +
                np.sqrt(np.sum((roi[1, [0, 2]] - roi[2, [0, 2]])**2)) +
                np.sqrt(np.sum((roi[4, [0, 2]] - roi[7, [0, 2]])**2)) +
                np.sqrt(np.sum((roi[5, [0, 2]] - roi[6, [0, 2]])**2))
            ) / 4
            l = np.sum(
                np.sqrt(np.sum((roi[0, [0, 2]] - roi[1, [0, 2]])**2)) +
                np.sqrt(np.sum((roi[2, [0, 2]] - roi[3, [0, 2]])**2)) +
                np.sqrt(np.sum((roi[4, [0, 2]] - roi[5, [0, 2]])**2)) +
                np.sqrt(np.sum((roi[6, [0, 2]] - roi[7, [0, 2]])**2))
            ) / 4
            x, y, z = np.sum(roi, axis=0) / 8
            y = y + h/2
            ry = np.sum(
                math.atan2(roi[2, 0] - roi[1, 0], roi[2, 2] - roi[1, 2]) +
                math.atan2(roi[6, 0] - roi[5, 0], roi[6, 2] - roi[5, 2]) +
                math.atan2(roi[3, 0] - roi[0, 0], roi[3, 2] - roi[0, 2]) +
                math.atan2(roi[7, 0] - roi[4, 0], roi[7, 2] - roi[4, 2]) +
                math.atan2(roi[0, 2] - roi[1, 2], roi[1, 0] - roi[0, 0]) +
                math.atan2(roi[4, 2] - roi[5, 2], roi[5, 0] - roi[4, 0]) +
                math.atan2(roi[3, 2] - roi[2, 2], roi[2, 0] - roi[3, 0]) +
                math.atan2(roi[7, 2] - roi[6, 2], roi[6, 0] - roi[7, 0])
            ) / 8
            if w > l:
                w, l = l, w
                ry = angle_in_limit(ry + np.pi / 2)
        else:  # max version
            h = max(abs(roi[:4, 1] - roi[4:, 1]))
            w = np.max(
                np.sqrt(np.sum((roi[0, [0, 2]] - roi[3, [0, 2]])**2)) +
                np.sqrt(np.sum((roi[1, [0, 2]] - roi[2, [0, 2]])**2)) +
                np.sqrt(np.sum((roi[4, [0, 2]] - roi[7, [0, 2]])**2)) +
                np.sqrt(np.sum((roi[5, [0, 2]] - roi[6, [0, 2]])**2))
            )
            l = np.max(
                np.sqrt(np.sum((roi[0, [0, 2]] - roi[1, [0, 2]])**2)) +
                np.sqrt(np.sum((roi[2, [0, 2]] - roi[3, [0, 2]])**2)) +
                np.sqrt(np.sum((roi[4, [0, 2]] - roi[5, [0, 2]])**2)) +
                np.sqrt(np.sum((roi[6, [0, 2]] - roi[7, [0, 2]])**2))
            )
            x, y, z = np.sum(roi, axis=0) / 8
            y = y + h/2
            ry = np.sum(
                math.atan2(roi[2, 0] - roi[1, 0], roi[2, 2] - roi[1, 2]) +
                math.atan2(roi[6, 0] - roi[5, 0], roi[6, 2] - roi[5, 2]) +
                math.atan2(roi[3, 0] - roi[0, 0], roi[3, 2] - roi[0, 2]) +
                math.atan2(roi[7, 0] - roi[4, 0], roi[7, 2] - roi[4, 2]) +
                math.atan2(roi[0, 2] - roi[1, 2], roi[1, 0] - roi[0, 0]) +
                math.atan2(roi[4, 2] - roi[5, 2], roi[5, 0] - roi[4, 0]) +
                math.atan2(roi[3, 2] - roi[2, 2], roi[2, 0] - roi[3, 0]) +
                math.atan2(roi[7, 2] - roi[6, 2], roi[6, 0] - roi[7, 0])
            ) / 8
            if w > l:
                w, l = l, w
                ry = angle_in_limit(ry + np.pi / 2)
        ret.append([x, y, z, h, w, l, ry])
    if coordinate == 'lidar':
        ret = camera_to_lidar_box(np.array(ret), calib_mat=calib_mat)
    return np.array(ret)

if __name__ == '__main__':
    pass

参考

 目标检测(一):目标框和锚框 https://zhuanlan.zhihu.com/p/605626695
 https://github.com/geaxgx/depthai_blazepose/blob/main/o3d_utils.py
 https://stackoverflow.com/questions/59026581/create-arrows-in-open3d
 MMDetection3D/3D目标检测中的边界框和坐标系介绍 https://blog.csdn.net/weixin_45657478/article/details/126860028
 https://github.com/tianweiy/CenterPoint/blob/master/det3d/core/bbox/box_np_ops.py
 https://github.com/Kiwoo/voxel_yolonet/blob/master/utils/utils.py

标签:roi,--,sum,角点,sqrt,np,boxes,点云,math
From: https://www.cnblogs.com/ytwang/p/18349419

相关文章

  • 分享一个200年日历的黄道吉日sql数据打包供下载以及推荐一个好用的基于bootstrap的颜
    一、分享一个200年日历的黄道吉日sql数据打包    自己抓取的一套200年(1900-2100)全部日期的黄道吉日数据,分享出来,也在此备份以备以后自己要用。包括每天年月日,干支年,干支月,干支日,星期,阳历,农历,阴历月份,阴历日期,星座,胎神,五行,冲,煞,生肖,吉日,值......
  • 分页:Paginator
    提要:列表分页主要是明白:列表当前需要显示内容索引=(列表当前页数-1)*每页显示条数 至 列表当前页数*每页显示条数一、Django的内置分页Django内置的分页需要使用到3个类:Paginator、EmptyPage、PageNotAnInteger1.1Paginator介绍paginator=Paginator(全部数据,每页显示条......
  • AI赋能周界安防:智能视频分析技术构建无懈可击的安全防线
    周界安全防范是保护机场、电站、油库、监狱、工业园区等关键设施免受非法入侵和破坏的重要措施。传统的周界安防手段主要依靠人员巡查和物理屏障,但这种方式不仅人力成本高,而且效率较低,难以满足日益复杂多变的安全需求。随着AI技术的引入,特别是视频智能分析技术的成熟,周界安全防范......
  • 使用SixLabors.ImageSharp 进行图片的缩放C#.net core,可跨平台运行
    引用命令空间usingSixLabors.ImageSharp;using SixLabors.ImageSharp.Formats.Png;using SixLabors.ImageSharp.Processing; publicstaticvidResize(byte[]imageBytes,intwidth=400){usingvarsteam=newMemoryStream(imageBytes);using(varimage=......
  • 揭秘人工智能三大基石:数据、算法与算力的深度融合
    在科技日新月异的今天,人工智能(AI)作为引领未来科技浪潮的核心力量,正以前所未有的速度改变着我们的生活、工作乃至整个社会的面貌。人工智能的快速发展并非偶然,而是建立在三大坚实基石之上:数据、算法与计算能力。这三者相辅相成,共同构筑了人工智能技术的基石,推动了AI技术的不断突破......
  • 2024-08-07 多校联合暑假训练赛第四场 补题+分析
    A.小盒子题意+思路:题意其实概括的不是非常准确简要题意:圆盒有n个格子,格子自带ai个棋子.是否通过任意起点通过顺时针-1,-2,...,-n的操作使得圆盒中所有所有的棋子都为0思路:贪心对于所有棋子通过顺时针操作的时候每一次都是(1+n)*n/2次是一个等差公式所以......
  • 打造“明厨亮灶”方案:AI+视频智能监管让食品安全与透明度并行
    在食品安全日益成为公众关注焦点的今天,提升餐饮行业的透明度,增强消费者信任,已成为行业发展的重要趋势。其中,“明厨亮灶”作为一种创新的餐饮管理模式,正逐步成为提升食品安全水平、促进餐饮业健康发展的有效手段。明厨亮灶主要服务于市场监管部门、餐饮部门等行业主管部门,“AI智能......
  • Windows 7 X64系统安装无签名驱动后设备管理器显示黄色叹号的解决办法
    因项目需要在工控机上安装了串口转USB转换器的驱动程序安装时提示缺少数字签名点击“仍然安装”查看设备管理器发现该串口设备上显示黄色叹号根据网上说法 重启设备时长按F8在菜单中选择“禁用安装驱动时强制签名”进入系统后黄色叹号消失设备可以正常使用但该方法仅在......
  • hystrix
    Hystrix是Netflix开发的一个延迟和容错库,它能够帮助服务在高并发、分布式环境下实现优雅的降级和隔离,从而提高整个系统的稳定性和可用性。虽然Hystrix最常与SpringCloud结合使用,但你也可以在非SpringCloud的Java应用中单独使用Hystrix。下面是一个不使用SpringClo......
  • milvus-cli安装部署
    环境:OS:Centos7milvus:2.3.5milvus-cli:1.0.01.在线安装你可以使用Python包管理在线安装,注意Python版本要在3.9以上。在线安装只需要一条命令即可:[root@host134bin]#pip-Vpip23.0.1from/usr/local/lib/python3.8/site-packages/pip(python3.8)[root@host1......