Commit 3adf3e2d by BellCodeEditor

auto save

parent 4a991988
Showing with 115 additions and 7 deletions
from PIL import Image,ImageSequence import turtle
import random
import numpy as np
import torch
import torch.nn as nn
from PLT import Image
img = Image.open("dive.gif") class Painter(nn.Module):
num = 0 """智能画笔神经网络"""
for i in ImageSequence.Iterator(img): def __init__(self):
i.save(r"./img"+str(num)+".png") super().__init__()
num += 1 self.fc = nn.Sequential(
\ No newline at end of file nn.Linear(4, 128),
nn.ReLU(),
nn.Linear(128, 64),
nn.Tanh(),
nn.Linear(64, 3) # 输出: 笔压, 转向, 步长
)
def forward(self, inputs):
return self.fc(inputs)
class InkPaintingSystem:
def __init__(self):
self.screen = turtle.Screen()
self.screen.setup(800, 600)
self.screen.bgcolor("#F0EAD6") # 宣纸底色
self.pen = turtle.Turtle()
self.pen.speed(0)
self.pen.width(2)
self.pen.color("#2F1B0A") # 墨色
# 初始化神经网络
self.painter = Painter()
self.optimizer = torch.optim.Adam(self.painter.parameters(), lr=0.001)
# 风格参考图
self.style_img = self.load_style("style_sample.jpg")
# 绘画参数
self.stroke_count = 0
self.max_strokes = 500
# 启动绘画
self.paint()
turtle.done()
def load_style(self, path):
"""载入风格参考图"""
img = Image.open(path).convert('L').resize((64,64))
return torch.FloatTensor(np.array(img)/255.0)
def get_state(self):
"""获取当前状态特征"""
pos = self.pen.position()
angle = self.pen.heading()
return [
pos[0]/400, # 归一化坐标
pos[1]/300,
angle/360,
self.stroke_count/self.max_strokes
]
def style_loss(self, generated):
"""计算风格差异损失"""
gen_tensor = torch.FloatTensor(generated).unsqueeze(0)
return nn.MSELoss()(gen_tensor, self.style_img)
def paint_stroke(self, action):
"""执行绘画动作"""
pressure, angle_delta, length = action
self.pen.pensize(max(1, pressure*10))
# 应用动作
self.pen.setheading(self.pen.heading() + angle_delta*180)
target = self.pen.position() + \
self.pen.heading().to_vector() * length*100
# 水墨晕染效果
for _ in range(3):
self.pen.forward(length*20)
self.pen.pensize(self.pen.pensize()*0.9)
self.pen.penup()
self.pen.goto(target)
self.pen.pendown()
def paint(self):
"""主绘画循环"""
while self.stroke_count < self.max_strokes:
state = torch.FloatTensor(self.get_state())
action = self.painter(state) # 神经网络决策
# 执行绘画动作
self.paint_stroke(action.detach().numpy())
# 获取当前画布图像
canvas_img = self.get_canvas_image()
# 计算并反向传播损失
loss = self.style_loss(canvas_img)
self.optimizer.zero_grad()
loss.backward()
self.optimizer.step()
self.stroke_count += 1
def get_canvas_image(self):
"""获取当前画布图像"""
canvas = np.array(turtle.getcanvas().postscript()
.split("\n")[3:], dtype=np.uint8)
return Image.fromarray(canvas).convert('L').resize((64,64))
if __name__ == "__main__":
artist = InkPaintingSystem()
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment