vl_imreadjpeg和cv2的resize结果不同
程序员文章站
2022-06-26 17:14:26
matlab 用 vl_imreadjpeg 读图并 resize 到 [224, 224],与 python 用 cv2 做同样操作,得到的结果不同。在用 vl_imreadjpeg 读图的 matlab 程序想做 zero mean 操作,不能直接白嫖之前 python 用 cv2 处理的 image mean pixel,而要重新处理一个 mean pixel。Data用 nuswide 测试,见 [1],用以下程序将 image 放到同一个目录,方便读取:效果:在 images/ 下,...
matlab 用 vl_imreadjpeg 读图并 resize 到 [224, 224],与 python 用 cv2 做同样操作,得到的结果不同。
- 在用 vl_imreadjpeg 读图的 matlab 程序想做 zero mean 操作,不能直接白嫖之前 python 用 cv2 处理的 image mean pixel,而要重新处理一个 mean pixel。
Environment
- matlab R2018a
- matconvnet-1.0-beta25
- opencv-python-headless 4.4.0.42
Data
用 nuswide 测试,见 [1],用以下程序将 image 放到同一个目录,方便读取:
- 效果:在 images/ 下,image 软链接名形如
n.jpg
,n 是 sample id。
import os
P = "/home/dataset/nuswide"
print("current dir:", os.getcwd())
print("--- image ---")
IMAGE_LIST = os.path.join(P, "ImageList/Imagelist.txt")
IMAGE_SRC = os.path.join(P, "Flickr")
IMAGE_DEST = os.path.join(os.getcwd(), "images")
if not os.path.exists(IMAGE_DEST):
os.makedirs(IMAGE_DEST)
with open(IMAGE_LIST, "r") as f:
for sid, line in enumerate(f):
line = line.replace('\\/'.replace(os.sep, ''), os.sep).strip()
img_p = os.path.join(IMAGE_SRC, line)
new_img_p = os.path.join(IMAGE_DEST, "{}.jpg".format(sid))
os.system("ln -s {} {}".format(img_p, new_img_p))
if sid % 1000 == 0:
print(sid)
Comparison
对比思路:先 matlab 用 vl_imreadjpeg 读一张图,存成 .mat 文件,然后 python 用 cv2 读同一张图比较。这里以 1.jpg 为例,可以换成其它 image。
without resize
在不用 resize 操作时,两者读出的结果相同。
- matlab + vl_imreadjpeg
cd matconvnet;
setup;
cd /home/tom/codes/test.matlab;
% 以 1.jpg 为例,可以换成 2.jpg、3.jpg……
a = {char(fullfile("images", "1.jpg"))};
img = vl_imreadjpeg(a); % 读图,不用 resize
img = uint8(img{1, 1});
disp(size(img)); % (181, 240, 3)
save("image_vl.1.mat", "img");
- python + cv2
import os
import numpy as np
import scipy.io as sio
import cv2
from PIL import Image
P = "images"
def load_image(idx):
img_p = os.path.join(P, "{}.jpg".format(idx))
img = cv2.imread(img_p)#[:, :, ::-1]
if img is None: # cv2 读不了,就改用 PIL.Image 读
img_f = Image.open(img_p)
img = np.asarray(img_f)
img_f.close()
if 2 == img.ndim: # 缺 channel
img = np.repeat(img[:, :, np.newaxis], 3, axis=2)
else:
img = img[:, :, ::-1]
# 不用 resize
# img = cv2.resize(img, (224, 224), interpolation=cv2.INTER_LINEAR)
return img
img_vl = sio.loadmat("image_vl.mat")["img"].astype(np.int64) # 读刚才 matlab 存的图
img_py = load_image(1).astype(np.int64) # 同样是 1.jpg
print(img_vl.shape, img_py.shape) # (181, 240, 3) (181, 240, 3),相同
print(img_vl.sum(), img_py.sum()) # 19504976 19504976,相同
print("diff:", np.abs(img_vl - img_py).sum()) # diff: 0
with resize
还是刚才的代码,只不过两者都加上 resize 操作:统一 resize 成 224 x 224,结果就不同了。
- matlab + vl_imreadjpeg
cd matconvnet;
setup;
cd /home/tom/codes/test.matlab;
% 还是 1.jpg 为例
a = {char(fullfile("images", "1.jpg"))};
img = vl_imreadjpeg(a, 'Resize', [224, 224]); % 这次加上 resize
img = uint8(img{1, 1});
disp(size(img)); % (224, 224, 3)
save("image_vl.1.mat", "img");
- python + cv2
import os
import numpy as np
import scipy.io as sio
import cv2
from PIL import Image
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
P = "images"
def load_image(idx):
img_p = os.path.join(P, "{}.jpg".format(idx))
img = cv2.imread(img_p)#[:, :, ::-1]
if img is None: # cv2 读不了,就改用 PIL.Image 读
img_f = Image.open(img_p)
img = np.asarray(img_f)
img_f.close()
if 2 == img.ndim: # 缺 channel
img = np.repeat(img[:, :, np.newaxis], 3, axis=2)
else:
img = img[:, :, ::-1]
# 用上 resize
img = cv2.resize(img, (224, 224), interpolation=cv2.INTER_LINEAR)
return img
img_vl = sio.loadmat("image_vl.mat")["img"].astype(np.int64) # 读刚才 matlab 存的图
img_py = load_image(1).astype(np.int64) # 同样是 1.jpg
print(img_vl.shape, img_py.shape) # (224, 224, 3) (224, 224, 3),相同
print(img_vl.sum(), img_py.sum()) # 22847441 22509472,不同!!!
print("diff:", np.abs(img_vl - img_py).sum()) # diff: 10933205,不同!!!
# 画出来看区别
fig, ax = plt.subplots(1, 2)
ax[0].imshow(img_vl);
ax[0].set_title("vl_imreadjpeg")
ax[1].imshow(img_py)
ax[1].set_title("cv2")
fig.savefig("compare_load.png")
plt.close(fig)
- 画图结果
…vl_imreadjpeg 这个难道不是叫「crop」?
Conclusion
所以 vl_imreadjpeg 和 cv2 两种读图方式,在不 resize 时结果相同,但用 resize 之后两者结果不同!
而令人迷惑的是:vl_imreadjpeg 的官网介绍[3]说它 resize 用的是「bilinear interpolation」;而我在 python 调 cv2 时用的 cv2.INTER_LINEAR
也是「bilinear interpolation」[4]…
References
- NUS-WIDE数据集预处理
- docker命令行安装matlab R2018a、matconvnet、gpu环境
- vl_imreadjpeg
- cv2.INTER_LINEAR
- opencv: 图像缩放(cv2.resize)
本文地址:https://blog.csdn.net/HackerTom/article/details/110926141
推荐阅读
-
C#对称加密(AES加密)每次生成的结果都不同的实现思路和代码实例
-
秦朝和汉朝都实施郡县制 为何会出现两种不同的结果
-
vl_imreadjpeg和cv2的resize结果不同
-
小弟我在本地写完程序放到了服务器下,发现服务器下model返回的结果和本地是不同的
-
utf-8 - php的strlen和mb_strlen结果不同
-
【翻译自mos文章】DBA_JOBS和DBA_JOBS_RUNNING不同的结果的解释
-
【翻译自mos文章】DBA_JOBS和DBA_JOBS_RUNNING不同的结果的解释
-
php中,自己重新拼接的字符串echo和var_damp出来的结果不同?【刚才的帖子发错了】
-
秦朝和汉朝都实施郡县制 为何会出现两种不同的结果
-
加密-java和php的hmac_sha1结果不同,求高手帮忙