前言:最近在可视化图像残差时,发现几种不同的差分方法,下面分别给出每种差分方法的实现方式,并比较不同方法之间的差异。
目录
- 1️⃣ cv2
- 2️⃣ PIL & torchvision
- 3️⃣ PIL & numpy
目标:对于给定的下述两张图像,计算二者的残差。
cur_clean_img 图像:
(图片来源:Flickr8k 数据集,1258913059_07c613f7ff.jpg)
cur_poi_img 图像:
cur_poi_img 相较于 cur_clean_img 的不同是,在 cur_clean_img 的右下角添加了一个 10*10 大小的 patch。所以,理想的差分结果应该是:除了添加patch区域,差分图像的其余部分都是全黑。
下面给出三种图像差分方法。
1️⃣ cv2
依赖库:cv2
安装方式:pip install opencv-python
import cv2
cur_poi_img = cv2.imread(poi_image_path)
cv2.imwrite(poi_save_path, cur_poi_img)
cur_clean_img = cv2.imread(clean_img_path)
# cur_clean_img = cv2.resize(cur_clean_img, (256, 256))
# cur_clean_img = np.array(Image.fromarray(cur_clean_img).resize((256, 256)))
cv2.imwrite(clean_save_path, cur_clean_img)
residual = cv2.absdiff(cur_poi_img,cur_clean_img)
cv2.imwrite(residual_save_path, residual)
对应残差结果:
2️⃣ PIL & torchvision
依赖库:torchvision
安装方式:pip install torchvision
import torchvision.transforms as T
from torchvision.utils import save_image
transform = T.Compose([
# T.Resize([256, 256]),
T.ToTensor(),
])
image = Image.open(clean_img_path).convert("RGB")
clean_img_tensor = transform(image)
save_image(clean_img_tensor, clean_save_path)
image = Image.open(poi_image_path).convert("RGB")
poi_img_tensor = transform(image)
save_image(poi_img_tensor, poi_save_path)
residual_tensor = poi_img_tensor - clean_img_tensor
save_image(residual_tensor, residual_save_path)
对应残差结果:
3️⃣ PIL & numpy
依赖库:PIL, numpy
安装方式:pip install pillow
, pip install numpy
from PIL import Image
import numpy as np
cur_poi_img = Image.open(poi_image_path)
cur_poi_img = np.asarray(cur_poi_img)
cur_clean_img = Image.open(clean_img_path)
cur_clean_img = np.asarray(cur_clean_img)
residual = cur_poi_img - cur_clean_img
residual = (residual * 255).astype(np.uint8)
residual = Image.fromarray(residual)
residual.save(residual_save_path)
对应残差结果:
后记:由上述结果可以看出,通过
numpy
方式计算得到的残差图像并不是十分准确,这是由于在使用.astype(np.uint8)
进行数据转换时产生了信息损失,大家在实际操作的时候也要引以为戒,选择正确的方式进行图像差分。
PS:resize操作对差分结果有很大影响!假如我们按照 clean_image-[Resize]-resized-image-[AddNoise]-poi_image的流程进行操作,在计算差分结果时,使用的图像对最好是resized-image和poi_image,而不是clean_image和poi_image。下面给出后者的错误计算结果(建议放大🔍观看)❌:
我们会发现,除patch区域,差分图像的其余区域也出现了扰动印记,这是resize操作带来的误差,从而印证了上述观点。
参考资料
- Python与机器视觉(x)图像差分-图像相减_图像差分python-CSDN博客