文章目录
- 💯前言
- 💯为什么要学习光影控制
- 光影控制的作用
- 💯强化主题
- hard lighting(硬光 )
- soft lighting(软光/柔光)
- 测试
- 💯氛围营造
- 高对比度
- 强光与阴影
- 强光测试
- 阴影测试
- 暗调
- 测试
- 亮调
- 测试
- 增强视觉效果
- 测试
- 镜头光晕(补充)
- 测试
- 注意点
- 💯小结
💯前言
- 我们在之前的文章了解了常用的Midjourney的前置指令和后置指令,例如:
【AI绘画】Midjourney前置指令/settings设置详解
【AI绘画】Midjourney后置指令–seed、–tile、–q、–chaos、–w、–no详解 - 接下来本文将聚焦于Midjourney提示词的光影控制和灯光布置,解析如何通过光影的调节来增强Midjourney图片生成的画面效果。光影是提升作品氛围感和视觉冲击力的重要因素,学会这些技巧,将帮助你在使用Midjourney时创作出更加生动和富有情感的图像。
- Midjourney官方使用手册
💯为什么要学习光影控制
光影是图片语言的重要组成部分,光影是图片的基础和核心之一,它们决定了画面的氛围、感情以及结构,是表达创意和情感的重要工具。
- 对于很多AI绘画的爱好者来说,虽然可以通过提示词生成不错的作品,但由于缺乏系统的美术或摄影理论知识,总是难以达到专业效果。而光影正是提升作品质量的关键之一。
- 通过学习光影的运用,你将能更好地控制画面的视觉效果,营造不同的氛围,从而大幅提升作品的感染力。在AI绘画中,掌握光影的控制不仅能让图像更加生动、立体,还能使你的创作更具专业水准。
光影控制的作用
- 强化主题:我们可以利用明亮的光线或强烈的阴影来吸引观众的注意力,使他们更加专注于图像中的主题或主体,从而更好地凸显我们想要表达的内容。
- 氛围营造:光影可以用来表达各种情感和氛围。例如,暗淡的光影能够营造神秘或忧郁的情感,而明亮的光线则可以带来轻松和愉悦的感受。
- 增强视觉效果:通过巧妙地运用光影,可以创造出许多令人惊叹的视觉效果,使图像更加生动、引人注目。
-
首先,光影能够强化主题。通过明亮的光线或强烈的阴影,可以有效吸引观众的注意力,使其更专注于图像的主体,从而突出我们想要表达的核心内容。
-
其次,光影可以用于营造氛围。不同的光影效果能够传递出各种情绪。例如,暗淡的光影能够营造神秘或阴郁的氛围,而明亮的光线则可以带来轻松和愉悦的感觉。
-
最后,光影还能增强视觉效果。巧妙地利用光影,可以创造出令人惊艳的视觉效果,使画面更加引人入胜。
💯强化主题
- 在强化主题时,我们可以通过硬光或软光来塑造画面的主体。硬光与软光各有不同的特点和应用场景。
hard lighting(硬光 )
硬光是指光源发出的光线直接照射在被摄体上,没有经过任何散射或扩散。这种光线会在被摄体上产生明显的、边缘清晰的阴影。硬光的特点是对比度高,阴影部分和光线部分的界限十分明显,能够突出物体的质感和立体感。例如,中午的直射阳光就是一种典型的硬光。
- 首先,什么是硬光呢?硬光指的是光源发出的光线直接照射在物体上,未经过扩散或散射处理。这种光线会在物体上形成边缘清晰、对比度高的阴影。硬光的一个显著特点是,阴影部分和光线部分的界限非常分明,能够有效地突出物体的质感和立体感。比如正午的直射阳光,就是一种典型的硬光。
soft lighting(软光/柔光)
软光是指光线经过散射或扩散后照射在被摄体上。这种光线会在被摄体上产生边缘模糊、过渡自然的阴影,能够均匀地照亮场景,减少过度的对比和阴影,使得照片看起来更加柔和。例如,阴天的自然光和通过漫反射板反射的光就是典型的软光。
- 软光/柔光的特点在于,光线经过反射或散射后照射在物体上,会产生边缘模糊、过渡自然的阴影。这样的光线能够均匀地照亮整个场景,减少画面的对比度和阴影的强烈感,从而使照片看起来更加柔和。这种光影效果适合营造温暖、宁静的氛围,并且通常用于需要表达和谐、柔美感受的作品。
测试
- 接下来,我们将在相同的提示词和相同的种子数基础上,分别添加硬光(hard lighting)和软光(soft lighting)的提示词,通过生成的图像,能够更加直观地感受到光影控制对强化主题带来的视觉差异。
原图:
still life,perfume,simple background --seed 0909
- 原始图像展示了一系列香水瓶,布置在简单、优雅的背景之中。静物画风格突出,背景细节简洁,带有自然元素如水果、花卉等装饰。每个香水瓶的玻璃质感清晰展现,反射着自然柔和的光线,整体给人一种温暖宁静的氛围。这张图像强调了静物香水广告的典雅和简约,视觉效果平衡柔和,背景细腻而不抢眼。
hard lighting(硬光):
still life,perfume,simple background,hard lighting --seed 0909
- 在这张图像中,硬光照射在香水瓶及其周围的布置上,形成了明显的光影对比。强烈的光线使香水瓶和背景中的物体投射出锐利的阴影,边缘清晰。光线在香水瓶上的反射变得更加强烈,突出瓶身的立体感和光泽感,整个画面显得更有戏剧性和力量感,营造出一种高端奢华的视觉体验。
soft lighting(柔光):
still life,perfume,simple background,soft lighting --seed 0909
- 在这张图像中,软光使得整体光线更加柔和,光影过渡自然,阴影边缘模糊。光线均匀地照亮了香水瓶和周围的装饰,使画面显得更加温暖和优雅。香水瓶的反射不再那么刺眼,而是呈现出柔和的光泽,整个画面充满了和谐、舒适的感觉,突显出柔美和细腻的质感。
💯氛围营造
- 在氛围营造中,光影和色调是极为关键的因素,它们能够直接影响画面的情感表达。例如,在这张图片中,首先感受到的是一种悲怆、低沉、甚至带有些许阴郁的氛围。这种情感的传达很大程度上来源于画面的光影效果和整体的色调选择。
高对比度
- 高对比度的光线通常会产生更强烈、更明显的阴影,可以增强人像照片的视觉冲击力和艺术效果。
high contrast,light and dark(高对比度,光与暗):
high contrast,light and dark,portrait of 1 elegant girl,indoor,simple background
- 提示词“high contrast, light and dark”(高对比度,光与暗)两个提示词搭配使用。通过这些提示词,光影的强烈对比使画面整体效果显得更加突出。结合“portrait of 1 elegant girl, indoor, simple background”(一个优雅女孩的肖像,室内,简单背景),我们可以看到人物的面部被光线完美勾勒,背景简洁但富有深度感,充分展现了人物的立体感和情感张力。
- 相比普通的优雅女孩肖像,这里通过光影的强烈对比,塑造出了一种冷峻、高冷甚至带有些许神秘感的气氛。不同区域的明暗对比,使得整个画面具有了一种艺术化的视觉审美,提升了人像摄影的表现力和情感表达,营造出了一种更为高级、引人注目的氛围。这种光影的应用极大地丰富了视觉层次,使画面更具感染力和视觉冲击力。
强光与阴影
- 强光和阴影其实是一对辩证关系。强光必然会导致强烈的阴影,而强烈的阴影也正是由于强光的存在。这四个提示词可以放在一起进行比较:强光会带来明亮的高光和戏剧性的光线,而这些强光也必然会在画面中产生阴影效果,甚至出现阴影堆叠的现象。
强光测试
- bright high lighting 突出光的强度和色彩的表现力,而 dramatic light 则通过光影对比营造出戏剧化的视觉效果,使画面更具冲击力和艺术感。
- 接下来我们在相同的提示词基础上,分别添加 bright high lighting 和 dramatic light,能够更加直观地感受到两者对图像效果的不同影响。
bright high lighting(明亮的高光):
bright high lighting, still life of fruit and vase, simple background, studio lighting, vibrant colors
- 在这组图片中,bright high lighting 突出了强光对画面的塑造作用。光线以高强度照射在静物上,产生了鲜明的高光效果,尤其是在水果的表面和花瓶的反射区域。高光使得物体的色彩更加鲜艳,反射光极为明显,增强了图像的质感。阴影部分虽然存在,但相对较淡,整体画面更多的侧重于光线的表现,带来了清晰且明亮的视觉冲击。整个画面呈现出一种强烈的对比感,色彩明快,带来一种充满生机的氛围。
dramatic light(戏剧性的光线):
dramatic light,still life of fruit and vase, simple background, studio lighting, vibrant colors
- 相比之下,dramatic light 强调了光线的戏剧性效果,在光影对比上更加突出。画面中的明暗对比非常强烈,光线与阴影部分的交替变化塑造出了一种更具层次感和深度的效果。光线的集中照射在某些区域使得画面显得更加立体,而阴影部分也更为浓重,增加了画面的张力。整体氛围比明亮的高光版本显得更加沉稳和富有戏剧性,呈现出一种具有强烈艺术效果的静物画风格。
阴影测试
- shadow effect 强调了单一的阴影效果,增强了画面的深度,而 stack shadow 则通过层叠的阴影线条提升了画面的艺术表现力和视觉冲击力。
- 接下来我们在相同的提示词基础上,分别添加shadow effect和stack shadow,能够更加直观地感受到两者对图像效果的不同影响。
shadow effect(阴影效果):
shadow effect,still life of fruit and vase, simple background, studio lighting, vibrant colors
- 在这组图片中,shadow effect 强调了阴影在画面中的表现力。通过光影的巧妙运用,物体与背景之间产生了鲜明的对比,物体在光线的照射下投射出清晰的阴影。这些阴影不仅增加了画面的层次感,还为静物增添了艺术效果。画面中的水果和花瓶被强烈的光线照射,同时柔和的阴影部分使整体氛围显得更为真实和生动,阴影的存在增强了视觉的深度感和情感表达。
stack shadow(阴影堆叠):
stack shadow,still life of fruit and vase, simple background, studio lighting, vibrant colors
- 相比之下,stack shadow 提示词带来了更加复杂的光影效果。阴影在画面中呈现出层叠的效果,像一条条平行的线条,整齐地排列在物体后方。这种堆叠的阴影结构显得非常有秩序感,同时极大地增强了画面的艺术性。阴影的层次分明,增强了静物的立体感和深度。通过这种排列有序的阴影线条,画面呈现出了一种更加精致且富有张力的视觉效果,凸显出光影对于提升画面表现力的重要作用。
暗调
- 暗调的提示词有非常多,当然并不止这三个,这里只是举例。这三个提示词可用于描述或创建具有暗调氛围的场景,代表了不同类型的暗调风格,分别传达出情感化的阴暗、朦胧的雾气以及冷峻的光线效果。如果要在图像生成或创作中结合暗调,可以使用这些提示词来创造具有这些氛围效果的作品。
测试
moody darkness(忧郁感暗调):
moody darkness,portrait of 1 elegant girl,indoor,simple background
- 这张图片运用了 moody darkness 提示词,营造出一种低沉、压抑的氛围。光线较弱,整体画面呈现出暗调,使人物看起来更加沉静和内敛。背景简洁,焦点集中在女孩的面部表情上,传达出一种忧郁和冷静的情绪。这种暗调通过光影的控制,表现出了一种内在的情感,增强了画面的情绪表达。
Misty foggy(雾气朦胧):
Misty foggy,portrait of 1 elegant girl,indoor,simple background
- 在这张图片中,misty foggy 提示词为画面增加了一层薄雾,使得背景变得模糊不清,呈现出一种梦幻、朦胧的氛围。人物周围的雾气进一步强化了阴郁、神秘的效果,色调偏暗,光线柔和,给人一种柔美但又略显压抑的感觉。整体上,画面中的雾气与背景的融合,使人物的情感表达更加微妙,营造出了一种不确定的情绪氛围。
cold light(冷光):
cold light,portrait of 1 elegant girl,indoor,simple background
- 这张图片使用了 cold light 提示词,光线冷峻而清晰,色调明显偏冷(如蓝色调)。这种冷光带来了清冷、理性的氛围,女孩的面部表情显得更加冷酷和沉默。与前两个版本相比,冷光强调的是冷静和距离感,而非压抑或梦幻。光线的使用赋予了画面一种独特的寒冷感,使人物看起来更加稳重和冷静,情感表达更加内敛且理性。
亮调
- 亮调作为暗调的反面通常给人一种轻松、快乐和乐观的感觉。如果你想要传达这样的情绪,亮调拍摄会是一个很好的选择。
测试
Sun light(太阳光):
Sun light,portrait of 1 elegant girl,indoor,simple background,8k,high quality
- 这张图片展现了温暖的阳光洒在女孩的脸庞上,整个画面弥漫着一种生机勃勃的感觉。阳光为整个场景增添了柔和的金色调,使人物看起来更加温暖、明亮。背景虽然简单,但通过光影的运用,增强了画面的立体感和空间感。这种光线带来的视觉感受是温暖的、舒适的,传递出一种希望和积极的情绪。
Morning light(晨光):
Morning light,portrait of 1 elegant girl,indoor,simple background,8k,high quality
- 在这张图片中,morning light 提示词带来了柔和的晨光效果。光线透过窗户照射在女孩身上,营造出一种宁静、清新的氛围。晨光温和、轻柔,使人物显得更加自然,富有生命力。与太阳光相比,晨光更显得柔和平静,仿佛整个画面都在展现一个美好的早晨时刻,充满希望和温馨。
Golden hour light(黄金时段光):
Golden hour light,portrait of 1 elegant girl,indoor,simple background,8k,high quality
- Golden hour light 叫做金色小时光。在摄影领域有一个特定的时间,就是太阳下山之前那一小时的时间,那个时间是特别容易出片的,因为那个时间段的光影效果是特别能戳动人心的。添加Golden hour light后画面充满了柔和的金黄色光线。人物在这种光线下显得格外迷人,温暖的色调给人一种舒适而宁静的感觉。这个时间段的光线有一种独特的魔力,不仅赋予画面温暖感,同时也营造出一种内敛的美感和情感的深度。观众能强烈感受到夕阳的宁静和柔和。
Rays of shimmering light(微光):
Rays of shimmering light,portrait of 1 elegant girl,indoor,simple background,8k,high quality
- 在这张图片中,Rays of shimmering light 的提示词为画面带来了斑驳的光影效果。光线如星星般穿透物体,投射出轻柔的光斑,使画面显得更加梦幻和神秘。女孩的脸上透过微光的点缀,营造出一种静谧、优雅的氛围。这种光影效果像是自然的点缀,使画面充满了层次感,给人一种沉浸在宁静世界中的感觉。
warm light(暖光):
warm light,portrait of 1 elegant girl,indoor,simple background,8k,high quality
- Warm light 在这张图片中强调了柔和的黄色光线,画面整体呈现出温暖的色调。人物的表情和周围的环境都被暖光笼罩,给人一种安心、舒适的感觉。与冷光形成对比,暖光使整个画面显得更加亲切、温馨,充满了家庭般的温暖氛围。这种光影传达出的是温暖、幸福和安全感。
增强视觉效果
- 有时,我们需要让画面呈现出更强的视觉冲击力,以提升其艺术表现力。这时候就要用到增强视觉效果
测试
Rembrandt Lighting(伦勃朗光):
被摄者脸部阴影一侧对着相机,灯光照亮脸部的四分之三。以这种用光方法拍摄的人像酷似伦勃朗的人物肖像绘画
Rembrandt Lighting,portrait of 1 elegant girl,simple background,8k,high quality
- Rembrandt Lighting(伦勃朗光)是一种经典的打光方式,常用于肖像摄影。在这种光线下,人物的一侧面部被主光源照亮,而另一侧形成三角形阴影。这种打光方式赋予人物浓厚的立体感和戏剧性。你可以看到图片中的人物,脸部有一种柔和的光影过渡,塑造出一种优雅而内敛的气质,就像经典绘画中的人物形象一样,十分复古而庄重。
Volumetric lighting(体积光):
体积光,也被称为光柱或光束,是一种在特定环境条件下出现的光线效果。当光线通过包含一些悬浮颗粒(如尘埃、烟雾或雾气)的空气时,光线会被散射,形成可见的光束。体积光通常在有强烈光源并且空气中含有悬浮颗粒的环境中出现,例如,阳光穿过森林中的树叶,照射在雾气或尘土中;或者舞台灯光照射在烟雾中。
Volumetric lighting,forest,river,8k,ue5
- Volumetric lighting(体积光)通常用于描绘光束穿透空气中的颗粒或水气,创造出可见的光柱。在这张图片中,阳光透过森林的树叶洒在河面上,光线在水面和树叶之间散射,制造出一种神秘而唯美的氛围。这样的光线效果在游戏和电影中常见,给人一种宁静与神秘的自然之美。
Crepuscular Ray(圣光):
在宗教题材用的比较多。
Crepuscular Ray,8k
- Crepuscular Ray(圣光)是一种常见于宗教或神秘场景中的光效,光线从云层中穿透,给人以神圣降临的感觉。你可以在图片中看到从天空降临的一道道光束,仿佛是天上降临的神圣力量,整个场景充满了神秘与超现实的氛围,常用于强调神秘和宗教感的画面。
生物光(Bioluminescence):
生物发出来的光,用于烘托神秘、宁静的效果。
Bioluminescence,sea,forest,simple background,8k,high quality
- 生物光(Bioluminescence)是一种神秘而独特的光效,通常描绘的是自然界中生物自发光现象。在图片中,海岸线或森林中的蓝色光斑,仿佛是夜晚中的蓝藻或发光的生物,使得整个画面充满了梦幻和魔幻的色彩。这个效果常用于创造神秘、超自然的氛围,适合描绘奇幻场景。
电影光(Cinematic lighting):
是指在电影或电视制作中使用的专门灯光设备和技术。它的目的是创造出适合电影故事和视觉风格的光线效果。
Cinematic lighting ,portrait of 1 elegant girl,simple background,8k,high quality
- 电影光(Cinematic lighting)并不是特定的一种光效,而是一种强调画面质感和光线布置的艺术手法。通过电影般的打光方式,使得画面看起来更有层次感和故事性。在图片中,光线的布置让人物仿佛从电影画面中走出来,给人一种高雅、沉稳的感觉,具有很强的艺术美感和视觉冲击力。
front lighting(正面光):
正面光是指光源与摄像机的拍摄方向大致相同的情况。它可以使被摄体得到充分的照明,减少阴影,使被摄体的细节和色彩得到充分的展现。正面光的应用常见于新闻摄影、商业摄影及肖像摄影等场景,它能使人物面部细节得到清晰展现,也能使商品的颜色和质地看起来更鲜明。然而,正面光可能会使照片缺乏立体感和深度,因为阴影的缺失使得物体的形状和质地不易表现出来。
front lighting,portrait of 1 elegant girl,simple background,8k,high quality
- 在正面光条件下,光源和摄像机的方向大致相同,光线从正面照射到拍摄对象上。这种打光方式带来的效果非常平衡,画面没有明显的阴影,能清楚地看到主体的细节,整体感觉光线均匀而平和。图片中可以看到,模特的面部轮廓和皮肤质感非常清晰,突出了人物的美感与细腻的妆容,适合展现干净、精致的形象。不过,这种光线较为常见,虽然能表现出被摄对象的细节,但缺乏强烈的情感张力和艺术性。
back lighting(逆光):
逆光是指光源直接照射在相机镜头的方向。在这种情况下,被摄体通常会被边缘光线(也称为边沿光或逆光轮廓)勾勒出轮廓。逆光拍摄可以创造出强烈的对比、梦幻的氛围、增加深度和立体感。
back lighting,portrait of 1 elegant girl,simple background,8k,high quality
- 逆光是指光源从拍摄对象的背后照射,逆光照射的情况下,模特的轮廓会被一道亮光勾勒出来,特别是头发和肩部的部分。这样的打光效果往往能够形成梦幻、柔和的氛围,增加照片的层次感和立体感。图片中,模特的头发被逆光照亮,显现出轻盈的质感,同时也给整个画面增添了一种柔和、宁静的氛围。逆光还能强化情感的表达,适合用于营造浪漫、神秘或梦幻的场景。
镜头光晕(补充)
-
镜头光晕,虽然严格来说不属于传统的光影效果,但它在特定场景中确实可以增强视觉效果。在摄影或影视作品中,镜头光晕常常出现在对着强烈光源(如太阳或强灯光)拍摄时,光线进入镜头后形成的光晕现象。这种光晕效果带来一种视觉上的震撼力和真实感,尤其是在阳光充沛的场景中,增加了画面的氛围感。
-
在设计或创作中,镜头光晕有时通过后期特效或素材来添加。这种特效更多是为了增强某些场景的视觉冲击力,给人一种更强的代入感,而不是必须通过实际拍摄时的物理光线产生。因此,虽然镜头光晕本身不是光影的核心部分,但它的运用可以为画面带来独特的氛围,尤其是在自然光线较强的场景中,能够显得更加逼真和富有情感表达力。
测试
Lens flare(镜头光晕):
Lens flare,8k
- 在镜头光晕效果中,强烈的光源直接照射镜头,形成明显的炫光现象。图片中展示的光晕效果通过阳光穿透窗户、树枝或其他缝隙,使光源的强度和亮度变得更加突出,周围伴有柔和的光斑点缀。这种效果常用于增强光源的自然感或营造出梦幻的气氛,尤其是在电影或摄影场景中,能够增加画面的视觉冲击力和美感。
Radial lens flare(径向透镜光晕):
Radial lens flare,8k
- 径向透镜光晕是一种特殊的光晕效果,表现为从中央光源向外放射的圆形光线。图片展示了径向光晕从中央爆发出强烈的光束,并向外扩散,形成多层次的光环和反射光斑,带有非常规则的几何结构。这种径向光晕常被用于表现强烈光源的直接照射,特别是在强调对称性和聚焦效果的场景中,能很好地引导观众的视线。
注意点
- AI目前对光晕效果的理解仍存在一定的局限性。有时候,当我们使用较为复杂的光影提示词时,生成的结果可能不如预期理想。因此,在遇到这种情况时,建议大家多尝试不同的提示词,通过反复调整和测试,需要耐心与技巧才能得到理想的光影表现。
💯小结
-
在本文中,我结合个人在Midjourney AI绘画中的实践,分享了如何通过光影控制来提升作品的氛围和视觉效果。通过解析不同光影效果,如硬光、软光、体积光、镜头光晕等,我展示了这些技巧如何增强作品的主题表现力与情感表达。希望通过这些经验,能帮助读者更好地掌握光影运用,提升作品的艺术性与感染力。 -
展望AI绘画的未来,随着技术的不断进步,AI将变得更加智能和精确,不仅能够理解复杂的光影效果,还能自动融入艺术创作中最细腻的情感表达。AI绘画将从工具进化为创意伙伴,帮助艺术家突破传统技法的限制,自由探索各种风格与表达方式。未来的AI绘画可能会结合更先进的视觉算法,实时分析和学习人类创作的情感和意图,从而生成更加生动、富有层次感的艺术作品。通过这种人机协作,艺术创作的门槛将进一步降低,每个人都能够利用AI表达自己的独特视觉语言。光影等艺术元素也将被精确掌控,推动艺术创作进入一个全新的高度,使得艺术与科技的结合更加和谐,实现更加丰富的视觉表达和情感共鸣。
import torch;import torch.nn as nn;import torch.optim as optim;from torch.utils.data import Dataset, DataLoader;from torchvision import transforms, utils;from PIL import Image;import numpy as np;import cv2;import os;import random;class PaintingDataset(Dataset):def __init__(self, root_dir, transform=None):self.root_dir=root_dir;self.transform=transform;self.image_files=os.listdir(root_dir);def __len__(self):return len(self.image_files);def __getitem__(self, idx):img_name=os.path.join(self.root_dir, self.image_files[idx]);image=Image.open(img_name).convert('RGB');if self.transform:image=self.transform(image);return image;class ResidualBlock(nn.Module):def __init__(self, in_channels):super(ResidualBlock, self).__init__();self.conv_block=nn.Sequential(nn.Conv2d(in_channels, in_channels, kernel_size=3, stride=1, padding=1),nn.InstanceNorm2d(in_channels),nn.ReLU(inplace=True),nn.Conv2d(in_channels, in_channels, kernel_size=3, stride=1, padding=1),nn.InstanceNorm2d(in_channels));def forward(self, x):return x+self.conv_block(x);class Generator(nn.Module):def __init__(self):super(Generator, self).__init__();self.downsampling=nn.Sequential(nn.Conv2d(3, 64, kernel_size=7, stride=1, padding=3),nn.InstanceNorm2d(64),nn.ReLU(inplace=True),nn.Conv2d(64, 128, kernel_size=3, stride=2, padding=1),nn.InstanceNorm2d(128),nn.ReLU(inplace=True),nn.Conv2d(128, 256, kernel_size=3, stride=2, padding=1),nn.InstanceNorm2d(256),nn.ReLU(inplace=True));self.residuals=nn.Sequential(*[ResidualBlock(256) for _ in range(9)]);self.upsampling=nn.Sequential(nn.ConvTranspose2d(256, 128, kernel_size=3, stride=2, padding=1, output_padding=1),nn.InstanceNorm2d(128),nn.ReLU(inplace=True),nn.ConvTranspose2d(128, 64, kernel_size=3, stride=2, padding=1, output_padding=1),nn.InstanceNorm2d(64),nn.ReLU(inplace=True),nn.Conv2d(64, 3, kernel_size=7, stride=1, padding=3),nn.Tanh());def forward(self, x):x=self.downsampling(x);x=self.residuals(x);x=self.upsampling(x);return x;class Discriminator(nn.Module):def __init__(self):super(Discriminator, self).__init__();self.model=nn.Sequential(nn.Conv2d(3, 64, kernel_size=4, stride=2, padding=1),nn.LeakyReLU(0.2, inplace=True),nn.Conv2d(64, 128, kernel_size=4, stride=2, padding=1),nn.InstanceNorm2d(128),nn.LeakyReLU(0.2, inplace=True),nn.Conv2d(128, 256, kernel_size=4, stride=2, padding=1),nn.InstanceNorm2d(256),nn.LeakyReLU(0.2, inplace=True),nn.Conv2d(256, 512, kernel_size=4, stride=2, padding=1),nn.InstanceNorm2d(512),nn.LeakyReLU(0.2, inplace=True),nn.Conv2d(512, 1, kernel_size=4, stride=1, padding=1));def forward(self, x):return self.model(x);def initialize_weights(model):for m in model.modules():if isinstance(m, (nn.Conv2d, nn.ConvTranspose2d)):nn.init.normal_(m.weight.data, 0.0, 0.02);elif isinstance(m, nn.InstanceNorm2d):nn.init.normal_(m.weight.data, 1.0, 0.02);nn.init.constant_(m.bias.data, 0);device=torch.device("cuda" if torch.cuda.is_available() else "cpu");generator=Generator().to(device);discriminator=Discriminator().to(device);initialize_weights(generator);initialize_weights(discriminator);transform=transforms.Compose([transforms.Resize(256), transforms.ToTensor(), transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])]);dataset=PaintingDataset(root_dir='path_to_paintings', transform=transform);dataloader=DataLoader(dataset, batch_size=16, shuffle=True);criterion=nn.MSELoss();optimizerG=optim.Adam(generator.parameters(), lr=0.0002, betas=(0.5, 0.999));optimizerD=optim.Adam(discriminator.parameters(), lr=0.0002, betas=(0.5, 0.999));def generate_noise_image(height, width):return torch.randn(1, 3, height, width, device=device);for epoch in range(100):for i, data in enumerate(dataloader):real_images=data.to(device);batch_size=real_images.size(0);optimizerD.zero_grad();noise_image=generate_noise_image(256, 256);fake_images=generator(noise_image);real_labels=torch.ones(batch_size, 1, 16, 16, device=device);fake_labels=torch.zeros(batch_size, 1, 16, 16, device=device);output_real=discriminator(real_images);output_fake=discriminator(fake_images.detach());loss_real=criterion(output_real, real_labels);loss_fake=criterion(output_fake, fake_labels);lossD=(loss_real+loss_fake)/2;lossD.backward();optimizerD.step();optimizerG.zero_grad();output_fake=discriminator(fake_images);lossG=criterion(output_fake, real_labels);lossG.backward();optimizerG.step();with torch.no_grad():fake_image=generator(generate_noise_image(256, 256)).detach().cpu();grid=utils.make_grid(fake_image, normalize=True);utils.save_image(grid, f'output/fake_painting_epoch_{epoch}.png');def apply_style_transfer(content_img, style_img, output_img, num_steps=500, style_weight=1000000, content_weight=1):vgg=models.vgg19(pretrained=True).features.to(device).eval();for param in vgg.parameters():param.requires_grad=False;content_img=Image.open(content_img).convert('RGB');style_img=Image.open(style_img).convert('RGB');content_img=transform(content_img).unsqueeze(0).to(device);style_img=transform(style_img).unsqueeze(0).to(device);target=content_img.clone().requires_grad_(True).to(device);optimizer=optim.LBFGS([target]);content_layers=['conv_4'];style_layers=['conv_1', 'conv_2', 'conv_3', 'conv_4', 'conv_5'];def get_features(image, model):layers={'0': 'conv_1', '5': 'conv_2', '10': 'conv_3', '19': 'conv_4', '28': 'conv_5'};features={};x=image;for name, layer in model._modules.items():x=layer(x);if name in layers:features[layers[name]]=x;return features;def gram_matrix(tensor):_, d, h, w=tensor.size();tensor=tensor.view(d, h*w);gram=torch.mm(tensor, tensor.t());return gram;content_features=get_features(content_img, vgg);style_features=get_features(style_img, vgg);style_grams={layer: gram_matrix(style_features[layer]) for layer in style_features};for step in range(num_steps):def closure():target_features=get_features(target, vgg);content_loss=torch.mean((target_features[content_layers[0]]-content_features[content_layers[0]])**2);style_loss=0;for layer in style_layers:target_gram=gram_matrix(target_features[layer]);style_gram=style_grams[layer];layer_style_loss=torch.mean((target_gram-style_gram)**2);style_loss+=layer_style_loss/(target_gram.shape[1]**2);total_loss=content_weight*content_loss+style_weight*style_loss;optimizer.zero_grad();total_loss.backward();return total_loss;optimizer.step(closure);target=target.squeeze().cpu().clamp_(0, 1);utils.save_image(target, output_img)