Cesium 动态绘制点、线、面工具封装

 最近做Cesium动态绘制,找了一个工具类,在这个基础上完善了一些功能,效果图:

deno如下:完善的内容主要有圆的边框,矩形两种实现方式,注释基本都有写


/**
 * @description cesium绘制 点、线、面
 * @export
 * @class Draw
 * @example
 * let draw = new Draw(viewer)
 * draw.drawCircle();
 */
export default class Draw {
    constructor(viewer, config) {
        /**cesium实例对象 */
        this.viewer = viewer;
        // 默认配置
        this.config = config || {
            // 几何-边框宽度
            borderWidth: 2,
            // 几何-边框颜色
            borderColor: Cesium.Color.WHITE,
            lineColor: Cesium.Color.fromCssColorString("#00ffff"),
            // 填充材质
            material: Cesium.Color.fromCssColorString("#00ffff").withAlpha(0.4)
        };
        /**存贮绘制的数据 坐标 */
        this.infoDetail = { point: [], line: [], rectangle: [], circle: [], planeSelf: [] };
        this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
    }
    /******* 
     * @function: function
     * @return {*}
     * @description: 绘制点数据
     */
    drawPoint() {
        this.handler.destroy();

        this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
        this.handler.setInputAction((click) => {
            /**点击位置笛卡尔坐标 */
            let cartesian = this.viewer.camera.pickEllipsoid(click.position, this.viewer.scene.globe.ellipsoid);
            /**笛卡尔转弧度坐标 */
            let cartographic = Cesium.Cartographic.fromCartesian(cartesian, this.viewer.scene.globe.ellipsoid, new Cesium.Cartographic());
            /**点击位置经度 */
            let lng = Cesium.Math.toDegrees(cartographic.longitude);
            /**点击位置维度 */
            let lat = Cesium.Math.toDegrees(cartographic.latitude);
            /**实体的唯一标注 */
            let id = new Date().getTime();
            this.viewer.entities.add({
                position: Cesium.Cartesian3.fromDegrees(lng, lat, 0),
                name: 'point',
                id: id,
                point: {
                    color: this.config.material,
                    pixelSize: 12,
                    outlineColor: this.config.borderColor,
                    outlineWidth: this.config.borderWidth
                }
            });
            this.infoDetail.point.push({ id: id, position: [lng, lat] });

        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

        this.handler.setInputAction((click) => {
            this.handler.destroy();
        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
    }

    /******* 
     * @function: function
     * @description: 绘制矩形区域
     * @return {*}
     */
    drawRectangle() {
        this.handler.destroy();
        /**
         * 矩形四点坐标
         */
        let westSouthEastNorth = [];
        /**实体的唯一标注 */
        let id = null;
        // 矩形绘制类型-- polygon、rectangle
        const rectangleType = 'polygon';
        /**地图点击对象 */
        this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
        this.handler.setInputAction((click) => {
            /**点击位置笛卡尔坐标 */
            let cartesian = this.viewer.camera.pickEllipsoid(click.position, this.viewer.scene.globe.ellipsoid);
            /**笛卡尔转弧度坐标 */
            let cartographic = Cesium.Cartographic.fromCartesian(cartesian, this.viewer.scene.globe.ellipsoid, new Cesium.Cartographic());
            /**点击位置经度 */
            let lng1 = Cesium.Math.toDegrees(cartographic.longitude);
            /**点击位置维度 */
            let lat1 = Cesium.Math.toDegrees(cartographic.latitude);
            /**边框坐标 */
            westSouthEastNorth = [lng1, lat1];
            id = new Date().getTime();
            if (westSouthEastNorth) {
                this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
            }
            // 面实例对象
            const rectangleStyle = {
                height: 0,
                // 填充的颜色,withAlpha透明度
                material: this.config.material,
                // 是否被提供的材质填充
                fill: true,
                // 是否显示
                show: true,
            };
            // 
            let rectangleOptions = {
                name: 'rectangle',
                id: id,
                polyline: {
                    positions: new Cesium.CallbackProperty(function () { return Cesium.Cartesian3.fromDegreesArray(westSouthEastNorth) }),
                    material: this.config.borderColor,
                    width: this.config.borderWidth,
                    zIndex: 1
                }
            }
            // 根据polygon绘制矩形
            if (rectangleType === 'polygon') {
                rectangleOptions['polygon'] = {
                    hierarchy: new Cesium.CallbackProperty(function () {
                        return {
                            positions: Cesium.Cartesian3.fromDegreesArray(westSouthEastNorth)
                        }
                    }),
                    ...rectangleStyle
                };
            }
            // 根据rectangle绘制矩形
            if (rectangleType === 'rectangle') {
                rectangleOptions['rectangle'] = {
                    coordinates: new Cesium.CallbackProperty(function () {
                        const rectangle = Cesium.Rectangle.fromCartesianArray(Cesium.Cartesian3.fromDegreesArray(westSouthEastNorth));
                        // 计算矩形四个角的坐标,绘制完成调用,此处为测试
                        // 西北角弧度坐标(左上)
                        // const northwest = Cesium.Rectangle.northwest(rectangle);
                        // 西南角弧度坐标(左下)
                        // const southwest = Cesium.Rectangle.southwest(rectangle);
                        // 东北角弧度坐标(右上)
                        // const northeast = Cesium.Rectangle.northeast(rectangle);
                        // 东南角弧度坐标(右下)
                        // const southeast = Cesium.Rectangle.southeast(rectangle);
                        // console.log(Cesium.Math.toDegrees(northwest.longitude));
                        // console.log(Cesium.Math.toDegrees(northwest.latitude));
                        // console.log(northwest.height);
                        return rectangle;
                    }, false),
                    ...rectangleStyle
                };
            }
            /**面实例对象 */
            let polygons = this.viewer.entities.add(rectangleOptions);
            this.handler.setInputAction((move) => {
                let cartesian = this.viewer.camera.pickEllipsoid(move.endPosition, this.viewer.scene.globe.ellipsoid);
                let cartographic = Cesium.Cartographic.fromCartesian(cartesian, this.viewer.scene.globe.ellipsoid, new Cesium.Cartographic());
                let lng = Cesium.Math.toDegrees(cartographic.longitude);
                let lat = Cesium.Math.toDegrees(cartographic.latitude);

                westSouthEastNorth = [lng1, lat1, lng1, lat, lng, lat, lng, lat1, lng1, lat1];


            }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

        this.handler.setInputAction(() => {
            this.handler.destroy();
            this.infoDetail.rectangle.push({ id: id, position: westSouthEastNorth });
        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
    }
    /******* 
     * @function: function
     * @description: 绘制圆形区域
     * @return {*}
     */
    drawCircle() {
        this.handler.destroy();
        /**实体的唯一标注 */
        let id = null;
        /**圆半径 */
        let radius = 0;
        /**圆心 */
        let lngLat = [];
        // 圆边界坐标
        let boundaryPositions = [];
        /**鼠标事件 */
        this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
        this.handler.setInputAction((click) => {
            id = new Date().getTime();
            let cartesian = this.viewer.camera.pickEllipsoid(click.position, this.viewer.scene.globe.ellipsoid);
            let cartographic = Cesium.Cartographic.fromCartesian(cartesian, this.viewer.scene.globe.ellipsoid, new Cesium.Cartographic());
            let lng = Cesium.Math.toDegrees(cartographic.longitude);
            let lat = Cesium.Math.toDegrees(cartographic.latitude);
            lngLat = [lng, lat];
            let entity = this.viewer.entities.add({
                position: new Cesium.CallbackProperty(function () { return new Cesium.Cartesian3.fromDegrees(...lngLat, 0) }, false),
                name: 'circle',
                id: id,
                ellipse: {
                    height: 0,
                    material: this.config.material
                },
                polyline: {
                    width: this.config.borderWidth,
                    material: this.config.borderColor
                }
            });

            entity.ellipse.semiMajorAxis = new Cesium.CallbackProperty(function () { return radius; }, false);
            entity.ellipse.semiMinorAxis = new Cesium.CallbackProperty(function () { return radius; }, false);
            entity.polyline.positions = new Cesium.CallbackProperty(function () { return boundaryPositions; }, false);

            if (lngLat) {
                this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
            }
            this.handler.setInputAction((move) => {
                boundaryPositions = [];
                let cartesian2 = this.viewer.camera.pickEllipsoid(move.endPosition, this.viewer.scene.globe.ellipsoid);
                if (Cesium.defined(cartesian2)) {
                    radius = Cesium.Cartesian3.distance(cartesian, cartesian2);
                    // 计算几何体圆的轮廓
                    let circleOutlineGeometryCreate = Cesium.CircleOutlineGeometry.createGeometry(new Cesium.CircleOutlineGeometry({
                        center: new Cesium.Cartesian3.fromDegrees(...lngLat, 0),
                        radius: radius || 1,
                        granularity: 0.01
                    }));
                    // 获取几何体圆的边界坐标
                    let positions = [].slice.call(circleOutlineGeometryCreate.attributes.position.values);
                    for (let i = 0; i < positions.length; i += 3) {
                        boundaryPositions.push(new Cesium.Cartesian3(positions[i], positions[i + 1], positions[i + 2]));
                    }
                    // 添加第一个点,实现闭合圆
                    if (boundaryPositions.length !== 0) {
                        boundaryPositions.push(boundaryPositions[0]);
                    }
                }
            }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

        this.handler.setInputAction(() => {
            this.infoDetail.circle.push({ id: id, center: lngLat, radius: radius });
            this.handler.destroy();
        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
    }
    /******* 
     * @function: function
     * @description: 自定义区域绘制
     * @return {*}
     */
    drawPlane() {
        this.handler.destroy();
        /**实体的唯一标注 */
        let id = new Date().getTime();
        /**记录拐点坐标 */
        let positions = [],
            /**记录返回结果 */
            codeInfo = [],
            /**面的hierarchy属性 */
            polygon = new Cesium.PolygonHierarchy(),
            _polygonEntity = new Cesium.Entity(),
            /**面对象配置 */
            polyObj = null;
        this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
        // left
        this.handler.setInputAction((movement) => {
            let cartesian = this.viewer.camera.pickEllipsoid(movement.position, this.viewer.scene.globe.ellipsoid);
            let cartographic = Cesium.Cartographic.fromCartesian(cartesian, this.viewer.scene.globe.ellipsoid, new Cesium.Cartographic());
            let lng = Cesium.Math.toDegrees(cartographic.longitude);
            let lat = Cesium.Math.toDegrees(cartographic.latitude);


            if (cartesian && cartesian.x) {
                if (positions.length == 0) {
                    positions.push(cartesian.clone());
                }
                codeInfo.push([lng, lat]);
                positions.push(cartesian.clone());
                polygon.positions.push(cartesian.clone());
                if (!polyObj) {
                    _polygonEntity.polyline = {
                        width: this.config.borderWidth,
                        material: this.config.borderColor,
                        clampToGround: false
                    };
                    _polygonEntity.polyline.positions = new Cesium.CallbackProperty(function () {
                        return positions;
                    }, false);

                    _polygonEntity.polygon = {

                        hierarchy: new Cesium.CallbackProperty(function () {
                            return polygon;
                        }, false),

                        material: this.config.material,
                        clampToGround: false
                    }
                    _polygonEntity.name = 'planeSelf'

                    _polygonEntity._id = id;
                    polyObj = this.viewer.entities.add(_polygonEntity);
                }
            }
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
        // mouse
        this.handler.setInputAction((movement) => {
            let cartesian = this.viewer.camera.pickEllipsoid(movement.endPosition, this.viewer.scene.globe.ellipsoid);
            if (Cesium.defined(cartesian)) {
                let cartographic = Cesium.Cartographic.fromCartesian(cartesian, this.viewer.scene.globe.ellipsoid, new Cesium.Cartographic());
                let lng = Cesium.Math.toDegrees(cartographic.longitude);
                let lat = Cesium.Math.toDegrees(cartographic.latitude);

                if (positions.length >= 0) {
                    if (cartesian && cartesian.x) {
                        positions.pop();
                        positions.push(cartesian);
                        polygon.positions.pop();
                        polygon.positions.push(cartesian);
                        codeInfo.pop();
                        codeInfo.push([lng, lat]);
                    }
                }
            }
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

        // right
        this.handler.setInputAction((movement) => {
            this.infoDetail.planeSelf.push({ id: id, positions: codeInfo });

            this.handler.destroy();
            positions.push(positions[0]);
        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

    }

    /******* 
     * @function: function
     * @return {*}
     * @description: 绘制线段
     */
    drawLine() {
        this.handler.destroy();
        /**实体的唯一标注 */
        let id = null;
        /**记录拐点坐标 */
        let positions = [],
            /**记录返回结果 */
            codeInfo = [],
            /**面的hierarchy属性 */
            polygon = new Cesium.PolygonHierarchy(),
            _polygonEntity = new Cesium.Entity(),
            /**面对象配置 */
            polyObj = null;
        this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
        // left
        this.handler.setInputAction((movement) => {
            id = new Date().getTime();
            let cartesian = this.viewer.camera.pickEllipsoid(movement.position, this.viewer.scene.globe.ellipsoid);
            let cartographic = Cesium.Cartographic.fromCartesian(cartesian, this.viewer.scene.globe.ellipsoid, new Cesium.Cartographic());
            let lng = Cesium.Math.toDegrees(cartographic.longitude);
            let lat = Cesium.Math.toDegrees(cartographic.latitude);

            if (cartesian && cartesian.x) {
                if (positions.length == 0) {
                    positions.push(cartesian.clone());
                }
                codeInfo.push([lng, lat])
                positions.push(cartesian.clone());
                polygon.positions.push(cartesian.clone());
                if (!polyObj) {
                    _polygonEntity.polyline = {
                        width: this.config.borderWidth,
                        material: this.config.lineColor,
                        clampToGround: false
                    };
                    _polygonEntity.polyline.positions = new Cesium.CallbackProperty(function () {
                        return positions;
                    }, false);
                    _polygonEntity.name = 'line';
                    _polygonEntity._id = id;

                    polyObj = this.viewer.entities.add(_polygonEntity);
                }
            }

        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
        // mouse
        this.handler.setInputAction((movement) => {
            let cartesian = this.viewer.camera.pickEllipsoid(movement.endPosition, this.viewer.scene.globe.ellipsoid);
            if (Cesium.defined(cartesian)) {
                let cartographic = Cesium.Cartographic.fromCartesian(cartesian, this.viewer.scene.globe.ellipsoid, new Cesium.Cartographic());
                let lng = Cesium.Math.toDegrees(cartographic.longitude);
                let lat = Cesium.Math.toDegrees(cartographic.latitude);

                if (positions.length >= 0) {
                    if (cartesian && cartesian.x) {
                        positions.pop();
                        positions.push(cartesian);
                        codeInfo.pop();
                        codeInfo.push([lng, lat]);
                    }
                }
            }
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

        // right
        this.handler.setInputAction((movement) => {
            this.infoDetail.line.push({ id: id, positions: codeInfo });
            this.handler.destroy();
        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
    }
    /******* 
     * @function: function
     * @description: 移除实体对象
     * @return {*}
     */
    removeEntity() {
        this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
        this.handler.setInputAction((move) => {
            /**实体对象信息  {id:entities,primitive:。。} */
            let pick = this.viewer.scene.pick(move.endPosition);

            if (pick && pick.id && pick.id.id) {
                document.body.style.cursor = "pointer";
                this.handler.setInputAction((click) => {
                    let newPoint;
                    switch (pick.id.name) {

                        case 'point':
                            /**删除某一条数据 */
                            newPoint = this.infoDetail.point.filter(item => item.id != pick.id._id);
                            this.infoDetail.point = newPoint;
                            break
                        case 'line':
                            /**删除某一条数据 */
                            newPoint = this.infoDetail.line.filter(item => item.id != pick.id._id);
                            this.infoDetail.line = newPoint;
                            break
                        case 'rectangle':
                            /**删除某一条数据 */
                            newPoint = this.infoDetail.rectangle.filter(item => item.id != pick.id._id);
                            this.infoDetail.rectangle = newPoint;
                            break

                        case 'planeSelf':
                            /**删除某一条数据 */
                            newPoint = this.infoDetail.planeSelf.filter(item => item.id != pick.id._id);
                            this.infoDetail.planeSelf = newPoint;
                            break
                        case 'circle':
                            /**删除某一条数据 */
                            newPoint = this.infoDetail.circle.filter(item => item.id != pick.id._id);
                            this.infoDetail.circle = newPoint;
                            break
                        default: break
                    }
                    this.viewer.entities.remove(pick.id);
                }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

            } else {

                document.body.style = "cursor: default;";

            }
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    }
    /******* 
     * @function: function
     * @return {*}
     * @description: 返回绘制数据
     */
    backInfoDetail() {
        return this.infoDetail;
    }
    /**
     * @description 计算空间两点间距离(计算第一个点、最后一个点)-方法1
     * @param {*} lat1
     * @param {*} lng1
     * @param {*} lat2
     * @param {*} lng2
     * @return {*} m
     */
    getSpaceDistance_first_last_1(lat1, lng1, lat2, lng2) {
        var EARTH_RADIUS = 6378137.0;    //单位M
        var PI = Math.PI;

        function getRad(d) {
            return d * PI / 180.0;
        }
        var f = getRad((lat1 + lat2) / 2);
        var g = getRad((lat1 - lat2) / 2);
        var l = getRad((lng1 - lng2) / 2);

        var sg = Math.sin(g);
        var sl = Math.sin(l);
        var sf = Math.sin(f);

        var s, c, w, r, d, h1, h2;
        var a = EARTH_RADIUS;
        var fl = 1 / 298.257;

        sg = sg * sg;
        sl = sl * sl;
        sf = sf * sf;

        s = sg * (1 - sl) + (1 - sf) * sl;
        c = (1 - sg) * (1 - sl) + sf * sl;

        w = Math.atan(Math.sqrt(s / c));
        r = Math.sqrt(s * c) / w;
        d = 2 * w * a;
        h1 = (3 * r - 1) / 2 / c;
        h2 = (3 * r + 1) / 2 / s;

        return d * (1 + fl * (h1 * sf * (1 - sg) - h2 * (1 - sf) * sg));
    }
    /**
     * @description 计算空间两点间距离(计算数组第一个点、最后一个点)-方法2
     * @param {*} positions [Cartesian3 { x, y, z }]
     * @return {*} m
     */
    getSpaceDistance_first_last_2(positions) {
        let distance = 0;
        for (let i = 0; i < positions.length - 1; i++) {
            const point1cartographic = Cesium.Cartographic.fromCartesian(positions[0]);
            const point2cartographic = Cesium.Cartographic.fromCartesian(positions[positions.length - 1]);
            // 根据经纬度计算出距离
            const geodesic = new Cesium.EllipsoidGeodesic();
            // 设置测地线的起点和终点
            geodesic.setEndPoints(point1cartographic, point2cartographic);
            // 获取起点和终点之间的表面距离
            let s = geodesic.surfaceDistance;
            //返回两点之间的距离
            s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2));
            distance = s;
        }
        return distance.toFixed(2);
    }
    /**
     * @description 空间两点距离计算函数(每次计算数组最后两个点之间的距离)
     * @param {*} positions [Cartesian3 { x, y, z }]
     * @return {*} m
     */
    getSpaceDistance_last_last(positions) {
        let distance = 0;
        for (let i = 0; i < positions.length - 1; i++) {
            const point1cartographic = Cesium.Cartographic.fromCartesian(positions[positions.length - 1]);
            const point2cartographic = Cesium.Cartographic.fromCartesian(positions[positions.length - 2]);
            // 根据经纬度计算出距离
            const geodesic = new Cesium.EllipsoidGeodesic();
            // 设置测地线的起点和终点
            geodesic.setEndPoints(point1cartographic, point2cartographic);
            // 获取起点和终点之间的表面距离
            let s = geodesic.surfaceDistance;
            //返回两点之间的距离
            s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2));
            distance = s;
        }
        return distance.toFixed(2);
    }
    /**
     * @description 空间两点距离计算函数(所有点之间的距离相加)
     * @param {*} positions Cartesian3 { x, y, z }
     * @return {*} m
     */
    getSpaceDistance_all(positions) {
        let distance = 0;
        for (let i = 0; i < positions.length - 1; i++) {
            const point1cartographic = Cesium.Cartographic.fromCartesian(positions[i]);
            const point2cartographic = Cesium.Cartographic.fromCartesian(positions[i + 1]);
            // 根据经纬度计算出距离
            const geodesic = new Cesium.EllipsoidGeodesic();
            // 设置测地线的起点和终点
            geodesic.setEndPoints(point1cartographic, point2cartographic);
            // 获取起点和终点之间的表面距离
            let s = geodesic.surfaceDistance;
            //返回两点之间的距离
            s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2));
            distance = distance + s;
        }
        return distance.toFixed(2);
    }
}

调用方式:

let draw = new Draw(viewer)
draw.drawCircle();

再绘制完成后获取坐标信息,可以在drawXxxx函数中添加回调函数,使用函数接收,如下:

drawCircle(callBack) {
    ...
    callback(this.infoDetail.circle);
}
// 回调函数接收
draw.drawCircle((res) => {
    // res === this.infoDetail.circle
});

参考文章:cesium动态绘制圆,矩形,自定义区域_cesium动态绘制矩形_LBY_XK的博客-优快云博客 

### RT-DETRv3 网络结构分析 RT-DETRv3 是一种基于 Transformer 的实时端到端目标检测算法,其核心在于通过引入分层密集正监督方法以及一系列创新性的训练策略,解决了传统 DETR 模型收敛慢和解码器训练不足的问题。以下是 RT-DETRv3 的主要网络结构特点: #### 1. **基于 CNN 的辅助分支** 为了增强编码器的特征表示能力,RT-DETRv3 引入了一个基于卷积神经网络 (CNN) 的辅助分支[^3]。这一分支提供了密集的监督信号,能够与原始解码器协同工作,从而提升整体性能。 ```python class AuxiliaryBranch(nn.Module): def __init__(self, in_channels, out_channels): super(AuxiliaryBranch, self).__init__() self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1) self.bn = nn.BatchNorm2d(out_channels) def forward(self, x): return F.relu(self.bn(self.conv(x))) ``` 此部分的设计灵感来源于传统的 CNN 架构,例如 YOLO 系列中的 CSPNet 和 PAN 结构[^2],这些技术被用来优化特征提取效率并减少计算开销。 --- #### 2. **自注意力扰动学习策略** 为解决解码器训练不足的问题,RT-DETRv3 提出了一种名为 *self-att 扰动* 的新学习策略。这种策略通过对多个查询组中阳性样本的标签分配进行多样化处理,有效增加了阳例的数量,进而提高了模型的学习能力和泛化性能。 具体实现方式是在训练过程中动态调整注意力权重分布,确保更多的高质量查询可以与真实标注 (Ground Truth) 进行匹配。 --- #### 3. **共享权重解编码器分支** 除了上述改进外,RT-DETRv3 还引入了一个共享权重的解编码器分支,专门用于提供密集的正向监督信号。这一设计不仅简化了模型架构,还显著降低了参数量和推理时间,使其更适合实时应用需求。 ```python class SharedDecoderEncoder(nn.Module): def __init__(self, d_model, nhead, num_layers): super(SharedDecoderEncoder, self).__init__() decoder_layer = nn.TransformerDecoderLayer(d_model=d_model, nhead=nhead) self.decoder = nn.TransformerDecoder(decoder_layer, num_layers=num_layers) def forward(self, tgt, memory): return self.decoder(tgt=tgt, memory=memory) ``` 通过这种方式,RT-DETRv3 实现了高效的目标检测流程,在保持高精度的同时大幅缩短了推理延迟。 --- #### 4. **与其他模型的关系** 值得一提的是,RT-DETRv3 并未完全抛弃经典的 CNN 技术,而是将其与 Transformer 结合起来形成混合架构[^4]。例如,它采用了 YOLO 系列中的 RepNCSP 模块替代冗余的多尺度自注意力层,从而减少了不必要的计算负担。 此外,RT-DETRv3 还借鉴了 DETR 的一对一匹配策略,并在此基础上进行了优化,进一步提升了小目标检测的能力。 --- ### 总结 综上所述,RT-DETRv3 的网络结构主要包括以下几个关键组件:基于 CNN 的辅助分支、自注意力扰动学习策略、共享权重解编码器分支以及混合编码器设计。这些技术创新共同推动了实时目标检测领域的发展,使其在复杂场景下的表现更加出色。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值