如何生成恶意软件家族灰度图像的变化热力图?含双图与多图场景
嘿,针对你处理恶意软件灰度图像生成变化热力图的需求,我分两个场景给你具体的实现方案,用Python的主流图像处理库就能轻松搞定:
场景1:两张图像高亮显示变化部分
核心思路
先计算两张图像的像素绝对差值,差值越大的区域说明变化越明显;接着把差值数据归一化后映射成彩色热力图,还可以把热力图叠加到原图上,让变化区域一目了然。
代码实现
首先安装依赖库:
pip install opencv-python numpy matplotlib
然后运行以下代码:
import cv2 import numpy as np import matplotlib.pyplot as plt # 加载两张恶意软件灰度图像 img1 = cv2.imread('malware_img1.png', cv2.IMREAD_GRAYSCALE) img2 = cv2.imread('malware_img2.png', cv2.IMREAD_GRAYSCALE) # 确保两张图像尺寸一致(如果不一致,将第二张图resize到第一张的尺寸) if img1.shape != img2.shape: img2 = cv2.resize(img2, (img1.shape[1], img1.shape[0])) # 计算像素级绝对差值 diff_map = cv2.absdiff(img1, img2) # 归一化差值到0-255范围,适配热力图颜色映射 normalized_diff = cv2.normalize(diff_map, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U) # 生成彩色热力图(这里用JET配色,也可以换成COLORMAP_HOT/VIRIDIS等) heatmap = cv2.applyColorMap(normalized_diff, cv2.COLORMAP_JET) # 可选:将热力图和原图叠加,更直观对比变化区域 overlay = cv2.addWeighted(img1[:, :, np.newaxis], 0.7, heatmap, 0.3, 0) # 展示结果 plt.figure(figsize=(12, 6)) plt.subplot(131), plt.imshow(img1, cmap='gray'), plt.title('Malware Image 1') plt.subplot(132), plt.imshow(img2, cmap='gray'), plt.title('Malware Image 2') plt.subplot(133), plt.imshow(cv2.cvtColor(overlay, cv2.COLOR_BGR2RGB)), plt.title('Change Heatmap') plt.show() # 保存热力图到本地 cv2.imwrite('two_img_change_heatmap.png', heatmap)
关键说明
- 像素差值直接反映了两张图的差异程度,归一化是为了让差值范围适配彩色映射的要求;
- 叠加原图的操作能帮你快速定位变化区域在原恶意软件图像中的位置;
- 如果图像有噪声,可以先加一行
diff_map = cv2.GaussianBlur(diff_map, (3,3), 0)来平滑噪声,让变化区域更清晰。
场景2:一组图像生成变化最频繁区域的热力图
核心思路
用像素方差来衡量每个位置的变化频率:方差越大,说明该像素在所有图像中的值波动越剧烈,也就是变化越频繁。我们统计所有图像中每个像素的方差,再将方差数据转换成热力图,就能直观看到哪些区域变化最频繁。
代码实现
同样先确保依赖库已安装,然后运行以下代码:
import cv2 import numpy as np import matplotlib.pyplot as plt import os # 定义存放恶意软件图像的文件夹路径 img_folder = 'malware_image_collection/' # 加载所有灰度图像并统一尺寸 img_collection = [] for filename in os.listdir(img_folder): if filename.lower().endswith(('.png', '.jpg', '.jpeg')): img_path = os.path.join(img_folder, filename) img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE) # 以第一张图像的尺寸为标准,统一所有图像大小 if not img_collection: target_h, target_w = img.shape else: img = cv2.resize(img, (target_w, target_h)) img_collection.append(img) # 将图像列表转换为numpy数组,形状为 (图像数量, 高度, 宽度) img_array = np.array(img_collection) # 计算每个像素位置的方差(沿图像数量维度计算) pixel_variance_map = np.var(img_array, axis=0) # 归一化方差到0-255范围,生成热力图 normalized_variance = cv2.normalize(pixel_variance_map, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U) heatmap = cv2.applyColorMap(normalized_variance, cv2.COLORMAP_JET) # 展示结果 plt.figure(figsize=(10, 5)) plt.subplot(121), plt.imshow(img_array[0], cmap='gray'), plt.title('Sample Malware Image') plt.subplot(122), plt.imshow(cv2.cvtColor(heatmap, cv2.COLOR_BGR2RGB)), plt.title('Most Frequent Change Heatmap') plt.show() # 保存热力图 cv2.imwrite('multi_img_change_heatmap.png', heatmap)
关键说明
- 方差是衡量数据离散程度的指标,完美适配“变化频率”的需求;如果觉得方差不够直观,也可以用标准差(
np.std(img_array, axis=0)),结果趋势完全一致; - 一定要确保所有图像尺寸统一,否则无法进行像素级的统计计算;
- 如果图像数量较多,可以考虑分批加载处理,避免内存占用过高。
内容的提问来源于stack exchange,提问作者Lelouch




