当前位置: 首页 > news >正文

【python】OpenCV—Image Colorization

在这里插入图片描述

文章目录

  • 1、CIELAB 色彩空间
  • 2、作色问题定义
  • 3、Caffe 模型
  • 4、代码实现——Image
  • 5、代码实现——Video
  • 6、参考

1、CIELAB 色彩空间

Lab颜色空间,也称为Lab色彩空间或CIELAB色彩空间,是一种基于人类视觉感知特性的颜色模型。它是在1931年国际照明委员会(CIE)制定的颜色度量国际标准的基础上建立的,并在1976年经过修订和完善。Lab颜色空间以其独特的优点在多个领域得到广泛应用。

Lab颜色空间是一种颜色-对立空间,它包含三个维度:L、a和b。

  • L:表示亮度(Luminosity),取值范围为0到100,对应从纯黑到纯白的亮度变化。

  • a:表示颜色对立维度之一,通常与绿色到红色的范围相对应,取值范围为-128到+127,其中负值表示绿色方向,正值表示洋红方向。

  • b:表示另一个颜色对立维度,通常与蓝色到黄色的范围相对应,取值范围同样为-128到+127,其中负值表示蓝色方向,正值表示黄色方向。

2、作色问题定义

参考文章

Zhang R, Isola P, Efros A A. Colorful image colorization[C]//Computer Vision–ECCV 2016: 14th European Conference, Amsterdam, The Netherlands, October 11-14, 2016, Proceedings, Part III 14. Springer International Publishing, 2016: 649-666.

在这里插入图片描述

在这里插入图片描述

为了简化计算,Lab 颜色空间的 ab 空间被量化为 313 个 bin,如下图所示。而不是为每个像素找到 a 和 b 值,因为这种量化,我们只需要找到一个介于 0 和 312之间的 bin 编号。另一种思考问题的方式是我们已经有了取值从 0 到 255 的 L 通道,我们需要找到取值在 0 到 312 之间的 ab 通道。所以颜色预测任务现在是变成了多分类问题,其中每个灰色像素有 313 个类别可供选择

在这里插入图片描述

3、Caffe 模型

在这里插入图片描述

colorization_release_v1

在这里插入图片描述

colorization_release_v2
在这里插入图片描述
colorization_release_v2_norebal
在这里插入图片描述

4、代码实现——Image

# This code is written by Sunita Nayak at BigVision LLC. It is based on the OpenCV project.
# It is subject to the license terms in the LICENSE file found in this distribution and at http://opencv.org/license.html#### Usage example: python3 colorize.py --input greyscaleImage.pngimport numpy as np
import cv2 as cv
import argparse
import os.pathparser = argparse.ArgumentParser(description='Colorize GreyScale Image')
parser.add_argument('--input', help='Path to image.', default="greyscaleImage.png")
args = parser.parse_args()if args.input==None:print('Please give the input greyscale image name.')print('Usage example: python3 colorizeImage.py --input greyscaleImage.png')exit()if os.path.isfile(args.input)==0:print('Input file does not exist')exit()# Read the input image
frame = cv.imread(args.input)# Specify the paths for the 2 model files
protoFile = "./models/colorization_deploy_v2.prototxt"
weightsFile = "./models/colorization_release_v2.caffemodel"
# weightsFile = "./models/colorization_release_v2_norebal.caffemodel"# Load the cluster centers
pts_in_hull = np.load('./pts_in_hull.npy')# Read the network into Memory
net = cv.dnn.readNetFromCaffe(protoFile, weightsFile)# populate cluster centers as 1x1 convolution kernel
pts_in_hull = pts_in_hull.transpose().reshape(2, 313, 1, 1)
net.getLayer(net.getLayerId('class8_ab')).blobs = [pts_in_hull.astype(np.float32)]
net.getLayer(net.getLayerId('conv8_313_rh')).blobs = [np.full([1, 313], 2.606, np.float32)]#from opencv sample
W_in = 224
H_in = 224img_rgb = (frame[:,:,[2, 1, 0]] * 1.0 / 255).astype(np.float32)
img_lab = cv.cvtColor(img_rgb, cv.COLOR_RGB2Lab)
img_l = img_lab[:,:,0] # pull out L channel# resize lightness channel to network input size
img_l_rs = cv.resize(img_l, (W_in, H_in)) #
img_l_rs -= 50 # subtract 50 for mean-centeringnet.setInput(cv.dnn.blobFromImage(img_l_rs))
ab_dec = net.forward()[0,:,:,:].transpose((1,2,0)) # this is our result(H_orig,W_orig) = img_rgb.shape[:2] # original image size
ab_dec_us = cv.resize(ab_dec, (W_orig, H_orig))
img_lab_out = np.concatenate((img_l[:,:,np.newaxis],ab_dec_us),axis=2) # concatenate with original image L
img_bgr_out = np.clip(cv.cvtColor(img_lab_out, cv.COLOR_Lab2BGR), 0, 1)outputFile = args.input[:-4]+'_colorized.png'
cv.imwrite(outputFile, (img_bgr_out*255).astype(np.uint8))
print('Colorized image saved as '+outputFile)
print('Done !!!')

cluster center

// 来自 pts_in_hull.npy 的 313 个 ab 聚类中心(已经转置)
static float hull_pts[] = {-90., -90., -90., -90., -90., -80., -80., -80., -80., -80., -80., -80., -80., -70., -70., -70., -70., -70., -70., -70., -70.,-70., -70., -60., -60., -60., -60., -60., -60., -60., -60., -60., -60., -60., -60., -50., -50., -50., -50., -50., -50., -50., -50.,-50., -50., -50., -50., -50., -50., -40., -40., -40., -40., -40., -40., -40., -40., -40., -40., -40., -40., -40., -40., -40., -30.,-30., -30., -30., -30., -30., -30., -30., -30., -30., -30., -30., -30., -30., -30., -30., -20., -20., -20., -20., -20., -20., -20.,-20., -20., -20., -20., -20., -20., -20., -20., -20., -10., -10., -10., -10., -10., -10., -10., -10., -10., -10., -10., -10., -10.,-10., -10., -10., -10., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 10., 10., 10., 10., 10., 10., 10.,10., 10., 10., 10., 10., 10., 10., 10., 10., 10., 10., 20., 20., 20., 20., 20., 20., 20., 20., 20., 20., 20., 20., 20., 20., 20.,20., 20., 20., 30., 30., 30., 30., 30., 30., 30., 30., 30., 30., 30., 30., 30., 30., 30., 30., 30., 30., 30., 40., 40., 40., 40.,40., 40., 40., 40., 40., 40., 40., 40., 40., 40., 40., 40., 40., 40., 40., 40., 50., 50., 50., 50., 50., 50., 50., 50., 50., 50.,50., 50., 50., 50., 50., 50., 50., 50., 50., 60., 60., 60., 60., 60., 60., 60., 60., 60., 60., 60., 60., 60., 60., 60., 60., 60.,60., 60., 60., 70., 70., 70., 70., 70., 70., 70., 70., 70., 70., 70., 70., 70., 70., 70., 70., 70., 70., 70., 70., 80., 80., 80.,80., 80., 80., 80., 80., 80., 80., 80., 80., 80., 80., 80., 80., 80., 80., 80., 90., 90., 90., 90., 90., 90., 90., 90., 90., 90.,90., 90., 90., 90., 90., 90., 90., 90., 90., 100., 100., 100., 100., 100., 100., 100., 100., 100., 100., 50., 60., 70., 80., 90.,20., 30., 40., 50., 60., 70., 80., 90., 0., 10., 20., 30., 40., 50., 60., 70., 80., 90., -20., -10., 0., 10., 20., 30., 40., 50.,60., 70., 80., 90., -30., -20., -10., 0., 10., 20., 30., 40., 50., 60., 70., 80., 90., 100., -40., -30., -20., -10., 0., 10., 20.,30., 40., 50., 60., 70., 80., 90., 100., -50., -40., -30., -20., -10., 0., 10., 20., 30., 40., 50., 60., 70., 80., 90., 100., -50.,-40., -30., -20., -10., 0., 10., 20., 30., 40., 50., 60., 70., 80., 90., 100., -60., -50., -40., -30., -20., -10., 0., 10., 20.,30., 40., 50., 60., 70., 80., 90., 100., -70., -60., -50., -40., -30., -20., -10., 0., 10., 20., 30., 40., 50., 60., 70., 80., 90.,100., -80., -70., -60., -50., -40., -30., -20., -10., 0., 10., 20., 30., 40., 50., 60., 70., 80., 90., -80., -70., -60., -50.,-40., -30., -20., -10., 0., 10., 20., 30., 40., 50., 60., 70., 80., 90., -90., -80., -70., -60., -50., -40., -30., -20., -10.,0., 10., 20., 30., 40., 50., 60., 70., 80., 90., -100., -90., -80., -70., -60., -50., -40., -30., -20., -10., 0., 10., 20., 30.,40., 50., 60., 70., 80., 90., -100., -90., -80., -70., -60., -50., -40., -30., -20., -10., 0., 10., 20., 30., 40., 50., 60., 70.,80., -110., -100., -90., -80., -70., -60., -50., -40., -30., -20., -10., 0., 10., 20., 30., 40., 50., 60., 70., 80., -110., -100.,-90., -80., -70., -60., -50., -40., -30., -20., -10., 0., 10., 20., 30., 40., 50., 60., 70., 80., -110., -100., -90., -80., -70.,-60., -50., -40., -30., -20., -10., 0., 10., 20., 30., 40., 50., 60., 70., -110., -100., -90., -80., -70., -60., -50., -40., -30.,-20., -10., 0., 10., 20., 30., 40., 50., 60., 70., -90., -80., -70., -60., -50., -40., -30., -20., -10., 0.
};

Class rebalancing

输入图片

在这里插入图片描述

v2 without re-balance
在这里插入图片描述
v2 with re-balance
在这里插入图片描述

输入图片

在这里插入图片描述

v2 without re-balance

在这里插入图片描述

v2 with re-balance

在这里插入图片描述

输入图片

在这里插入图片描述

v2 without re-balance

在这里插入图片描述

v2 with re-balance

在这里插入图片描述
输入图片

在这里插入图片描述

v2 without re-balance

在这里插入图片描述

v2 with re-balance

在这里插入图片描述

输入图片

在这里插入图片描述

v2 without re-balance

在这里插入图片描述

v2 with re-balance

在这里插入图片描述

输入图片

在这里插入图片描述

v2 without re-balance

在这里插入图片描述

v2 with re-balance

在这里插入图片描述

输入图片

在这里插入图片描述

v2 without re-balance

在这里插入图片描述

v2 with re-balance

在这里插入图片描述

可以观察到引入 color rebalance 后,整体画面变得更黄

5、代码实现——Video

# This code is written by Sunita Nayak at BigVision LLC. It is based on the OpenCV project.
# It is subject to the license terms in the LICENSE file found in this distribution and at http://opencv.org/license.html#### Usage example: python3 colorizeVideo.py --input greyscaleVideo.mp4import numpy as np
import cv2 as cv
import argparse
import os.pathparser = argparse.ArgumentParser(description='Colorize GreyScale Video')
parser.add_argument('--input', help='Path to video file.')
args = parser.parse_args()if args.input==None:print('Please give the input greyscale video file.')print('Usage example: python3 colorizeVideo.py --input greyscaleVideo.mp4')exit()if os.path.isfile(args.input)==0:print('Input file does not exist')exit()# Read the input video
cap = cv.VideoCapture(args.input)
hasFrame, frame = cap.read()outputFile = args.input[:-4]+'_colorized.avi'
vid_writer = cv.VideoWriter(outputFile, cv.VideoWriter_fourcc('M','J','P','G'), 60, (frame.shape[1],frame.shape[0]))# Specify the paths for the 2 model files
protoFile = "./models/colorization_deploy_v2.prototxt"
# weightsFile = "./models/colorization_release_v2.caffemodel"
weightsFile = "./models/colorization_release_v2_norebal.caffemodel"# Load the cluster centers
pts_in_hull = np.load('./pts_in_hull.npy')# Read the network into Memory
net = cv.dnn.readNetFromCaffe(protoFile, weightsFile)# populate cluster centers as 1x1 convolution kernel
pts_in_hull = pts_in_hull.transpose().reshape(2, 313, 1, 1)
net.getLayer(net.getLayerId('class8_ab')).blobs = [pts_in_hull.astype(np.float32)]
net.getLayer(net.getLayerId('conv8_313_rh')).blobs = [np.full([1, 313], 2.606, np.float32)]#from opencv sample
W_in = 224
H_in = 224while cv.waitKey(1):hasFrame, frame = cap.read()frameCopy = np.copy(frame)if not hasFrame:breakimg_rgb = (frame[:,:,[2, 1, 0]] * 1.0 / 255).astype(np.float32)img_lab = cv.cvtColor(img_rgb, cv.COLOR_RGB2Lab)img_l = img_lab[:,:,0] # pull out L channel# resize lightness channel to network input sizeimg_l_rs = cv.resize(img_l, (W_in, H_in))img_l_rs -= 50 # subtract 50 for mean-centeringnet.setInput(cv.dnn.blobFromImage(img_l_rs))ab_dec = net.forward()[0,:,:,:].transpose((1,2,0)) # this is our result(H_orig,W_orig) = img_rgb.shape[:2] # original image sizeab_dec_us = cv.resize(ab_dec, (W_orig, H_orig))img_lab_out = np.concatenate((img_l[:,:,np.newaxis],ab_dec_us),axis=2) # concatenate with original L channelimg_bgr_out = np.clip(cv.cvtColor(img_lab_out, cv.COLOR_Lab2BGR), 0, 1)vid_writer.write((img_bgr_out*255).astype(np.uint8))vid_writer.release()print('Colorized video saved as '+outputFile)
print('Done !!!')

输入视频

greyscaleVideo

结果

colorization_release_v2_noreba

Result-colorization_release_v2

可以观察到引入 color rebalance 后,整体画面变得更黄

6、参考

  • OpenCV进阶(9)基于OpenCV的图像着色

  • 图像着色领域可有什么经典论文?

相关文章:

【python】OpenCV—Image Colorization

文章目录 1、CIELAB 色彩空间2、作色问题定义3、Caffe 模型4、代码实现——Image5、代码实现——Video6、参考 1、CIELAB 色彩空间 Lab颜色空间,也称为Lab色彩空间或CIELAB色彩空间,是一种基于人类视觉感知特性的颜色模型。它是在1931年国际照明委员会&…...

vue 学习笔记

模板语法 1. 插值语法 用于解析标签体内容 { { 表达式 } } ,可以直接读取到 data 中的所有属性 2. 指令语法 解析标签(标签属性, 标签内容, 绑定事件) v-bind : href " url " 或 : href &…...

武汉流星汇聚:‘中国制造’闪耀欧洲站,体育赛事成亚马逊增长点

随着2024年的欧洲体育赛事激情四溢,欧洲杯与奥运会的双重盛会不仅点燃了全球体育迷的热情,更为亚马逊欧洲站带来了前所未有的发展机遇。在这场体育盛宴的推动下,欧洲站正展现出其无限的发展潜力和广阔的市场前景,为中国卖家乃至全…...

RPA是什么?探讨RPA发展的最新趋势 | RPA研究

随着人工智能和自动化技术的飞速发展,机器人流程自动化(Robotic Process Automation,简称RPA)正逐渐成为企业数字化转型的关键工具。RPA通过模拟人类用户的操作行为,自动化执行重复性高、规则性强的任务,从…...

sqlalchemy时间范围查询

1、sqlalchemy时间范围查询 在 SQLAlchemy 中,进行时间范围查询可以通过比较日期或时间字段来实现。假设你有一个模型 Event,它包含一个 timestamp 字段,你想查询在某个时间范围内的所有事件。以下是如何使用 SQLAlchemy 来实现这个查询的示例。 首先,确保你有 SQLAlchem…...

电脑不小心删除的文件怎么恢复?教你文件恢复的绝招

在日常使用电脑的过程中,我们有时会因为误操作或不小心而删除了重要的文件。面对这种情况,很多人可能会感到焦虑和无助。但其实,通过一些专业的方法和工具,我们有可能恢复这些被误删的文件。本文将介绍两种常见的恢复方法&#xf…...

stm32:使用和学习--硬件和程序

一硬件 1. GPIO 1.FT, TT功能 ft:five tolerate tt:three tolerate 1. FT(Five-Volt Tolerant)引脚 FT 引脚能够容忍高于 VDD 的输入电压(例如 5V)。这些引脚通常不具有连接到 VDD 的保护二极管&…...

ARM知识点二

一、指令 指令的生成过程 指令执行过程示例 if (a 0) {x 0; } else {x x 3; } //翻译为 cmp r0,#0 MOVEQ R1,#0 ADDGT R1,R1,#3指令获取:从Flash中读取 CMP R0, #0,控制器开始执行。 指令解码:解码器解析 CMP 指令,ALU比较R…...

C# ?的使用

栏目总目录 可空类型标记符(?) 说明: 可空类型标记符?用于指示某个值类型(如int、float等)可以为null。这是C# 2.0引入的一个特性,用于处理数据库查询、JSON解析等场景中可能出现的空值。 示例代码&am…...

【unity小技巧】unity性能优化以及如何进行性能测试

文章目录 前言GPU性能优化打包素材 CPU性能优化代码执行优化 性能测试Vector2.Distance 和 sqrMagnitude哪个好?动画切换优化shader属性优化 URP渲染器资产优化对象池优化删除没必要的空函数图片、音乐音效、贴图等素材压缩ScriptableObject优化参数参考完结 前言 …...

算法参考改进点/知识点

1、clip文章中改进点 图像编码器image encoder: 将全局平均池化层替换为注意力池化机制。注意力池化机制:通过一个单层的“transformer式”多头QKV注意力,其中查询query是基于图像的全局平均池表示。改进VIT(Vision Transformer…...

electron 配置、打包 -报错解决

目录 一、配置途中遇到的问题: 二、 make 配置好后开始打包 三、Electron-builder 打包报错 一、配置途中遇到的问题: 1. 安装 yarn add electron -D 一直卡在这里失败 一直卡可以使用下面这个,然后再重新装依赖 1. 采用新的镜像地址 npm …...

基于STM32设计的智能鱼缸(华为云IOT)(200)

文章目录 一、前言1.1 项目介绍【1】项目功能介绍【2】设计实现的功能【3】项目硬件模块组成1.2 设计思路【1】整体设计思路【2】ESP8266工作模式配置【3】自动换水原理1.3 项目开发背景【1】选题的意义【2】可行性分析【3】参考文献1.4 开发工具的选择【1】设备端开发【2】上位…...

Django与数据库

目录 创建项目app 路由子表 数据库 创建数据库 什么是ORM 定义数据库表 Django Admin 管理数据 过滤条件 代码直接生成HTML 使用模板 前后端分离架构 对资源的增删改查处理 列出客户 添加客户 临时取消 CSRF 校验 修改客户信息 删除客户 Django中ORM的处理 数据模…...

大数据系列之:CentOS7安装R详细步骤

大数据系列之:CentOS7安装R详细步骤 一、下载R二、解压R三、创建安装目录四、指定安装目录五、安装编译依赖六、编译与编译安装七、设置环境变量八、激活环境变量九、执行R命令十、执行demo测试程序 一、下载R wget https://cran.r-project.org/src/base/R-4/R-4.4…...

Linux学习第57天:Linux PWM驱动实验

Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长 本章的思维导图如下: 一、PWM驱动简析 1、设备树下的PWM控制节点 8 路 PWM 都属于 I.MX6ULL 的 AIPS-1 域,分为了两部分, PWM1~P…...

git 远程拉取指定文件

指定操作 git init 创建一个空的文件 git remote add orgin 远程仓库地址链接 表示添加远程库的地址 git config core.sparsecheckout true 打开sparsecheckout功能 注意:如果需要分支内所有文件,这个指令可以直接过忽略,则会拉取对应分支所有的文件…...

【css】 CSS3+JS做一个酷炫的仪表进度条3d进度条

创建一个动态进度环组件 在现代网页设计中,进度环是一种常见的视觉元素,用于展示任务的完成度或加载状态。本文将介绍如何使用Vue.js和Less创建一个动态进度环组件,该组件不仅具有美观的视觉效果,还能够根据用户输入动态改变颜色…...

uniapp小程序全局配置分享到朋友和朋友圈功能的实现

文章目录 1.创建/mixins/share.js插件2.全局配置3.编写share.js4.调用5.分享成功 1.创建/mixins/share.js插件 直接创建 2.全局配置 (1)找到main.js在下面引入share.js文件 (2)使用mixins混入vue中,这样就相当于在每一…...

Java优化后台分页

第一种情况&#xff1a;先查询出所有记录&#xff0c;再进行分页处理&#xff08;分页中可以异步处理&#xff09; 优化前&#xff1a; List<String> list Arrays.asList("1","2","3","4","5","6","…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

在Ubuntu中设置开机自动运行(sudo)指令的指南

在Ubuntu系统中&#xff0c;有时需要在系统启动时自动执行某些命令&#xff0c;特别是需要 sudo权限的指令。为了实现这一功能&#xff0c;可以使用多种方法&#xff0c;包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法&#xff0c;并提供…...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生&#xff0c;小白用户&#xff0c;想学习知识的 有点基础&#xff0c;想要通过项…...

MyBatis中关于缓存的理解

MyBatis缓存 MyBatis系统当中默认定义两级缓存&#xff1a;一级缓存、二级缓存 默认情况下&#xff0c;只有一级缓存开启&#xff08;sqlSession级别的缓存&#xff09;二级缓存需要手动开启配置&#xff0c;需要局域namespace级别的缓存 一级缓存&#xff08;本地缓存&#…...

【Post-process】【VBA】ETABS VBA FrameObj.GetNameList and write to EXCEL

ETABS API实战:导出框架元素数据到Excel 在结构工程师的日常工作中,经常需要从ETABS模型中提取框架元素信息进行后续分析。手动复制粘贴不仅耗时,还容易出错。今天我们来用简单的VBA代码实现自动化导出。 🎯 我们要实现什么? 一键点击,就能将ETABS中所有框架元素的基…...