【OpenCV入门】第九部分——模板匹配
文章结构
- 模板匹配方法
- 单模板匹配
- 单目标匹配
- 多目标匹配
- 多模板匹配
模板匹配方法
模板是被查找的图像。模板匹配是指查找模板在原始图像中的哪个位置的过程。
result = cv2.matchTemplate(image, templ, method, mask)
- image: 原始图像
- templ: 模板图像,尺寸必须小于或等于原始图像
- method: 匹配的方法
- mask:(可选)掩模,只有 cv2.TM_SQDIFF和 c2.TM_CCORR_NORMED 支持此参数,建议采用默认值
- result: 计算得出的匹配结果。如果原始图像的宽、高分别为 W、H,模板图像的宽、高分别为 w、h,result 就是一个 W-w+1列、H-h+1行的32位浮点型数组。数组中每个浮点数都是原始图像中对应像素位置的匹配结果,其含义需要根据 method 参数来解读
在模板匹配的计算过程中,模板会在原始图像中移动。模板会与重叠区域内的像素逐个对比,最后将对比的结果保存在模板左上角像素点索引位置对应的数组位置中。
使用 cv2.TM_SQDIFF(平方差匹配)方法计算出的数组格式如下所示(其他方法计出的数组格式相同,仅数值不同):
模板会将原始图像中每一块区域都覆盖一遍,但结果数组的行列数并不会等于原始图像的像素的行列数。假设模板的宽为 w、高为h,原始图像的宽为 W、高为H,
模板移动到原始图像的边缘之后就不会继续移动了,所以模板的移动区域如下图所示,该区域的边长为“原始图像边长 - 模板边长 +1”,最后加 1 是因为移动区域内的上下、左右的两个边都被模板覆盖到了,如果不加1会丢失数据。
单模板匹配
匹配过程中只用到一个模板的场景叫单模板匹配。原始图像中可能只有一个和模板相以的图像,也有可能有多个。如果只获取匹配程度最高的那一个结果,这种操作叫单目标配;如果需要同时获取所有匹配程度较高的结果,这种操作叫多目标匹配。
单目标匹配
单目标匹配只获取一个结果即可,就是匹配程度最高的结果 (如果使用平方差匹配,则为计算出的最小结果;如果使用相关匹配或相关系数匹配,则为计算出的最大结果)。本节以平方差匹配为例做介绍。
matchTemplate()
方法的计算结果是一个二维数组,minMaxLoc()方法专门用来解析这个二维数组中的最大值、最小值以及这两个值对应的坐标:
minValue, maxValue, minLoc, maxLoc = cv2.minMaxLoc(src, mask)
- src: matchTemplate() 方法计算得出的数组
- mask:(可选)掩模,建议使用默认值。
- minValue: 数组中的最小值
- maxValue: 数组中的最大值。
- minLoc: 最小值的坐标,格式为(x,y)。
- maxLoc: 最大值的坐标,格式为(x,y)。
平方差匹配的计算结果越小,匹配程度越高。minMaxLoc() 方法返回的 minValue 值是模板匹配的最优结果,minLoc 是最优结果区域左上角的点坐标,区域大小与模板大小一致。
实例1: 为原始图片中匹配成功的区域绘制红框
import cv2img = cv2.imread("background.jpg") # 读取原始图像
templ = cv2.imread("template.png") # 读取模板图像
height, width, c = templ.shape # 获取模板图像的高度、宽度和通道数
results = cv2.matchTemplate(img, templ, cv2.TM_SQDIFF_NORMED) # 按照标准平方差方式匹配
# 获取匹配结果中的最小值、最大值、最小值坐标和最大值坐标
minValue, maxValue, minLoc, maxLoc = cv2.minMaxLoc(results)
resultPoint1 = minLoc # 将最小值坐标当作最佳匹配区域的左上角点坐标
# 计算出最佳匹配区域的右下角点坐标
resultPoint2 = (resultPoint1[0] + width, resultPoint1[1] + height)
# 在最佳匹配区域位置绘制红色方框,线宽为2像素
cv2.rectangle(img, resultPoint1, resultPoint2, (0, 0, 255), 2)
cv2.imshow("img", img) # 显示匹配的结果
cv2.waitKey() # 按下任何键盘按键后
cv2.destroyAllWindows() # 释放所有窗体
结果如下:
实例2: 从两幅图像中选择最佳的匹配结果
import cv2image = [] # 存储原始图像的列表
# 向image列表添加原始图像image_221.png
image.append(cv2.imread("image_221.png"))
# 向image列表添加原始图像image_222.png
image.append(cv2.imread("image_222.png"))
templ = cv2.imread("templ.png") # 读取模板图像
index = -1 # 初始化车位编号列表的索引为-1
min = 1
for i in range(0, len(image)): # 循环匹配image列表中的原始图像# 按照标准平方差方式匹配results = cv2.matchTemplate(image[i], templ, cv2.TM_SQDIFF_NORMED)# 获得最佳匹配结果的索引if min > any(results[0]):index = i
cv2.imshow("result", image[index]) # 显示最佳匹配结果
cv2.waitKey() # 按下任何键盘按键后
cv2.destroyAllWindows() # 释放所有窗体
结果如下:
实例3: 查找重复的图像
现在有十张图像,这些图像格式不同,而且分辨率也各不相同。想要找到重复的图像,可以使用matchTemplate()来判断两幅图像的相似度,如果相似度大于0.9,就认为这两幅图像是相同的。
import cv2
import os
import sysPIC_PATH = "C:\\Users\\Administrator\\Desktop\\test\\" # 照片文件夹地址
width, height = 100, 100 # 缩放比例pic_file = os.listdir(PIC_PATH) # 所有照片文件列表
same_pic_index = [] # 相同图像的索引列表
imgs = [] # 缩放后的图像对象列表
has_same = set() # 相同图像的集合
count = len(pic_file) # 照片数量if count == 0: # 如果照片数量为零print("没有图像")sys.exit(0) # 停止程序for file_name in pic_file: # 遍历照片文件pic_name = PIC_PATH + file_name # 拼接完整文件名img = cv2.imread(pic_name) # 创建文件的图像img = cv2.resize(img, (width, height)) # 缩放成统一大小imgs.append(img) # 按文件顺序保存图像对象for i in range(0, count - 1): # 遍历所有图像文件,不遍历最后一个图像if i in has_same: # 如果此图像已经找到相同的图像continue # 跳过templ = imgs[i] # 取出模板图像same = [i] # 与templ内容相同的图像索引列表for j in range(0 + i + 1, count): # 从templ的下一个位置开始遍历if j in has_same: # 如果此图像已经找到相同的图像continue # 跳过pic = imgs[j] # 取出对照图像results = cv2.matchTemplate(pic, templ, cv2.TM_CCOEFF_NORMED) # 比较两图像相速度if results > 0.9: # 如果相似度大于90%,认为是同一张照片same.append(j) # 记录对照图像的索引has_same.add(i) # 模板图像已找到相同图像has_same.add(j) # 对照图像已找到相同图像if len(same) > 1: # 如果模板图像找到了至少一张与自己相同的图像same_pic_index.append(same) # 记录相同图像的索引for same_list in same_pic_index: # 遍历所有相同图像的索引text = "相同的照片:"for same in same_list:text += str(pic_file[same]) + ", " # 拼接文件名print(text)
结果如下:
多目标匹配
多目标匹配需要将原始图像中所有与模板相似的图像都找出来,使用相关匹配或相关系数匹配可以很好地实现这个功能。如果计算结果大于某一值,则认为匹配区域的图案和模板是相同的。
实例4: 为原始图片中所有匹配成功的图案绘制红框
使用cv2.TM_CCOEFF_NORMED方式进行模板匹配,使用for循环遍历matchTemplate()方法返回的结果,找到所有大于0.99的计算结果,在这些结果的对应区域位置绘制红色矩形边框。
import cv2
img = cv2.imread("background2.jpg") # 读取原始图像
templ = cv2.imread("template.png") # 读取模板图像
width, height, c = templ.shape # 获取模板图像的宽度、高度和通道数
results = cv2.matchTemplate(img, templ, cv2.TM_CCOEFF_NORMED) # 按照标准相关系数匹配
for y in range(len(results)): # 遍历结果数组的行for x in range(len(results[y])): # 遍历结果数组的列if results[y][x] > 0.99: # 如果相关系数大于0.99则认为匹配成功# 在最佳匹配结果位置绘制红色方框cv2.rectangle(img, (x, y), (x + width, y + height), (0, 0, 255), 2)
cv2.imshow("img", img) # 显示匹配的结果
cv2.waitKey() # 按下任何键盘按键后
cv2.destroyAllWindows() # 释放所有窗体
结果如下:
实例5: 统计一条快轨线路的站台总数
import cv2image = cv2.imread("image.png") # 读取原始图像
templ = cv2.imread("templ.png") # 读取模板图像
height, width, c = templ.shape # 获取模板图像的高度、宽度和通道数
results = cv2.matchTemplate(image, templ, cv2.TM_CCOEFF_NORMED) # 按照标准相关系数匹配
station_Num = 0 # 初始化快轨的站台个数为0
for y in range(len(results)): # 遍历结果数组的行for x in range(len(results[y])): # 遍历结果数组的列if results[y][x] > 0.99: # 如果相关系数大于0.99则认为匹配成功# 在最佳匹配结果位置绘制蓝色矩形边框cv2.rectangle(image, (x, y), (x + width, y + height), (255, 0, 0), 2)station_Num += 1 # 快轨的站台个数加1
cv2.putText(image, "the numbers of stations: " + str(station_Num), (0, 30),cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 0, 255), 1) # 在原始图像绘制快轨站台的总数
cv2.imshow("result", image) # 显示匹配的结果
cv2.waitKey() # 按下任何键盘按键后
cv2.destroyAllWindows() # 释放所有窗体
结果如下:
实例6: 优先选择直线距离最短的地铁站
import cv2
import numpy as np
import mathimage = cv2.imread("image.png") # 读取原始图像
templ = cv2.imread("templ.png") # 读取模板图像
height, width, c = templ.shape # 获取模板图像的高度、宽度和通道数
results = cv2.matchTemplate(image, templ, cv2.TM_CCOEFF_NORMED) # 按照标准相关系数匹配
point_X = [] # 用于存储最佳匹配结果左上角横坐标的列表
point_Y = [] # 用于存储最佳匹配结果左上角纵坐标的列表
for y in range(len(results)): # 遍历结果数组的行for x in range(len(results[y])): # 遍历结果数组的列if results[y][x] > 0.99: # 如果相关系数大于0.99则认为匹配成功# 在最佳匹配结果位置绘制红色方框cv2.rectangle(image, (x, y), (x + width, y + height), (255, 0, 0), 2)point_X.extend([x]) # 把最佳匹配结果左上角的横坐标添加到列表中point_Y.extend([y]) # 把最佳匹配结果左上角的纵坐标添加到列表中
# 出发点的横、纵坐标
start_X = 62
start_Y = 150
# 计算出发点到人民广场地铁站的距离
place_Square = np.array([point_X[0], point_Y[0]])
place_Start = np.array([start_X, start_Y])
minus_SS = place_Start - place_Square
start_Square = math.hypot(minus_SS[0], minus_SS[1])
# 计算出发点到解放大路地铁站的距离
place_Highroad = np.array([point_X[1], point_Y[1]])
minus_HS = place_Highroad - place_Start
start_Highroad = math.hypot(minus_HS[0], minus_HS[1])
# 用绿色的线画出距离较短的路线
if start_Square < start_Highroad:cv2.line(image, (start_X, start_Y), (point_X[0], point_Y[0]), (0, 255, 0), 2)
else:cv2.line(image, (start_X, start_Y), (point_X[1], point_Y[1]), (0, 255, 0), 2)
cv2.imshow("result", image) # 显示匹配的结果
cv2.waitKey() # 按下任何键盘按键后
cv2.destroyAllWindows() # 释放所有窗体
结果如下:
多模板匹配
匹配过程中同时查找多个模板的操作叫多模板匹配。多模板匹配实际上就是进行了n次“单模板多模板匹配”操作,n的数量为模板总数。
实例7: 同时匹配3个不同的模板
每一个模板都要做一次“单模板多目标匹配”,最后把所有模板的匹配结果汇总到一起。“单模板多模板匹配”的过程可以封装成一个方法,方法参数为模板和原始图像,方法内部将计算结果再加工一下,直接返回所有红框左上角和右下角两点横纵坐标的列表。在方法之外,将所有模板计算得出的坐标汇总到一个列表中,按照这些汇总的坐标一次性将所有红框都绘制出来。
import cv2def myMatchTemplate(img, templ): # 自定义方法:获取模板匹配成功后所有红框位置的坐标width, height, c = templ.shape # 获取模板图像的宽度、高度和通道数results = cv2.matchTemplate(img, templ, cv2.TM_CCOEFF_NORMED) # 按照标准相关系数匹配loc = list() # 红框的坐标列表for i in range(len(results)): # 遍历结果数组的行for j in range(len(results[i])): # 遍历结果数组的列if results[i][j] > 0.99: # 如果相关系数大于0.99则认为匹配成功# 在列表中添加匹配成功的红框对角线两点坐标loc.append((j, i, j + width, i + height))return locimg = cv2.imread("background2.jpg") # 读取原始图像
templs = list() # 模板列表
templs.append(cv2.imread("template.png")) # 添加模板1
templs.append(cv2.imread("template2.png")) # 添加模板2
templs.append(cv2.imread("template3.png")) # 添加模板3loc = list() # 所有模板匹配成功位置的红框坐标列表
for t in templs: # 遍历所有模板loc += myMatchTemplate(img, t) # 记录该模板匹配得出的for i in loc: # 遍历所有红框的坐标cv2.rectangle(img, (i[0], i[1]), (i[2], i[3]), (0, 0, 255), 2) # 在图片中绘制红框cv2.imshow("img", img) # 显示匹配的结果
cv2.waitKey() # 按下任何键盘按键后
cv2.destroyAllWindows() # 释放所有窗体
结果如下:
实例8: 控制台输出4辆车分别停在了哪个车位上
import cv2image = cv2.imread("image.png") # 读取原始图像
templs = [] # 模板列表
templs.append(cv2.imread("car1.png")) # 添加模板图像1
templs.append(cv2.imread("car2.png")) # 添加模板图像2
templs.append(cv2.imread("car3.png")) # 添加模板图像3
templs.append(cv2.imread("car4.png")) # 添加模板图像3
for car in templs: # 遍历所有模板图像# 按照标准相关系数匹配results = cv2.matchTemplate(image, car, cv2.TM_CCOEFF_NORMED)for i in range(len(results)): # 遍历结果数组的行for j in range(len(results[i])): # 遍历结果数组的列# print(results[i][j])if results[i][j] > 0.99: # 如果相关系数大于0.99则认为匹配成功if 0 < j <= 140:print("车位编号:", 1)elif j <= 330:print("车位编号:", 2)elif j <= 500:print("车位编号:", 3)else:print("车位编号:", 4)break
1号车位水平像素的取值范围是0 ~ 140,2号车位水平像素的取值范围是 141 ~ 330,3号车位水平像素的取值范围是331 ~ 500,4号车位水平像素的取值范围是 501 ~ 650。
结果如下:
相关文章:

【OpenCV入门】第九部分——模板匹配
文章结构 模板匹配方法单模板匹配单目标匹配多目标匹配 多模板匹配 模板匹配方法 模板是被查找的图像。模板匹配是指查找模板在原始图像中的哪个位置的过程。 result cv2.matchTemplate(image, templ, method, mask)image: 原始图像templ: 模板图像&a…...
在设计web页面时,为移动端设计一套页面,PC端设计一套页面,并且能自动根据设备类型来选择是用移动端的页面还是PC端的页面。
响应式设计,即移动端和PC端共用一个HTML模式,网站的程序和模板自动根据设备类型和屏幕大小进行自适应调整。这种方法我不喜欢,原因是不能很好保证各种客户端的效果,里面存在各种复杂的兼容性等问题。 我喜欢为不同的客户端写不同的…...

微信小程序地图应用总结版
1.应用场景:展示公司位置,并打开第三方app(高德,腾讯)导航到目标位置。 (1)展示位置地图 uniapp官网提供了相关组件,uniapp-map组件https://uniapp.dcloud.net.cn/component/map.ht…...

分支创建查看切换
1、初始化git目录,创建文件并将其推送到本地库 git init echo "123" > hello.txt git add hello.txt git commit -m "first commit" hello.txt$ git init Initialized empty Git repository in D:/Git/git-demo/.git/ AdministratorDESKT…...

参编三大金融国标,奇富科技以技术促行业规范化演进
近期,由中国互联网金融协会领导制定的《互联网金融智能风险防控技术要求》《互联网金融个人网络消费信贷信息披露》《互联网金融个人身份识别技术要求》三项国家标准颁布,由国家市场监督管理总局、国家标准化管理委员会发布,奇富科技作为核心…...

芯片开发之难如何破解?龙智诚邀您前往DR IP-SoC China 2023 Day
2023年9月6日(周三),龙智即将亮相D&R IP-SoC China 2023 Day,呈现集成了Perforce与Atlassian产品的芯片开发解决方案,助力企业更好、更快地进行芯片开发。 龙智资深顾问、技术支持部门负责人李培将带来主题演讲—…...

Gof23设计模式之策略模式
1.概述 该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,…...

SAP 物料主数据屏幕增强
增强步骤 1.为主表添加一个附加结构 根据业务需求新建一个结构,结构中放入需要增强的屏幕字段并激活。 打开事务代码SE11,在需要保存的主表中添加这个附加结构并激活。 注:根据业务需求及屏幕增强的视图判断需要保存的主表是哪张ÿ…...
数据库-索引
介绍: 索引是帮助数据库高效获取数据的数据结构 优缺点: 优点:提高数据查询的效率,降低数据库的IO成本 通过索引列对数据进行排序,降低数据排序的成本,降低cpu消耗 缺点:索引会占用存储空间 索…...

Excel·VBA二维数组组合函数的应用实例
看到一个问题《关于#穷举#的问题,如何解决?(语言-开发语言)》,对同一个数据存在“是/否”2种状态,判断其是否参与计算,并输出一系列数据的“是/否”状态的结果 目录 方法1:二维数组组合函数结果 方法2&am…...
hive anti join 的几种写法
t_a 表的记录如下 c1 | :———— | a | b | c | 生成 SQL 如下: create table t_a(c1 string); insert into t_a values("a"),("b"),("c");t_b 表的记录如下 c1bm 生成 SQL 如下: create table t_b(c1 string); in…...

使用Android原生制作毛玻璃效果图片
毛玻璃效果,也被称为模糊效果,是许多现代应用中流行的一种视觉效果。在 Android 中,我们可以通过多种方式实现该效果。本文将探讨如何使用 Android 原生的 Bitmap 类和 RenderScript 来实现毛玻璃效果。 1. 准备工作 首先,你需要…...
软件设计的七大原则
一. 软件设计的七大原则 单一职责原则:一个类只负责一个功能领域中的饿相应职责。开闭原则:对扩展开放,对修改关闭,多使用抽象类和接口,应该尽量使这个系统能够扩展新的功能,通过扩展来实现变化࿰…...

Windows下安装配置Nginx
nginx安装 官网下载地址 https://nginx.org/en/download.html 推荐使用稳定版本 截止时间2023年9月5日稳定版本为 1.24.0 百度网盘 链接:https://pan.baidu.com/s/1cXm-jN2fMzKdVMRhbG72Fg 提取码:9hcq 下载完成以后,得到nginx压缩包; 双击启动nginx.…...
数据结构类型
1.在C和C中static关键字的用法 在C中 1.static修饰未初始化全局变量,默认结果为0 2.static修饰局部变量,延长生命周期,生命周期不是作用域,它依旧是局部变量 3.static修饰函数只能在当前文件中调用,不可用跨文件调用…...
WPF元素绑定
简单的说,数据绑定是一种关系,该关系告诉WPF从源对象提取一些信息,并用这些信息设置目标对象的属性。目标属性始终是依赖属性,通常位于WPF元素中——毕竟,WPF数据绑定的最终目标是在用户界面中显示一些信息。然而&…...

centos编译升级cmake,痛苦的Linux小白
环境 root 用户 下载 cmake官网下载地址:https://cmake.org/download/ 获取下载地址,右击cmake-3.27.4.tar.gz 命令行输入链接地址,下载 wget https://github.com/Kitware/CMake/releases/download/v3.27.4/cmake-3.27.4.tar.gz解压 tar -zx…...

Unity资源无法下载 反复提示需同意Terms of Service和EULA 同意后无效的解决方案
前言 最近在玩Unity,跟着tutorial做点项目,但是在下载免费资源时,只有从网站上点“打开Unity”,才能在本地Unity Editor的Package Manager里找到这个资源(且点一下下面的刷新就没有了),并且点击…...

记录--vue 拉伸指令
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 前言 在我们项目开发中,经常会有布局拉伸的需求,接下来 让我们一步步用 vue指令 实现这个需求 动手开发 在线体验 codesandbox.io/s/dawn-cdn-… 常规使用 解决拉伸触发时机 既然我们使用了指令的方式…...
前端缓存方法有哪些?cookie有哪些属性?
这里写目录标题 前端缓存方法有哪些:cookie有哪些属性? 前端缓存方法有哪些: Browser Cache(浏览器缓存): 当浏览器请求一个资源(例如图片、CSS、JS 文件)时,它会首先检查自己的缓存…...

国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...

初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...

C# winform教程(二)----checkbox
一、作用 提供一个用户选择或者不选的状态,这是一个可以多选的控件。 二、属性 其实功能大差不差,除了特殊的几个外,与button基本相同,所有说几个独有的 checkbox属性 名称内容含义appearance控件外观可以变成按钮形状checkali…...

ArcGIS Pro+ArcGIS给你的地图加上北回归线!
今天来看ArcGIS Pro和ArcGIS中如何给制作的中国地图或者其他大范围地图加上北回归线。 我们将在ArcGIS Pro和ArcGIS中一同介绍。 1 ArcGIS Pro中设置北回归线 1、在ArcGIS Pro中初步设置好经纬格网等,设置经线、纬线都以10间隔显示。 2、需要插入背会归线…...