#python #pytorch
#python #pytorch
Вопрос:
Модель CNN принимает тензор размера изображения (112x112)
в качестве входных данных и выдает (1x512)
тензор размера в качестве выходных данных.
Использование функции Opencv cv2.resize()
или использование Transform.resize
в pytorch для изменения размера входных данных (112x112)
дает разные результаты.
В чем причина этого? (Я понимаю, что причиной этого может быть разница в базовой реализации изменения размера opencv по сравнению с изменением размера torch, но я хотел бы иметь подробное представление об этом)
import cv2
import numpy as np
from PIL import image
import torch
import torchvision
from torchvision import transforms as trans
# device for pytorch
device = torch.device('cuda:0')
torch.set_default_tensor_type('torch.cuda.FloatTensor')
model = torch.jit.load("traced_facelearner_model_new.pt")
model.eval()
# read the example image used for tracing
image=cv2.imread("videos/example.jpg")
test_transform = trans.Compose([
trans.ToTensor(),
trans.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
])
test_transform2 = trans.Compose([
trans.Resize([int(112), int(112)]),
trans.ToTensor(),
trans.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
])
resized_image = cv2.resize(image, (112, 112))
tensor1 = test_transform(resized_image).to(device).unsqueeze(0)
tensor2 = test_transform2(Image.fromarray(image)).to(device).unsqueeze(0)
output1 = model(tensor1)
output2 = model(tensor2)
Тензоры output1 и output2 имеют разные значения.
Ответ №1:
В основном torchvision.transforms.Resize()
используется PIL.Image.BILINEAR
интерполяция по умолчанию.
В то время как в вашем коде вы просто используете cv2.resize
, который не использует никакой интерполяции.
Например
import cv2
from PIL import Image
import numpy as np
a = cv2.imread('videos/example.jpg')
b = cv2.resize(a, (112, 112))
c = np.array(Image.fromarray(a).resize((112, 112), Image.BILINEAR))
Вы увидите, что b
и c
немного отличаются.
Редактировать:
На самом деле в документах opencv говорится
INTER_LINEAR — билинейная интерполяция (используется по умолчанию)
Но да, это не дает того же результата, что PIL
.
Правка 2:
Это также в документах
Чтобы уменьшить изображение, оно, как правило, будет выглядеть лучше всего с интерполяцией INTER_AREA
И, по-видимому
d = cv2.resize(a, (112, 112), interpolation=cv2.INTER_AREA)
Дает почти тот же результат, что и c
. Но, к сожалению, они не отвечают на вопрос.
Комментарии:
1. OpenCV по умолчанию не использует интерполяцию
2. Читайте здесь docs.opencv.org/trunk/da/d54 /…
3. Это выполняется
None
на Python, но по умолчаниюcv::resize
используетсяINTER_LINEAR
4. @Natthaphon Хонгчароен. PIL применяет некоторый фильтр сглаживания перед изменением размера. Но не cv2, это также приводит к некоторым различиям
5. @GirishDattatrayHegde Вот и ответ на вопрос. Я думаю, вам следует использовать это в качестве другого ответа, поскольку здесь его можно легко пропустить.