Pytorch 学习 (四) 三通道图片 CNN 图片轮廓检测

 单通道,三通道 介绍:

(一):单通道图,

俗称灰度图,每个像素点只能有有一个值表示颜色,它的像素值在0到255之间,0是黑色,255是白色,中间值是一些不同等级的灰色。(也有3通道的灰度图,3通道灰度图只有一个通道有值,其他两个通道的值都是零)。

(二):三通道图,每个像素点都有3个值表示 ,所以就是3通道。也有4通道的图。例如RGB图片即为三通道图片,RGB色彩模式是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。总之,每一个点由三个值表示。

轮廓检测  卷积层:

(一):卷积在 pytorch 中有两种方式,一种是 torch.nn.Conv2d(),一种是 torch.nn.functional.conv2d(),这两种形式本质都是使用一个卷积操作

这两种形式的卷积对于输入的要求都是一样的,首先需要输入是一个 torch.autograd.Variable() 的类型,大小是 (batch, channel, H, W),其中 batch 表示输入的一批数据的数目,第二个是输入的通道数,一般一张彩色的图片是 3,灰度图是 1,而卷积网络过程中的通道数比较大,会出现几十到几百的通道数,H 和 W 表示输入图片的高度和宽度,比如一个 batch 是 32 张图片,每张图片是 3 通道,高和宽分别是 50 和 100,那么输入的大小就是 (32, 3, 50, 100)

(二):图片读入的时候:格式(H, W, channel)

# -*- coding: utf-8 -*-
# @Time    : 2021/1/14 12:06
# @Author  : wwq_biubiu!!
# @FileName: chapter2_7_CNN_show.py
# @Software: PyCharm
import numpy as np
import torch
from torch import nn
from torch.autograd import Variable
import torch.nn.functional as F
from PIL import Image
import matplotlib.pyplot as plt
from torchvision import transforms
import cv2
# 读入照片
im = Image.open('./data/face_1.jpeg')
# 将照片变成 np
plt.imshow(im, cmap='gray')
plt.show()

im = np.array(im, dtype='float32')
print(im.shape)
print(im[:][1][:].shape)
plt.imshow(im[:][:][1].astype('uint8'), cmap='gray')
plt.show()
# 将图片矩阵转化为pytorch tensor ,并适配卷积输入要求

im = np.transpose(im, (2, 1, 0))
im = im[np.newaxis, :]
print(im.shape)
conv1 = nn.Conv2d(3, 3, 3, bias= False) # 定义卷积
# sobel_kernel = np.array([[[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]], [[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]], [[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]]], dtype='float32') # 定义轮廓检测算子

sobel_kernel = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]], dtype='float32') / 3
# 将sobel算子转换为适配卷积操作的卷积核
sobel_kernel = sobel_kernel.reshape((1, 1, 3, 3))
# 卷积输出通道,这里我设置为3
#  np.repeats(a,repeats, axis=None)

# 其中a为数组,repeats为重复的次数,axis表示数组维度
sobel_kernel = np.repeat(sobel_kernel, 3, axis=1)
# 输入图的通道,这里我设置为3
print(sobel_kernel.shape)
sobel_kernel = np.repeat(sobel_kernel, 3, axis=0)
print(sobel_kernel.shape)
conv1.weight.data = torch.from_numpy(sobel_kernel)# 给卷积的 kernel 赋值

edge1 = conv1(Variable(torch.from_numpy(im)))# 作用在图片上
print(edge1.shape)
edge1 = edge1.data.squeeze().detach().numpy()# # 将输出转换为图片的格式
#edge1= edge1.reshape(3, 298, 299)
print('------')
print(edge1.shape)
edge1 = np.transpose(edge1,(2,1,0))
print(edge1.shape)
cv2.imshow('edge.jpg', edge1)
cv2.waitKey(0)

ouput:

(300, 301, 3)
(1, 3, 301, 300)
(1, 3, 3, 3)
(3, 3, 3, 3)
torch.Size([1, 3, 299, 298])
------
(3, 299, 298)
(298, 299, 3)

 

函数型代码;

import torch
import numpy as np
from torch import nn
from PIL import Image
from torch.autograd import Variable
import torch.nn.functional as F


def edge_conv2d(im):
    # 用nn.Conv2d定义卷积操作
    conv_op = nn.Conv2d(3, 3, kernel_size=3, padding=1, bias=False)
    # 定义sobel算子参数,所有值除以3个人觉得出来的图更好些
    sobel_kernel = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]], dtype='float32') / 3
    # 将sobel算子转换为适配卷积操作的卷积核
    sobel_kernel = sobel_kernel.reshape((1, 1, 3, 3))
    # 卷积输出通道,这里我设置为3
    sobel_kernel = np.repeat(sobel_kernel, 3, axis=1)
    # 输入图的通道,这里我设置为3
    sobel_kernel = np.repeat(sobel_kernel, 3, axis=0)
    print(sobel_kernel.shape)
    conv_op.weight.data = torch.from_numpy(sobel_kernel)
    # print(conv_op.weight.size())
    # print(conv_op, '\n')

    edge_detect = conv_op(im)
    print(torch.max(edge_detect))
    # 将输出转换为图片格式
    edge_detect = edge_detect.squeeze().detach().numpy()
    print(edge_detect.shape)
    return edge_detect

def edge_extraction():
    im = cv2.imread("./data/face_1.jpeg", flags=1)
    print(im.shape) #  图片的的张量(W,H,H)
    im = np.transpose(im, (2, 0, 1))
    print(im.shape)
    # 添加一个维度,对应于pytorch模型张量(B, N, W, H)中的batch_size
    im = im[np.newaxis, :]
    print(im.shape)
    im = torch.Tensor(im)
    edge_detect = edge_conv2d(im)
    edge_detect = np.transpose(edge_detect, (1, 2, 0))
    cv2.imshow('edge.jpg', edge_detect)
    cv2.waitKey(0)
    cv2.imwrite('./data/fac3_1.jpeg', edge_detect)

if __name__ == "__main__":
    edge_extraction()

池化层:

灰度值越高,最高值255(白色),越暗的像素,灰度值越低,最低值0(黑色)

import numpy as np
import torch
from torch import nn
from torch.autograd import Variable
import torch.nn.functional as F
from PIL import Image
import matplotlib.pyplot as plt
from torchvision import transforms
import cv2
# 读入照片
im = Image.open('./data/face_1.jpeg')
im = np.array(im, dtype='float32')
im = np.transpose(im, (2, 1, 0))
im = im[np.newaxis, :]
pool1 = nn.MaxPool2d(2,2)
print('before max pool, image shape: {} x {}'.format(im.shape[2], im.shape[3]))
small_im1 = pool1(Variable(torch.from_numpy(im)))
print(small_im1.shape)
small_im1 = small_im1.data.squeeze().numpy()
small_im1 = np.transpose(small_im1, (2, 1, 0))

small_im2 = F.max_pool2d(torch.from_numpy(im), 2, 2)
small_im2 = small_im2.data.squeeze().numpy()
print('after max pool, image shape: {} x {} '.format(small_im1.shape[0], small_im1.shape[1]))
print(small_im2.shape)
cv2.imshow('edge.jpg', small_im1)
cv2.waitKey(0)

output:

before max pool, image shape: 301 x 300
torch.Size([1, 3, 150, 150])
after max pool, image shape: 150 x 150 
(3, 150, 150)

 

note: 可能是图片的质量问题 图片显示几乎是白色 。

 

reference;

https://wizardforcel.gitbooks.io/learn-dl-with-pytorch-liaoxingyu/content/4.1.html

https://blog.csdn.net/qq_37760750/article/details/107228529

 

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
PyTorch是一款深度学习框架,它支持多种卷积神经网络(CNN)模型,能够高效地完成分类、分割、目标检测等任务。本文将介绍,如何使用PyTorch实现图片篡改检测。 图片篡改检测是指对一张图片进行分析和检测,判断其中是否存在未经授权或恶意篡改的修改痕迹,如水印、尺度变换、亮度调整等。 进行图片篡改检测的CNN模型可以分为以下几个步骤: 1. 数据预处理:首先需要对图片进行预处理,包括图像增强、尺寸调整、归一化等,以便模型更好地学习痕迹。 2. 卷积神经网络:使用PyTorch搭建CNN模型,该模型可以通过多层卷积、池化、批规范化等操作提取特征,有效地区分正常图片和篡改图片。 3. 损失函数:为了让模型更加准确地判断图片是否被篡改,需要设置相应的损失函数,如交叉熵函数、均方误差函数等。 4. 优化器:建立优化器,如Adam、SGD、RMSprop等,通过迭代学习优化器来降低损失函数值,提高模型预测效果。 5. 训练模型:将大量的篡改和正常图片作为训练样本,经过模型进行训练后,可以得到训练好的模型。 6. 测试模型:在测试数据集上,使用训练好的模型进行图片的判断,判断哪些图片中存在篡改痕迹,哪些图片是正常的。 最终,利用PyTorch搭建的CNN模型,可以实现对图片进行篡改检测,并且具有较高的准确度。实践中也会遇到一些问题和细节,需要在模型搭建、损失函数、优化器和训练模型等方面进行调试和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值