import cv2
import numpy as np
import torch
from torch.autograd import Variable
from torchvision import models
def preprocess_image(cv2im, resize_im=True):
# 图片网络的平均值和标准差
mean = [0.485, 0.456, 0.406]
std = [0.229, 0.224, 0.225]
# 重定义图片大小
if resize_im:
cv2im = cv2.resize(cv2im, (224, 224))
im_as_arr = np.float32(cv2im)
im_as_arr = np.ascontiguousarray(im_as_arr[..., ::-1])
im_as_arr = im_as_arr.transpose(2, 0, 1) # Convert array to D,W,H
# 标准化
for channel, _ in enumerate(im_as_arr):
im_as_arr[channel] /= 255
im_as_arr[channel] -= mean[channel]
im_as_arr[channel] /= std[channel]
# 转换为浮点张量
im_as_ten = torch.from_numpy(im_as_arr).float()
# Add one more channel to the beginning. Tensor shape = 1,3,224,224
im_as_ten.unsqueeze_(0)
# 转换为pytorch变量
im_as_var = Variable(im_as_ten, requires_grad=True)
return im_as_var
class FeatureVisualization():
def __init__(self, img_path, selected_layer):
self.img_path = img_path
self.selected_layer = selected_layer
self.pretrained_model = models.vgg16(pretrained=True).features
def process_image(self):
img = cv2.imread(self.img_path)
img = preprocess_image(img)
return img
def get_feature(self):
# input = Variable(torch.randn(1, 3, 224, 224))
input = self.process_image()
print(input.shape)
x = input
for index, layer in enumerate(self.pretrained_model):
x = layer(x)
if (index == self.selected_layer):
return x
def get_single_feature(self):
features = self.get_feature()
print(features.shape)
feature = features[:, 0, :, :]
print(feature.shape)
feature = feature.view(feature.shape[1], feature.shape[2])
print(feature.shape)
return feature
def save_feature_to_img(self):
#to numpy
feature = self.get_single_feature()
feature = feature.data.numpy()
#use sigmod to [0,1]
feature = 1.0/(1+np.exp(-1*feature))
# to [0,255]
feature = np.round(feature*255)
print(feature[0])
cv2.imwrite(r'路径\img.jpg', feature)
if __name__=='__main__':
# get class
myClass = FeatureVisualization(r'路径\1.jpg', 2)
print(myClass.pretrained_model)
myClass.save_feature_to_img()
网络输出:
Sequential(
(0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(1): ReLU(inplace=True)
(2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(3): ReLU(inplace=True)
(4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(6): ReLU(inplace=True)
(7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(8): ReLU(inplace=True)
(9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(11): ReLU(inplace=True)
(12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(13): ReLU(inplace=True)
(14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(15): ReLU(inplace=True)
(16): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(17): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(18): ReLU(inplace=True)
(19): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(20): ReLU(inplace=True)
(21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(22): ReLU(inplace=True)
(23): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(24): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(25): ReLU(inplace=True)
(26): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(27): ReLU(inplace=True)
(28): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(29): ReLU(inplace=True)
(30): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)