双文件夹图像相似性匹配(欧氏距离)报错排查与需求实现
问题解决:图像相似性计算中的1-D向量错误及自定义相似性度量实现
错误原因
报错ValueError: Input vector should be 1-D是因为scipy.spatial.distance.euclidean要求输入必须是1维向量,但你传入的是2维灰度图像矩阵(形状为(H,W)),不符合函数的输入要求。
快速修复错误(仅解决报错,不满足需求)
如果只是想先修复报错,把2维图像展平为1维向量即可,修改相似性计算的代码行:
# 原代码 s = dist.euclidean(input_img, input_img2) # 修改后 s = dist.euclidean(input_img.flatten(), input_img2.flatten())
但这种像素级欧氏距离不符合你"仅依赖点的中心距离,不依赖点的直径大小"的需求,下面是符合需求的完整实现。
符合需求的相似性度量实现
你的核心需求是基于目标点的中心距离计算相似性,距离越小则匹配度越高。下面是具体实现步骤和代码修改:
1. 编写目标中心提取函数
首先实现一个从分割图像中提取目标中心坐标的函数(假设图像是二值分割结果,前景为白色):
def get_centroid(img): # 二值化处理(确保前景为白色) _, binary_img = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY) # 提取图像轮廓 contours, _ = cv2.findContours(binary_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if not contours: return (0, 0) # 无目标时返回原点 # 取面积最大的轮廓(假设单目标场景) largest_contour = max(contours, key=cv2.contourArea) # 计算轮廓矩 contour_moments = cv2.moments(largest_contour) if contour_moments["m00"] == 0: return (0, 0) # 计算中心坐标 center_x = int(contour_moments["m10"] / contour_moments["m00"]) center_y = int(contour_moments["m01"] / contour_moments["m00"]) return (center_x, center_y)
2. 修改相似性计算逻辑
替换原代码中的像素级欧氏距离计算,改为基于中心坐标的距离计算,同时修正匹配逻辑(中心距离越小,匹配度越高,所以取最小值而非最大值):
# 替换原循环内的相似性计算部分 for image in range(images_list.shape[0]): input_img = images_list[image, :, :] # 提取两张图像的目标中心 center1 = get_centroid(input_img) center2 = get_centroid(input_img2) # 计算中心间的欧氏距离 distance = dist.euclidean(center1, center2) resultlist.append(float(distance)) img_number += 1 # 修正匹配逻辑:找距离最小的图像(匹配度最高) ll = min(resultlist) # 原代码用max,这里改为min Maxlist.append(float(ll)) MM = resultlist.index(ll)
3. 其他注意事项
- 如果你的图像不是二值分割图,需要先根据实际情况调整二值化阈值,确保能准确提取目标区域。
- 若存在多目标场景,可以修改
get_centroid函数,比如计算所有目标中心的平均坐标,或者根据业务需求选择特定目标。
内容的提问来源于stack exchange,提问作者Fadil
相关产品推荐
相关产品推荐

