Python实现照片卡通化,一拳打破次元壁 | 机器学习

简介: Python实现照片卡通化,一拳打破次元壁 | 机器学习

前言

接着我上一篇开源机器学习的使用:如何将照片变成卡通图,animegan2-pytorch机器学习项目使用 | 机器学习_阿良的博客-CSDN博客


我还是继续把项目稍微魔改一下,依然变为一个python文件就可以执行单一图片的处理。变为可以直接拿去使用的工具。


项目github地址:github地址


项目结构

samples目录里面有一些样例图片,可以测试用。weights目录放了原项目的4个模型。python环境需要安装一些依赖,主要是pytorch。pytorch的环境安装可以参考我的另一篇文章:机器学习基础环境部署 | 机器学习系列_阿良的博客-CSDN博客


image.png

image.png




核心代码

不废话,上核心代码了。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2021/12/4 22:34
# @Author  : 剑客阿良_ALiang
# @Site    : 
# @File    : image_cartoon_tool.py
from PIL import Image
import torch
from torchvision.transforms.functional import to_tensor, to_pil_image
from torch import nn
import os
import torch.nn.functional as F
import uuid
# -------------------------- hy add 01 --------------------------
class ConvNormLReLU(nn.Sequential):
    def __init__(self, in_ch, out_ch, kernel_size=3, stride=1, padding=1, pad_mode="reflect", groups=1, bias=False):
        pad_layer = {
            "zero": nn.ZeroPad2d,
            "same": nn.ReplicationPad2d,
            "reflect": nn.ReflectionPad2d,
        }
        if pad_mode not in pad_layer:
            raise NotImplementedError
        super(ConvNormLReLU, self).__init__(
            pad_layer[pad_mode](padding),
            nn.Conv2d(in_ch, out_ch, kernel_size=kernel_size, stride=stride, padding=0, groups=groups, bias=bias),
            nn.GroupNorm(num_groups=1, num_channels=out_ch, affine=True),
            nn.LeakyReLU(0.2, inplace=True)
        )
class InvertedResBlock(nn.Module):
    def __init__(self, in_ch, out_ch, expansion_ratio=2):
        super(InvertedResBlock, self).__init__()
        self.use_res_connect = in_ch == out_ch
        bottleneck = int(round(in_ch * expansion_ratio))
        layers = []
        if expansion_ratio != 1:
            layers.append(ConvNormLReLU(in_ch, bottleneck, kernel_size=1, padding=0))
        # dw
        layers.append(ConvNormLReLU(bottleneck, bottleneck, groups=bottleneck, bias=True))
        # pw
        layers.append(nn.Conv2d(bottleneck, out_ch, kernel_size=1, padding=0, bias=False))
        layers.append(nn.GroupNorm(num_groups=1, num_channels=out_ch, affine=True))
        self.layers = nn.Sequential(*layers)
    def forward(self, input):
        out = self.layers(input)
        if self.use_res_connect:
            out = input + out
        return out
class Generator(nn.Module):
    def __init__(self, ):
        super().__init__()
        self.block_a = nn.Sequential(
            ConvNormLReLU(3, 32, kernel_size=7, padding=3),
            ConvNormLReLU(32, 64, stride=2, padding=(0, 1, 0, 1)),
            ConvNormLReLU(64, 64)
        )
        self.block_b = nn.Sequential(
            ConvNormLReLU(64, 128, stride=2, padding=(0, 1, 0, 1)),
            ConvNormLReLU(128, 128)
        )
        self.block_c = nn.Sequential(
            ConvNormLReLU(128, 128),
            InvertedResBlock(128, 256, 2),
            InvertedResBlock(256, 256, 2),
            InvertedResBlock(256, 256, 2),
            InvertedResBlock(256, 256, 2),
            ConvNormLReLU(256, 128),
        )
        self.block_d = nn.Sequential(
            ConvNormLReLU(128, 128),
            ConvNormLReLU(128, 128)
        )
        self.block_e = nn.Sequential(
            ConvNormLReLU(128, 64),
            ConvNormLReLU(64, 64),
            ConvNormLReLU(64, 32, kernel_size=7, padding=3)
        )
        self.out_layer = nn.Sequential(
            nn.Conv2d(32, 3, kernel_size=1, stride=1, padding=0, bias=False),
            nn.Tanh()
        )
    def forward(self, input, align_corners=True):
        out = self.block_a(input)
        half_size = out.size()[-2:]
        out = self.block_b(out)
        out = self.block_c(out)
        if align_corners:
            out = F.interpolate(out, half_size, mode="bilinear", align_corners=True)
        else:
            out = F.interpolate(out, scale_factor=2, mode="bilinear", align_corners=False)
        out = self.block_d(out)
        if align_corners:
            out = F.interpolate(out, input.size()[-2:], mode="bilinear", align_corners=True)
        else:
            out = F.interpolate(out, scale_factor=2, mode="bilinear", align_corners=False)
        out = self.block_e(out)
        out = self.out_layer(out)
        return out
# -------------------------- hy add 02 --------------------------
def load_image(image_path, x32=False):
    img = Image.open(image_path).convert("RGB")
    if x32:
        def to_32s(x):
            return 256 if x < 256 else x - x % 32
        w, h = img.size
        img = img.resize((to_32s(w), to_32s(h)))
    return img
def handle(image_path: str, output_dir: str, type: int, device='cpu'):
    _ext = os.path.basename(image_path).strip().split('.')[-1]
    if type == 1:
        _checkpoint = './weights/paprika.pt'
    elif type == 2:
        _checkpoint = './weights/face_paint_512_v2.pt'
    else:
        raise Exception('type not support')
    os.makedirs(output_dir, exist_ok=True)
    net = Generator()
    net.load_state_dict(torch.load(_checkpoint, map_location="cpu"))
    net.to(device).eval()
    image = load_image(image_path)
    with torch.no_grad():
        image = to_tensor(image).unsqueeze(0) * 2 - 1
        out = net(image.to(device), False).cpu()
        out = out.squeeze(0).clip(-1, 1) * 0.5 + 0.5
        out = to_pil_image(out)
    result = os.path.join(output_dir, '{}.{}'.format(uuid.uuid1().hex, _ext))
    out.save(result)
    return result
if __name__ == '__main__':
    print(handle('samples/images/fengjing.jpg', 'samples/images_result/', 1))
    print(handle('samples/images/renxiang.jpg', 'samples/images_result/', 2))


代码说明


1、handle方法可以将一张图片变为卡通化图片,入参为:图片路径、输出目录、类型(1为景色类型图片、2为人物人像图片)、设备类型(默认cpu,可以选择cuda)


2、按照我上一篇文章的测试,适合风景的模型和适合人像的模型不太一样,所以做了区分。


3、输出结果图片名字为了不重复,使用uuid。


验证一下


先发一下准备的图片



image.png


执行结果

image.png



效果如下



image.png


image.png


OK,没什么问题。


总结

整体效果还不错,最近在想要不要把操作过程录制成视频,可能会让人更好理解,只是不知道有没有必要,也征求一下意见,可以私信或者评论告诉我。


这个项目我还会改改,让输入变为视频不是更香吗?


分享:


       我想成为一个温柔的人,因为曾被温柔的人那样对待,深深了解那种被温柔相待的感觉。


                                                                                                       ·        ——《夏目友人帐》


如果本文对你有帮助的话,给个赞吧,谢谢!


相关文章
|
2天前
|
机器学习/深度学习 人工智能 自然语言处理
【机器学习】python之人工智能应用篇--代码生成技术
代码生成技术是人工智能与软件工程交叉领域的一项重要技术,它利用机器学习、自然语言处理和其他AI算法自动编写或辅助编写计算机程序代码。这一技术旨在提高编程效率、降低错误率,并帮助非专业开发者快速实现功能。以下是代码生成技术的概述及其典型应用场景。
15 6
|
2天前
|
机器学习/深度学习 人工智能 自然语言处理
【机器学习】python之人工智能应用篇——3D生成技术
在Python中,人工智能(AI)与3D生成技术的结合可以体现在多个方面,比如使用AI算法来优化3D模型的生成、通过机器学习来预测3D模型的属性,或者利用深度学习来生成全新的3D内容。然而,直接通过AI生成完整的3D模型(如从文本描述中生成)仍然是一个活跃的研究领域。 3D生成技术是一种通过计算机程序从二维图像或文本描述自动创建三维模型的过程。这一技术在近年来得到了飞速的发展,不仅为游戏、动画和影视行业带来了革命性的变革,还在虚拟现实、增强现实以及工业设计等多个领域展现出了巨大的应用潜力
7 2
|
2天前
|
机器学习/深度学习 人工智能 自然语言处理
【机器学习】python之人工智能应用篇--游戏生成技术
游戏生成技术,特别是生成式人工智能(Generative Artificial Intelligence, 简称Generative AI),正逐步革新游戏开发的多个层面,从内容创作到体验设计。这些技术主要利用机器学习、深度学习以及程序化内容生成(Procedural Content Generation, PCG)来自动创造游戏内的各种元素,显著提高了开发效率、丰富了游戏内容并增强了玩家体验。以下是生成式AI在游戏开发中的几个关键应用场景概述
6 2
|
3天前
|
机器学习/深度学习 JSON API
【Python奇迹】FastAPI框架大显神通:一键部署机器学习模型,让数据预测飞跃至Web舞台,震撼开启智能服务新纪元!
【8月更文挑战第16天】在数据驱动的时代,高效部署机器学习模型至关重要。FastAPI凭借其高性能与灵活性,成为搭建模型API的理想选择。本文详述了从环境准备、模型训练到使用FastAPI部署的全过程。首先,确保安装了Python及相关库(fastapi、uvicorn、scikit-learn)。接着,以线性回归为例,构建了一个预测房价的模型。通过定义FastAPI端点,实现了基于房屋大小预测价格的功能,并介绍了如何运行服务器及测试API。最终,用户可通过HTTP请求获取预测结果,极大地提升了模型的实用性和集成性。
13 1
|
13天前
|
机器学习/深度学习 自然语言处理 算法
【数据挖掘】金山办公2020校招大数据和机器学习算法笔试题
金山办公2020校招大数据和机器学习算法笔试题的解析,涵盖了编程、数据结构、正则表达式、机器学习等多个领域的题目和答案。
40 10
|
13天前
|
机器学习/深度学习 存储 人工智能
【数据挖掘】2022年2023届秋招知能科技公司机器学习算法工程师 笔试题
本文是关于2022-2023年知能科技公司机器学习算法工程师岗位的秋招笔试题,包括简答题和编程题,简答题涉及神经网络防止过拟合的方法、ReLU激活函数的使用原因以及条件概率计算,编程题包括路径行走时间计算和两车相向而行相遇时间问题。
35 2
【数据挖掘】2022年2023届秋招知能科技公司机器学习算法工程师 笔试题
|
13天前
|
机器学习/深度学习 数据采集 数据可视化
基于python 机器学习算法的二手房房价可视化和预测系统
文章介绍了一个基于Python机器学习算法的二手房房价可视化和预测系统,涵盖了爬虫数据采集、数据处理分析、机器学习预测以及Flask Web部署等模块。
基于python 机器学习算法的二手房房价可视化和预测系统
|
17天前
|
机器学习/深度学习 分布式计算 算法
【算法工程师】成为一名优秀的机器学习算法工程师所需知识及资料汇总-附思维导图
成为一名优秀的机器学习算法工程师所需要具备的技能和知识,包括理论基础、数学能力、编程技能、实践经验以及对特定领域的深入了解,并提供了学习资源和面试准备建议。
46 3
【算法工程师】成为一名优秀的机器学习算法工程师所需知识及资料汇总-附思维导图
|
2天前
|
机器学习/深度学习 算法 搜索推荐
【机器学习】机器学习的基本概念、算法的工作原理、实际应用案例
机器学习是人工智能的一个分支,它使计算机能够在没有明确编程的情况下从数据中学习并改进其性能。机器学习的目标是让计算机自动学习模式和规律,从而能够对未知数据做出预测或决策。
7 2
|
12天前
|
机器学习/深度学习 人工智能 算法
【数据挖掘】2022年2023届秋招奇虎360机器学习算法工程师 笔试题
本文提供了奇虎360公司2022年秋招机器学习算法工程师岗位的笔试题内容,包括选择题和编程题,涉及概率统计、数据结构、机器学习、计算机组成原理等多个领域。
38 5