如何使用OpenCV等工具量化图像不对称性,优先提供Python实现方案
不对称度量化Python实现方案
方案原理
对于这类二维网格的对称度量化,核心思路是将数组沿参考对称轴翻转后,计算翻转结果与原数组的差异,再对差异做归一化得到可横向对比的不对称系数,系数范围为0~1,0代表完全对称,数值越大不对称性越强。
由于你是直接使用
pylab.contourf绘制图像,优先使用绘图用的原始二维网格数据计算,可完全避免图像色阶映射、压缩带来的误差,结果更可靠。
1. 基于原始网格数据的实现(优先推荐)
直接使用你绘制contourf时输入的Z轴二维数组计算,代码如下:
import numpy as np def calculate_asymmetry(Z, axis=1): """ 计算二维网格的归一化不对称度 参数: Z: 绘图用的原始二维数值数组 axis: 对称参考轴:1代表校验左右对称(沿垂直中线翻转),0代表校验上下对称(沿水平中线翻转) 返回: asymmetry_score: 归一化不对称度,取值范围[0,1] residual: 翻转数组与原数组的差值矩阵,可用于定位不对称区域 """ # 沿指定轴翻转数组 Z_flipped = np.flip(Z, axis=axis) # 计算绝对残差总和 residual_abs_sum = np.sum(np.abs(Z - Z_flipped)) # 计算归一化分母,避免不同量级数组结果不可比 total_abs_sum = np.sum(np.abs(Z)) + np.sum(np.abs(Z_flipped)) # 处理全零数组的边界情况 asymmetry_score = residual_abs_sum / total_abs_sum if total_abs_sum != 0 else 0 return asymmetry_score, Z - Z_flipped
调用示例:
# 你的contourf绘图代码比如是plt.contourf(X, Y, Z),直接传入Z即可 asym_score, residual_mat = calculate_asymmetry(Z, axis=1) print(f"当前网格不对称度为:{asym_score:.4f}")
如果需要可视化不对称分布,可直接绘制残差矩阵:
import matplotlib.pyplot as plt plt.contourf(residual_mat, cmap="RdBu_r") plt.colorbar(label="不对称残差(正/负代表两侧数值差异方向)") plt.title("不对称区域分布") plt.show()
2. 基于已生成图像的实现
如果丢失了原始网格数据,只有输出的png图像,可先将图像转为灰度数组后再计算:
import numpy as np from PIL import Image def calculate_asymmetry(Z, axis=1): # 和上面的函数实现完全一致 Z_flipped = np.flip(Z, axis=axis) residual_abs_sum = np.sum(np.abs(Z - Z_flipped)) total_abs_sum = np.sum(np.abs(Z)) + np.sum(np.abs(Z_flipped)) return residual_abs_sum / total_abs_sum if total_abs_sum !=0 else 0, Z-Z_flipped # 读取图像并转为灰度数组 img = Image.open("你的图像路径.png").convert("L") img_arr = np.array(img) asym_score, residual_mat = calculate_asymmetry(img_arr, axis=1)
结果说明
- 完全对称的图2计算得到的
asym_score会无限接近0 - 存在不对称性的图1的得分会明显高于0,数值越高不对称性越强
- 该得分是归一化结果,可直接用于和你的物理属性参数做相关性分析,不需要额外校准
内容的提问来源于stack exchange,提问作者Hangci Du
相关产品推荐
相关产品推荐

