根据文字匹配返回对应行的坐标所在值

文章介绍了Excel中的INDEX和MATCH函数,这两个函数常用于查找和返回矩阵中的特定值。INDEX函数根据给定的行和列坐标返回指定范围内的值,而MATCH函数则返回比对值在特定区域内的位置。举例说明了如何结合使用这两个函数来查找特定行的数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

公式

INDEX:根据坐标返回对应值,注意:坐标是以选择的区域的相对坐标

        index(范围,很坐标,纵坐标)

        index(A1:C10,2,7):在A1到C10的范围内,找到横坐标=2,纵坐标(列)=7的值

MATCH:比对值,返回选择区域的横坐标,注意是所在域的横坐标

        match(范围,比对的值,比对的列范围)

        match(B2,A1:A30,0):返回B2在A1~A30里的位置,值为1~30,如果没有则返回0

        第三个参数的说明

                1表示会查找小于或等于“lookup_value”的最大值;

                0表示会查找等于“lookup_value”的第一个值;

                -1表示会查找大于或等于“lookup_value”的最小值;

例子

需求

        如果我当前行“级别加权”页签范围获取数据,列为3,行为当前页签R10在页签“级别加权”中D10到D54范围内的行数。返回改值。

实现

=INDEX(级别加权!$A$10:$D$45,MATCH(R10,级别加权!$D$10:$D$45,0),3)

注意,因为INDEX和MATCH的坐标都是以所选择范围内的,所以他们的选择范围开始行一般都在同一行。

帮我分析这几个方法,修改不合理的部分,并注释修改,将主要逻辑流程说明就好,多余的文字去除,方法如下: def checkImage(self, src_path, similar=0.95, loc=5, debug=False): """ 检测当前屏幕是否存在目标图片(基于图像匹配) :param src_path: 目标图片路径(相对或绝对路径) :param similar: 相似度阈(0-1之间,默认0.95) :param loc: 匹配位置参数(具体含义依赖ImgUtils.quick_find实现) :param debug: 是否开启调试模式(默认False) :return: 布尔(True:找到目标图片;False:未找到) """ # 步骤1:获取当前屏幕截图路径 screenshot_dir = os.path.join(os.getcwd(), "resource/superapp") os.makedirs(screenshot_dir, exist_ok=True) current_screenshot_path = os.path.join(screenshot_dir, "test.png") # 步骤2:校验目标图片是否存在 resource_root = os.path.join(os.getcwd(), "resource", "superapp") target_image_path = os.path.join(resource_root, src_path) if not os.path.isfile(target_image_path): print(f"{src_path}不存在!!!") # 步骤3:校验截图文件是否有效 if not os.path.exists(current_screenshot_path) or not os.path.isfile(current_screenshot_path): print(f"{current_screenshot_path}无效!!!") # 步骤4:校验相似度阈有效性 if not 0 <= similar <= 1: raise ValueError(f"相似度阈必须在0到1之间,当前:{similar}") try: # 步骤5:调用图片匹配算法(返回匹配坐标匹配得分) match_position, match_score = self.quick_find( current_screenshot_path, target_image_path, similar=similar, loc="all", debug=debug ) print(f"匹配结果-坐标:{match_position},得分:{match_score}") # 步骤6:判定是否匹配成功(坐标和得分均不为None) is_matched = (match_position is not None) and (match_score is not None) print(f"匹配结果:{is_matched}") return is_matched except Exception as e: print(f"图片匹配异常:{str(e)}") return False def quick_find(self,fp1: str, fp2: str,similar: float = 1,density: float = None,rect: tuple = None,loc: str = "all", debug: bool = False) -> any: """在背景图像中搜索目标图像的位置(核心功能:图像匹配)""" # -------------------- 调试模式初始化(可选计时) -------------------- if debug: # from time import time # 示例计时工具(可替换为自定义TS) # start_time = time() # 记录开始时间 print(f"此处废弃调试计时") # -------------------- 步骤1:加载背景图和目标图 -------------------- background_img = Image.open(fp1) # 加载背景图(待搜索的大图) target_img = Image.open(fp2) # 加载目标图(需要查找的小图) # -------------------- 步骤2:确定搜索区域 -------------------- bg_width, bg_height = background_img.size # 获取背景图尺寸(宽度, 高度) # 若未手动指定搜索区域rect,则根据loc自动计算默认区域(调用get_rect) if rect is None: rect = self.get_rect( width=bg_width, height=bg_height, loc=loc) # -------------------- 步骤3:预处理图像为数组 -------------------- # 注:img2arr可能是将PIL图像转为numpy数组的工具函数(需自定义实现) if rect: cropped_bg = background_img.crop(rect) else: cropped_bg = background_img background_arr = self.img2arr(cropped_bg) # 背景图数组 target_arr = self.img2arr(target_img) # 目标图数组 # -------------------- 调试模式:输出预处理耗时 -------------------- if debug: print(f"此处废弃调试计时") # -------------------- 步骤4:执图像匹配 -------------------- # 调用核心匹配函数(假设find_arr是自定义匹配函数,需自实现) return self.find_arr( im1=background_arr, im2=target_arr, similar=1, density=density, rect=rect, debug=False ) def get_rect(self,width: int, height: int, loc: str = "all", region_ratio: float = 0.5) -> tuple: """ 根据位置字符串计算背景图的搜索区域矩形坐标(适配quick_find的loc参数) """ center_x, center_y = width // 2, height // 2 half_w = int(width * region_ratio / 2) half_h = int(height * region_ratio / 2) if loc == "all": return (0, 0, width, height) elif loc == "top_left": return (0, 0, width // 2, height // 2) elif loc == "top_right": return (width // 2, 0, width, height // 2) elif loc == "bottom_left": return (0, height // 2, width // 2, height) elif loc == "bottom_right": return (width // 2, height // 2, width, height) elif loc == "center": return ( center_x - half_w, center_y - half_h, center_x + half_w, center_y + half_h ) else: raise ValueError( f"无效的loc参数:{loc}。\n" f"可选:'all'(全图)、'top_left'(左上)、'top_right'(右上)、'bottom_left'(左下)、'bottom_right'(右下)、'center'(中心)" ) def img2arr(slef,img, rect=None, convert=True): """ 将图像转换为像素的二维数组 参数: img: PIL.Image 对象,输入图像 rect: 元组 (x_start, y_start, x_end, y_end),可选,指定要提取的矩形区域坐标 convert: 布尔,是否将图像转换为灰度模式(默认True) 返回: 二维列表,每个元素是对应坐标的像素(0-255) """ # 转换为灰度图(如果需要) if convert and img.mode != 'L': img = img.convert('L') # 'L' 表示8位灰度模式 # 获取图像尺寸(宽、高) width, height = img.size # 加载像素访问对象(用于获取具体坐标的像素) pixels = img.load() # 情况1:需要提取指定矩形区域的像素 if rect: x_start, y_start, x_end, y_end = rect # 解包矩形区域坐标 # 遍历y轴范围(高度方向),再遍历x轴范围(宽度方向) return [ [ pixels[x, y] # 获取坐标(x, y)的像素 for x in range(width) # 遍历图像宽度方向所有x坐标 if x_start <= x <= x_end # 仅保留x在指定区域内的像素 ] for y in range(height) # 遍历图像高度方向所有y坐标 if y_start <= y <= y_end # 仅保留y在指定区域内的像素 ] # 情况2:无矩形区域,返回全图像素数组 return [ [ pixels[x, y] # 获取坐标(x, y)的像素 for x in range(width) # 遍历宽度方向所有x坐标 ] for y in range(height) # 遍历高度方向所有y坐标 ] def find_arr(self,im1, im2, similar=1, density=None, rect=None, debug=False): """ 在主图像数组中查找模板图像的位置(基于像素匹配的定位算法) 参数: im1: 二维列表,主图像的像素数组(×列结构) im2: 二维列表,待查找的模板图像的像素数组(×列结构) similar: 相似度阈(0-1之间),越大要求匹配越严格(默认1) density: 元组(density_x, density_y),采样密度参数(控制匹配时的采样点数) rect: 元组(x_start, y_start, x_end, y_end),可选,限制搜索区域的矩形框 debug: 布尔,是否开启调试模式(打印耗时等信息,默认False) 返回: (相似度, 位置元组) 或 (None, None) 位置元组格式: (x1, y1, x2, y2) 表示模板在主图中的左上和右下坐标 """ # 调试模式:记录开始时间 if debug: print(f"此处废弃调试计时") # -------------------- 初始化基础参数 -------------------- template_width = len(im2[0]) # 模板图像的宽度(列数) template_height = len(im2) # 模板图像的高度(数) # 主图像中模板可滑动的最大横向/纵向位置数(避免越界) max_x = len(im1[0]) - template_width + 1 # 横向最大起始x坐标范围 max_y = len(im1) - template_height + 1 # 纵向最大起始y坐标范围 # -------------------- 处理采样密度 -------------------- # 采样密度:控制匹配时的采样点数(密度越大,采样点越少,计算越快) if not density: # 未指定密度时,通过工具类获取默认采样密度(假设返回横向/纵向的位移位数) density_x, density_y = self.get_density(template_width, template_height) else: density_x, density_y = density # 使用用户指定的密度参数 # 计算采样步长(通过右移操作实现降采样) step_y = template_height >> density_y # 纵向采样步长(数方向) step_x = template_width >> density_x # 横向采样步长(列数方向) total_samples = step_y * step_x # 总采样点数(用于计算相似度) max_fail = (1 - similar) * total_samples # 最大允许不匹配点数(超过则判定不匹配) # 调试模式:打印采样参数 if debug: print(f"denXX: {step_x}; denYY: {step_y}; total: {total_samples}") print(f"maxFailNum {max_fail}") # -------------------- 搜索超时控制(5分钟) -------------------- start_time = time.time() timeout = start_time + 5 * 60 # 最大允许运时间5分钟 # -------------------- 遍历主图像所有可能的位置 -------------------- # 外层循环:纵向遍历主图像(y坐标范围) for y in range(max_y): # 内层循环:横向遍历主图像(x坐标范围) for x in range(max_x): # 超时检测 if time.time() > timeout: return None, None # 超时返回空 mismatch = 0 # 当前位置的不匹配点数计数 is_match = True # 是否匹配的标记 # 遍历所有采样点(纵向×横向) for sample_y in range(step_y): for sample_x in range(step_x): # 计算采样点在模板中的实际坐标(通过左移还原原始位置) template_x = sample_x << density_x # 模板中的列坐标 = 采样x × 2^density_x template_y = sample_y << density_y # 模板中的坐标 = 采样y × 2^density_y # 获取模板采样点的像素 template_pixel = im2[template_y][template_x] # 获取主图像对应位置的像素(主图起始位置(x,y) + 模板偏移(template_x, template_y)) main_pixel = im1[y + template_y][x + template_x] # 像素不匹配时计数 if main_pixel != template_pixel: mismatch += 1 # 超过最大允许不匹配数时,提前终止检查 if mismatch >= max_fail: is_match = False break if not is_match: break # 内层循环提前终止 # 匹配成功时返回结果 if is_match: # 调试模式:记录结束时间 if debug: print(f"此处废弃调试计时") # 处理区域限制(rect参数):调整返回的位置坐标 if rect: x_start, y_start, x_end, y_end = rect # 最终位置 = 原始位置 + rect的偏移量 return ( 1 - (mismatch / total_samples), # 相似度 = 1 - 不匹配率 ( x + x_start, # 左上角x坐标 y + y_start, # 左上角y坐标 x + template_width + x_start, # 右下角x坐标 y + template_height + y_start # 右下角y坐标 ) ) else: # 无区域限制时直接返回原始位置 return ( 1 - (mismatch / total_samples), (x, y, x + template_width, y + template_height) ) # 调试模式:记录结束时间 if debug: print(f"此处废弃调试计时") # 遍历完所有位置未找到匹配 return None, None def get_density(self,width, height, maxWNum=4, maxHNum=4): """ 计算图像匹配时的横向/纵向采样密度(通过右移次数控制采样点数) 核心逻辑: 通过循环右移操作(等价于不断除以2取整),将图像的宽/高缩小到不超过maxWNum/maxHNum, 最终返回需要右移的次数(即密度参数)。该参数用于控制匹配时的采样间隔。 参数: width: 原始图像的宽度(列数) height: 原始图像的高度(数) maxWNum: 横向最大允许采样点数(默认4) maxHNum: 纵向最大允许采样点数(默认4) 返回: (density_x, density_y): 横向/纵向的采样密度(右移次数) """ # 初始化密度参数(右移次数) density_x, density_y = 0, 0 # -------------------- 计算横向采样密度 -------------------- # 当宽度超过maxWNum时,持续右移(每次右移1位,即宽度减半) while width > maxWNum: density_x += 1 # 右移次数+1(密度增加) width = int(width >> 1) # 宽度右移1位(等价于整除2) # -------------------- 计算纵向采样密度 -------------------- # 当高度超过maxHNum时,持续右移(每次右移1位,即高度减半) while height > maxHNum: density_y += 1 # 右移次数+1(密度增加) height = int(height >> 1) # 高度右移1位(等价于整除2) return density_x, density_y
最新发布
07-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值