博客主页:[小ᶻZ࿆] 本文专栏: AI绘画|Midjourney
文章目录
💯前言
【AI绘画】Midjourney进阶:对称构图详解 https://blog.csdn.net/2201_75539691?type=blog
【AI绘画】Midjourney进阶:三分线构图详解 https://blog.csdn.net/2201_75539691?type=blog
【AI绘画】Midjourney进阶:中心点构图详解 https://blog.csdn.net/2201_75539691?type=blog
【AI绘画】Midjourney进阶:留白构图详解 https://blog.csdn.net/2201_75539691?type=blog
- 在之前的文章中,我们深入探讨了构图在 Midjourney 中的核心作用。通过对称、三分线、中心点构图和留白构图,我们理解了如何利用视觉平衡、比例和位置,使画面更具表现力。今天,我们将重点探讨引导线构图,这是一种极具实用性的技巧。通过自然或人为的线条,巧妙地引导观众的视线,赋予作品更强的层次感和视觉流动性。这不仅能够增加画面的深度感,还能让作品在视觉上更具吸引力。无论是在风景绘画、建筑场景,还是人物作品中,引导线构图都能够帮助创作者实现更精致的画面布局。本文将详细解析这种构图方法,助你在 Midjourney 中更高效地运用引导线技术,创造出引人入胜的视觉效果。
Midjourney官方使用手册
💯什么是构图
构图是摄影、绘画、设计等视觉艺术中的一个基本概念。它指的是艺术家如何在二维平面上安排元素,包括形状、线条、色彩、质地、空间等,以达到一定的视觉效果和艺术表达。
为什么Midjourney要使用构图
- 简单来说,Midjourney有构图词画面质量更高
- 构图的目标是引导观众的视线,突出主题,增加视觉吸引I力,以及传达艺术家的观点或情感。
-
在Midjourney中使用构图是非常重要的,有两个方向可以解释其必要性:非共性和共性。
-
从非共性的角度来看,在Midjourney中使用构图相关的提示词可以显著提升生成画面的质量。这是因为Midjourney的模型在训练时,不仅使用了图像,还结合了与这些图像相关的提示词。通常来说,这些图像来源于专业摄影或高质量渠道,具有较高的视觉标准。当模型学习了这些图片与提示词之间的关联后,用户在生成图像时如果使用了构图相关的提示词,系统会优先选择类似图库中的优质素材,从而生成更为精致的画面。因此,通过使用构图提示词,可以明显地提高生成图像的质量。
-
从共性的角度来说,构图本身就是一种极为有效的手段,可以用于引导观众的视线、突出画面的主题、增强视觉吸引力,并传递创作者的情感和观点。构图所带来的这些视觉上的提升效果,是不受具体工具限制的,无论是在摄影、绘画还是AI生成图像中都是通用的。因此,当在Midjourney中使用构图提示词时,画面的质量提升几乎是必然的结果。这些道理或许听起来有些抽象,但在实际操作和练习时,大家会切实地感受到构图带来的效果提升。
-
💯引导线构图
引导线构图是一种常用技巧,它利用图像中的线条引导观者的视线,将注意力引向图片的主要焦点或者让眼睛在画面中流动。
-
引导线构图是一种非常实用的构图技巧,它通过利用图像中的线条来引导观众的视线,将他们的注意力自然引向画面的主要焦点。这种技巧不仅能够强化作品的视觉重点,还可以创造出一种流动感,使得观众的视线能够顺着线条在画面中移动,从而增加画面的层次感和深度。无论是在风景摄影、建筑设计,还是人物肖像中,引导线构图都能有效提升作品的表现力,帮助观众更好地理解创作者想要传达的主题。
-
为了更好地理解引导线构图的概念,我们来看几张示例图片。首先是一张风景图,公路从近处延伸到远方。通过道路两侧的边缘线以及道路中央的分隔线,观众的视线会自然而然地从画面前景引导至远处的风景。这种构图手法非常直观地展现了引导线的作用,将视线引向更为广阔的远景。
-
接着我们来看另一组建筑设计的图片。在这些画面中,建筑物的线条同样起到了引导视线的作用。通过建筑物的结构和线条,观众的目光会被引导在画面中流动,仿佛在空间中探索。这不仅使画面更具秩序感,也增加了视觉的层次感和延展性。
特点
-
引导视线
- 引导线能够有效地引导观众的目光,使他们的视线自然地沿着线条移动,进而突出画面中的重点元素。这种构图方式让观众的视线在画面中流动,从而增强作品的表现力。
- 引导线能够有效地引导观众的目光,使他们的视线自然地沿着线条移动,进而突出画面中的重点元素。这种构图方式让观众的视线在画面中流动,从而增强作品的表现力。
-
增加深度:
- 引导线,特别是有序排列的线条,能够为图片增添空间感,使二维的画面呈现出类似三维的效果。尤其是在建筑类作品中,不同线条的组合能够带来强烈的深度感和秩序感,使得整个画面更加立体、富有层次。
- 引导线,特别是有序排列的线条,能够为图片增添空间感,使二维的画面呈现出类似三维的效果。尤其是在建筑类作品中,不同线条的组合能够带来强烈的深度感和秩序感,使得整个画面更加立体、富有层次。
使用场景
-
首先,在风景摄影中,我们可以利用自然界中的线条作为引导线,比如山脉、河流或道路等元素。这些线条能够有效地引导观众的视线,深入到画面的远方,增强景物的层次感。
-
其次,在建筑摄影中,建筑物的线条、形状和结构同样可以作为引导线,帮助观众的目光在画面中流动。这种构图方式可以使建筑作品更具秩序感和空间感。
-
最后,在人像摄影中,模特的姿态、眼神甚至衣物的线条都可以成为引导线,吸引观众的注意力,强调人物的重点细节,增强照片的情感表达。
提示词书写技巧
- 在撰写提示词时,准确地使用引导线构图(
Guide Line Composition
)这一关键词非常关键。这一构图技巧通过线条的排列与设计,引导观众的视线沿着特定路径在画面中流动,最终聚焦在图像的重点区域。在提示词中加入guide Line Composition
,能够帮助AI生成的图像更好地体现视觉引导效果,强化画面的层次感和空间感。这一技巧广泛应用于风景、建筑以及人像摄影等领域,使生成的图像更具深度和视觉连贯性。
测试
原图:
landscape photography, mountains, valley, river, sunset, soft lighting, 8k, cinematic, wide angle --ar 16:9
- 原图展示的是自然风光的整体美感,主要以山脉、河流和夕阳为主,画面中的元素没有明显的引导,观众的视线在画面中可能会随机游走,无法集中在某一特定区域。画面虽然美丽,但缺乏明确的视觉焦点,层次感和纵深感相对较弱。
原图+guide Line Composition:
landscape photography, mountains, winding road, river, sunset, guide line composition, leading lines, cinematic, 8k, dramatic lighting, wide angle --ar 16:9
- 添加
guide line composition
后大大增强了视觉引导效果。通过蜿蜒的道路和河流作为引导线,观众的视线会自然地从画面前景延伸至远处,画面中的线条结构强化了纵深感,使得图像看起来更加有序和立体。同时,观众的目光被有效地引导至远方的风景,使得画面的层次更加分明,整体的视觉体验更具连贯性和冲击力。
💯小结
引导线构图作为一种重要的视觉表现手法,在Midjourney生成图像的过程中,能够显著提升画面的视觉效果和层次感。通过合理运用线条,将观众的视线自然而然地引向图像的主要焦点,不仅可以强化画面中的视觉重点,还能够创造出一种流动感,使图像看起来更加生动、有深度。在风景、建筑和人像摄影等场景中,引导线构图的运用都能帮助创作者实现更具吸引力的作品。这种构图技巧,结合了美学与技术,能够有效增强图像的视觉连贯性和表现力,尤其在使用Midjourney进行AI生成图像时,通过在提示词中添加相关的构图词汇,作品的质量和层次感可以得到显著提升。- 随着AI绘画技术的不断进步,构图技巧的应用将变得更加智能化和细致化。未来,AI不仅能够根据提示词生成高质量的图像,还会逐渐掌握艺术创作中的隐性规则,如情感表达、主题深度和视觉美学。通过不断优化对构图、光影、色彩等元素的理解,AI将能够更加精准地捕捉创作者的意图,甚至在无明确提示的情况下自主生成具有艺术性和内涵的作品。AI绘画的未来,不仅仅是工具的升级,更是艺术与技术深度融合的时代,它将拓宽人类艺术表达的边界,激发出更多富有创意与思考的视觉作品。
python
import torch, torchvision.transforms as transforms; from torchvision.models import vgg19; import torch.nn.functional as F; from PIL import Image; import matplotlib.pyplot as plt; class StyleTransferModel(torch.nn.Module): def __init__(self): super(StyleTransferModel, self).__init__(); self.vgg = vgg19(pretrained=True).features; for param in self.vgg.parameters(): param.requires_grad_(False); def forward(self, x): layers = {'0': 'conv1_1', '5': 'conv2_1', '10': 'conv3_1', '19': 'conv4_1', '21': 'conv4_2', '28': 'conv5_1'}; features = {}; for name, layer in self.vgg._modules.items(): x = layer(x); if name in layers: features[layers[name]] = x; return features; def load_image(img_path, max_size=400, shape=None): image = Image.open(img_path).convert('RGB'); if max(image.size) > max_size: size = max_size; else: size = max(image.size); if shape is not None: size = shape; in_transform = transforms.Compose([transforms.Resize((size, size)), transforms.ToTensor(), transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225))]); image = in_transform(image)[:3, :, :].unsqueeze(0); return image; def im_convert(tensor): image = tensor.to('cpu').clone().detach(); image = image.numpy().squeeze(); image = image.transpose(1, 2, 0); image = image * (0.229, 0.224, 0.225) + (0.485, 0.456, 0.406); image = image.clip(0, 1); return image; def gram_matrix(tensor): _, d, h, w = tensor.size(); tensor = tensor.view(d, h * w); gram = torch.mm(tensor, tensor.t()); return gram; content = load_image('content.jpg').to('cuda'); style = load_image('style.jpg', shape=content.shape[-2:]).to('cuda'); model = StyleTransferModel().to('cuda'); style_features = model(style); content_features = model(content); style_grams = {layer: gram_matrix(style_features[layer]) for layer in style_features}; target = content.clone().requires_grad_(True).to('cuda'); style_weights = {'conv1_1': 1.0, 'conv2_1': 0.8, 'conv3_1': 0.5, 'conv4_1': 0.3, 'conv5_1': 0.1}; content_weight = 1e4; style_weight = 1e2; optimizer = torch.optim.Adam([target], lr=0.003); for i in range(1, 3001): target_features = model(target); content_loss = F.mse_loss(target_features['conv4_2'], content_features['conv4_2']); style_loss = 0; for layer in style_weights: target_feature = target_features[layer]; target_gram = gram_matrix(target_feature); style_gram = style_grams[layer]; layer_style_loss = style_weights[layer] * F.mse_loss(target_gram, style_gram); b, c, h, w = target_feature.shape; style_loss += layer_style_loss / (c * h * w); total_loss = content_weight * content_loss + style_weight * style_loss; optimizer.zero_grad(); total_loss.backward(); optimizer.step(); if i % 500 == 0: print('Iteration {}, Total loss: {}'.format(i, total_loss.item())); plt.imshow(im_convert(target)); plt.axis('off'); plt.show()