【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的模型在训练时,不仅使用了图像,还结合了与这些图像相关的提示词。通常来说,这些图像来源于专业摄影或高质量渠道,具有较高的视觉标准。当模型学习了这些图片与提示词之间的关联后,用户在生成图像时如果使用了构图相关的提示词,系统会优先选择类似图库中的优质素材,从而生成更为精致的画面。因此,通过使用构图提示词,可以明显地提高生成图像的质量。
- 从共性的角度来说,构图本身就是一种极为有效的手段,可以用于引导观众的视线、突出画面的主题、增强视觉吸引力,并传递创作者的情感和观点。构图所带来的这些视觉上的提升效果,是不受具体工具限制的,无论是在摄影、绘画还是AI生成图像中都是通用的。因此,当在Midjourney中使用构图提示词时,画面的质量提升几乎是必然的结果。这些道理或许听起来有些抽象,但在实际操作和练习时,大家会切实地感受到构图带来的效果提升。
留白构图,也被称为负空间构图或空白构图。它的核心思想是在画面中留出大量的空白,通过这些空白来突出画面的主体,给予观众更多的想象空间。
- 通过大量的空白区域,留白构图将观众的视线自然地引向主体,使其更加清晰和引人注目。空白的存在反衬出主体的独特性,强化了画面的视觉焦点。
- 大面积的留白为观众提供了广阔的想象空间,使画面更具深度和趣味性。这种空间感赋予了作品一种可品味的层次,与传统国画中的美学理念相得益彰,鼓励观众在观看时进行更深层次的思考。
- 留白构图去除了多余的元素,使画面更加简洁、清晰。这种构图方式不仅让视觉呈现更为直观,还提升了画面的易读性,让观众可以轻松理解其意图。
- 通过使用留白构图,可以让人物的**面部表情和身体语言**更加突出,从而强化主体的表现力。
- 通过留白构图,可以**突出静物的特点和细节**,让观众更专注于画面的核心元素。
原图:
A vibrant pink lotus flower blooming in a pond, surrounded by green lily pads and other flowers, with water ripples and reflections, soft sunlight illuminating the scene, peaceful and natural setting --ar 16:9
原图+Negative Space Composition:
A vibrant pink lotus flower blooming alone with vast open space around it, minimal background details, soft shadows on a plain white surface, creating a calm and contemplative atmosphere, Negative Space Composition --ar 16:9
在探索Midjourney的构图技巧时,构图对画面质量的提升效果尤为显著。从对称构图、三分线构图到中心点构图,每一种构图方法都有助于引导观众的视线、突出主题、并传递情感。而留白构图,作为一种简洁、富有禅意的构图方式,更加突显了主体的独特性,为观众提供了广阔的想象空间。通过运用Negative Space Composition提示词,不仅可以让图像呈现出宁静的氛围,还能强化画面的视觉集中度,使作品更具深度和现代感。实践过程中,这种构图方式的简洁与空白感带来了独特的视觉张力,为作品赋予了更多可能性,也让我们更深刻地体会到构图在视觉表达中的重要作用。
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()