OpenAI GPT For Python Developers 第十章 图像分类与OpenAI CLIP

发布于 2023年11月25日

什么是CLIP?

CLIP或对比语言-图像预训练是一种高效的模型,它通过自然语言监督学习视觉概念。它可以应用于任何视觉分类基准,只需提供要识别的视觉类别的名称,类似于GPT-2和GPT-3的“零样本”能力。

目前,计算机视觉的深度学习方法存在一些挑战和问题,包括典型视觉数据集所教授的视觉概念有限,以及模型在压力测试上性能较差。根据OpenAI的说法,CLIP解决了这些问题。

这个神经网络在多样化的图像集上进行了训练,可以通过自然语言指导来执行各种分类任务,而无需明确优化任务。这种方法使模型能够推广到更广泛的图像范围,并在未见过的数据上表现更好,这被称为健壮性。根据OpenAI的说法,CLIP能够减小健壮性差距,最多减小75%,这意味着它可以正确分类传统模型可能难以处理的图像。

一个有趣的事实是,CLIP是通过结合以前的零样本学习和自然语言处理研究而开发的。

零样本学习是一种技术,允许机器学习模型识别新对象,而无需对这些对象的示例进行训练。这种方法已经通过使用自然语言来帮助模型理解它正在查看的内容而得到进一步发展。

2013年,斯坦福的研究人员使用这种方法训练了一个模型,根据人们用来描述这些对象的词语来识别图片中的对象。他们能够证明这个模型可以识别以前从未见过的对象。同年晚些时候,另一位研究人员在这项工作的基础上进行了改进,表明通过微调ImageNet模型来识别新对象是可能的。

CLIP模型建立在这项研究的基础上,以改进基于自然语言的图像分类任务,并帮助机器以更类似于人类的方式理解图像。您可以在官方博客文章 中了解更多关于CLIP的信息。

如何使用CLIP

我们将使用来自维基共享资源的公共领域图像,您可以在此页面找到它,还有其他图像。

或者,您可以使用以下命令直接下载图像:

wget -c https://upload.wikimedia.org/wikipedia/commons/d/d0/STS086-371-015_-_STS-086_-_Various_views_of_STS-86_and_Mir_24_crewmembers_on_the_Mir_space_station_-_DPLA_-_92233a2e397bd089d70a7fcf922b34a4.jpg

Windows用户可以使用cURL。

我们可以首先检查您的计算机是否具有CUDA兼容的GPU。

device="cuda" if torch.cuda.is_available() else "cpu"

如果有GPU可用,设备变量将设置为“cuda”,这意味着模型将在GPU上运行。如果没有GPU可用,设备变量将设置为“cpu”,这意味着模型将在CPU上运行。

CUDA是一个允许开发人员通过使用GPU进行并行处理来加速计算密集型进程的工具包。通过将计算工作负载卸载到GPU上,您可以减少执行这些任务所需的时间。CPU和GPU共同优化系统的处理能力。CUDA由NVIDIA创建。

接下来,让我们使用clip.load函数加载模型。此函数接受两个参数:

  • 要加载的模型的名称,

  • 要在模型上运行的设备。

模型名称是'ViT-B/32'。

model, preprocess = clip.load('ViT-B/32', device=device)

接下来,我们加载图像,对其进行预处理并使用CLIP模型进行编码:

# 加载图像

image = PIL.Image.open("../resources/ASTRONAUTS.jpg")

# 预处理图像

image_input = preprocess(image).unsqueeze(0).to(device)

# 使用CLIP模型对图像进行编码

with torch.no_grad():

    image_features = model.encode_image(image_input)

preprocess函数对输入图像应用一组标准图像变换(调整大小、归一化等),以准备将其输入CLIP模型。经过预处理的图像被转换为PyTorch张量,沿着第一个维度添加一个批处理维度,并移到设备(CPU或GPU),该设备由设备变量指定。

为了将图像输入CLIP模型,我们需要将其转换为张量。预处理函数返回一个已经以正确格式输入模型的张量,但它一次只处理一个图像。模型期望以批处理的形式输入图像,即使批处理大小只有一个。为了创建一个大小为一的批处理,我们需要在张量的第一个轴上添加一个额外的维度(也称为批处理轴)。这就是unsqueeze(0)方法的作用:它在索引0处向张量添加一个新维度。

简而言之,张量是数字的多维数组,而PyTorch张量是深度学习中使用的特定类型的张量。在我们的上下文中,输入图像是一个像素值的二维数组。

torch.no_grad()块用于确保不计算梯度,这可以提高性能并减少内存使用量。

在机器学习中,梯度是帮助优化神经网络的数学函数。PyTorch使用梯度来帮助训练模型。然而,当我们在这里使用CLIP模型进行编码时,我们不需要计算梯度,因为我们不是在训练模型。因此,我们使用with torch.no_grad()块来临时禁用梯度;这就是为什么计算性能会提高的原因。

当PyTorch跟踪计算图并存储中间结果时,它需要额外的内存和计算资源。通过使用with torch.no_grad(),我们可以减小内存占用并加速计算,因为PyTorch不需要存储中间结果或在此操作期间计算梯度。当对大量文本提示进行编码时,这可能特别重要,因为它可以提高性能并减少内存使用。

接下来,让我们定义一个文本提示列表:

# 定义文本提示列表
prompts = [
    "一个位于星座Bostes中的星团中心的大星系",
    "MTA长岛巴士刚刚离开了亨普斯特德巴士站的N6路线",
    "STS-86任务的专家弗拉基米尔·季托夫和让-卢克·克雷蒂安在BaseBlock中合影",
    "从联盟TMA-19太空船上观看国际空间站(ISS)的视图,因为它接近对接站",
    "笼子里的一只驯化的老虎,背后是一位老虎训练师",
    "一位机械工程师正在修理汽车发动机",
]

我们对文本提示进行编码:

# 使用CLIP模型对文本提示进行编码
with torch.no_grad():
    text_features = model.encode_text(clip.tokenize(prompts).to(device))

计算图像与每个提示之间的相似性:

# 计算图像与每个提示之间的相似性

similarity_scores = (100.0 * image_features @ text_features.T).softmax(dim=-1)

最后,我们打印具有最高相似性分数的提示:

# 打印具有最高相似性分数的提示
most_similar_prompt_index = similarity_scores.argmax().item()
most_similar_prompt = prompts[most_similar_prompt_index]

print("图像与以下提示最相似: {}".format(most_similar_prompt))

这是完整的代码:

import torch
import clip
import PIL

# 加载CLIP模型
device = "cuda" if torch.cuda.is_available() else "cpu"
model, preprocess = clip.load('ViT-B/32', device=device)

# 加载图像
image = PIL.Image.open("../resources/ASTRONAUTS.jpg")

# 预处理图像
image_input = preprocess(image).unsqueeze(0).to(device)

# 使用CLIP模型对图像进行编码
with torch.no_grad():

    image_features = model.encode_image(image_input)

# 定义文本提示列表
prompts = [

    "一个位于星座Bostes中的星团中心的大星系",

    "MTA长岛巴士刚刚离开了亨普斯特德巴士站的N6路线",

    "STS-86任务的专家弗拉基米尔·季托夫和让-卢克·克雷蒂安在BaseBlock中合影",

    "从联盟TMA-19太空船上观看国际空间站(ISS)的视图,因为它接近对接站",

    "笼子里的一只驯化的老虎,背后是一位老虎训练师",

    "一位机械工程师正在修理汽车发动机",

]

# 使用CLIP模型对文本提示进行编码

with torch.no_grad():

    text_features = model.encode_text(clip.tokenize(prompts).to(device))

# 计算图像与每个提示之间的相似性

similarity_scores = (100.0 * image_features @ text_features.T).softmax(dim=-1)

# 打印具有最高相似性分数的提示

most_similar_prompt_index = similarity_scores.argmax().item()

most_similar_prompt = prompts[most_similar_prompt_index]

print("图像与以下提示最相似: {}".format(most_similar_prompt))

请注意,您需要首先按照[官方Git存储库](https://github.com/openai/CLIP)的描述安装正确的依赖项。

conda install --yes-c pytorch pytorch=1.7.1 torchvision cudatoolkit=11.0 

pip install ftfy regex tqdm 
pip install git+https://github.com/openai/CLIP.git

反向稳定扩散:从图像到文本

使用CLIP构建的一些有用工具是CLIP Interrogator。

CLIP Interrogator是一个提示工程工具,它结合了OpenAI的CLIP和Salesforce的BLIP,用于优化给定图像的文本提示。生成的提示可以与文本到图像模型一起使用,例如[DreamStudio](https://beta.dreamstudio.ai/)上的Stable Diffusion,用于创建或再现图像。

使用方法简单明了:

from PIL import Image

from clip_interrogator import Config, Interrogator

image = Image.open(image_path).convert('RGB')

ci = Interrogator(Config(clip_model_name="ViT-L-14/openai"))

print(ci.interrogate(image))

请注意,您需要首先安装这些包:

# 安装带有GPU支持的torch,例如:
pip3 install torch torchvision --extra-index-url https://download.pytorch.org/whl/cu117

# 安装clip-interrogator
pip install clip-interrogator==0.5.4

BLIP是一个用于预训练模型以理解和生成图像和语言的框架。它在许多涉及视觉和语言的任务上取得了最先进的结果。

根据Salesforce的说法,BLIP在七个涉及视觉和语言的任务上实现了最先进的性能,包括:

  • 图像文本检索

  • 图像字幕生成

  • 视觉问题回答

  • 视觉推理

  • 视觉对话

  • 零样本文本-视频检索

  • 零样本视频问题回答

使用DALL-E生成图像

简介

使用深度学习技术,GPT模型可以基于提示或现有图像创建图像。

输入图像使用一组指令(算法)进行更改,以创建新图像。该模型可以根据其要处理的内容创建许多不同类型的图像,从简单到复杂不等。

其中一个强大的功能是它可以查看它创建的图像并更好地使它们更详细和准确。换句话说,它可以从自己的图像中学习,并随着时间的推移变得更加优秀。

总的来说,图像API提供三种与图像端点进行交互的方式:

  • 您可以根据文本提示从头开始创建图像。

  • 您可以根据新的文本提示对现有图像进行编辑。

  • 您可以创建提供的现有图像的不同变体。

近年来,OpenAI已经训练了一个名为DALL-E的神经网络,基于GPT-3。DALL-E是GPT-3的一个较小版本,具有120亿个参数,而不是1750亿个。它专门设计用于根据文本描述生成图像,使用了文本-图像对的数据集,而不是像GPT-3那样非常广泛的数据集。

要看它的实际效果,您可以使用DALL-E预览应用程序。

在本指南的这一部分中,我们将看到如何使用API而不是Web界面。

目前,速率限制设置为每分钟50张图像,但可以通过按照此帮助中心文章中的说明来增加。

从提示生成图像的基本示例

让我们从一个简单的示例开始:

import os
import openai

def init_api():
    with open(".env") as env:
        for line in env:
            key, value = line.strip().split("=")
            os.environ[key] = value
    
	openai.api_key = os.environ.get("API_KEY")
    openai.organization = os.environ.get("ORG_ID")

init_api()

kwargs = {
    "prompt": "一个美丽的风景。",
}

im = openai.Image.create(**kwargs)
print(im)

基本上,我们仍然遵循与以前相同的步骤:

  • 身份验证

  • 使用一组参数调用API端点。

在此示例中,我们将参数放在kwargs字典中,但这不会改变任何内容。执行上述代码后,您将获得类似以下的输出:

{
  "created": 1675354429,
  "data": [
    {
      "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-EDUZx9TXM1EWZ6oB5e49duhV/user-FloqMRrL7hkbSSXMojMpIaw1/img-MvgeSIKm0izdlr32ePzcAr8H.png?st=2023-02-02T15%3A13%3A49Z&se=2023-02-02T17%3A13%3A49Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2023-02-01T21%3A21%3A02Z&ske=2023-02-02T21%3A21%3A02Z&sks=b&skv=2021-08-06&sig=WWyNYn5JHC2u08Hrb4go42azmA8k0daPw2G%2BQV9Tsh8%3D"
    }
  ]
}

点击URL以打开图像。

生成多个图像

默认情况下,API返回单个图像,但您可以使用n参数一次请求多达10个图像。让我们尝试2张图像:

import os
import openai

def init_api():
    with open(".env") as env:
        for line in env:
            key, value = line.strip().split("=")
            os.environ[key] = value

    openai.api_key = os.environ.get("API_KEY")
    openai.organization = os.environ.get("ORG_ID")

init_api()
prompt = "一个美丽的风景."
n = 2

kwargs = {
    "prompt": prompt,
    "n": n,
}

im = openai.Image.create(**kwargs)
print(im)

请注意,我们可以直接使用以下方式打印图像URL:

for i in range(n):
    print(im.data[i].url)

使用不同大小

值得注意的是,生成的图像可以具有3种可能的大小:

  • 256x256像素

  • 512x512像素

  • 1024x1024像素

显然,尺寸越小,生成速度越快。

为了生成具有特定尺寸的图像,您需要将size参数传递给API:

import os
import openai

def init_api():
    with open(".env") as env:
        for line in env:
            key, value = line.strip().split("=")
            os.environ[key] = value

    openai.api_key = os.environ.get("API_KEY")
    openai.organization = os.environ.get("ORG_ID")

init_api()

prompt = "一个美丽的风景."
n = 1
size = "256x256"
kwargs = {
    "prompt": prompt,
    "n": n,
    "size": size,

}

im = openai.Image.create(**kwargs)
for i in range(n):
    print(im.data[i].url)

更好的图像提示

提示工程是一种利用人工智能来理解自然语言的方法。它通过将任务转化为提示并教导语言模型识别提示的方式运作。语言模型可以是一个已经训练好的大型模型,只需要学习提示即可。

在2022年,三个AI平台DALL-E、Stable Diffusion和Midjourney向所有人提供了使用。这些平台以提示作为输入,生成图像,这开辟了一个新的提示工程领域,专注于将文字转化为图像。

使用DALL-E,您可以自定义提示以满足您的口味和需求。从光线、艺术风格、氛围到位置和角度,有无穷无尽的可能性。

我们将查看其中一些示例,但我邀请您探索在线提供的许多其他资源,与这个主题相关,包括免费的[DALL·E 2提示词的书](https://dallery.gallery/the-dalle-2-prompt-book/)。一些以下提示是受到了DALL-E 2提示书的启发,其他一些则受到了多个其他来源,包括我的工作的启发。

模仿艺术家

这两个提示之间生成的图像有所不同:

提示="beautiful landscape"

提示="beautiful landscape by VanGogh"

显然,后者更有可能看起来像梵高的画作。

生成的图像可以是梵高的绘画、卡通风格的图像或抽象艺术品。请注意,您可以简单地使用逗号分隔的关键词:

提示="beautiful landscape , VanGogh"

例如,我们可以使用Agnes Lawrence Pelton的现代主义绘画风格。

提示="beautiful landscape by AgnesLawrence Pelton"

或者,采用Naruto背后的漫画家Masashi Kishimoto的风格:

提示="A teenager by MasashiKishimoto"

通过这种方式,您可以定制生成图像的风格以满足您的需求。

还可以使用与您想要的风格相关的其他关键词,不一定是艺术家:

提示="A teenager . Naruto manga style"

以下是一些艺术家、画家和摄影师的列表:

MohammedAmin

DorotheaLange

YousufKarsh

HelmutNewton

DianeArbus

EricLafforgue

AnnieLeibovitz

LeeJeffries

SteveMcCurry

DmitryAgeev

RosieMatheson

NancyGoldin

DavidLachapelle

PeterLindbergh

RobertMapplethorpe

DavidBailey

TerryRichardson

MartinSchoeller

JuliaMargaretCameron

GeorgeHurrell

AnselAdams

DorotheaLange

EdwardWeston

ElliottErwitt

HenriCartier-Bresson

RobertCapa

W.EugeneSmith

GarryWinogrand

DianeArbus

RobertFrank

WalkerEvans

RobertMapplethorpe

PabloPicasso

VincentVanGogh

ClaudeMonet

EdvardMunch

SalvadorDali

EdgarDegas

PaulCezanne

ReneMagritte

SoniaDelaunay

ZengFanzhi

VittoNgai

YojiShinkawa

J.M.W.Turner

GeraldBrom

JackKirby

Pre-Raphaelite

AlphonseMucha

CasparDavidFriedrich

WilliamBlake

WilliamMorris

AlbrechtDurer

RaphaelSanzio

MichelangeloBuonarroti

LeonardoDaVinci

ReneMagritte

模仿艺术风格

要模仿其他艺术风格,您还可以使用包含艺术风格和运动的关键词,如新艺术运动、印象派、抽象表现主义、奥菲斯主义、新古典主义等等!

新艺术运动(ArtNouveau)

印象派(Impressionism)

抽象表现主义(AbstractExpressionism)

奥菲斯主义(Orphism)

新古典主义(Neoclassicism)

立体主义(Cubism)

野兽派(Fauvism)

超现实主义(Surrealism)

表现主义(Expressionism)

达达主义(Dadaism)

波普艺术(PopArt)

极简主义(Minimalism)

后现代主义(Postmodernism)

未来主义(Futurism)

装饰艺术(ArtDeco)

早期文艺复兴(EarlyRenaissance)

宗教艺术(ReligiousArt)

中国艺术(ChineseArt)

巴洛克(Baroque)

尝试更多,使用这些解释不同艺术风格的其他关键词:

三维雕塑

漫画书

素描绘画

旧照片

现代照片

肖像

Risograph

油画

涂鸦

水彩画

赛博朋克

合成波

水粉画

铅笔绘画(详细、超详细、非常逼真)

粉彩画

墨水画

矢量

像素艺术

视频游戏

动画

漫画

插图

海报

排版

标志

品牌

蚀刻

木刻

政治漫画

报纸

着色表

野外日志线条

街头艺术

喷气

蜡笔

儿童绘画

帆布上的亚克力

铅笔绘画(彩色、详细)

浮世绘

中国水彩画

粉彩

企业孟菲斯设计

拼贴(照片、杂志)

水彩和钢笔

丝网印刷

低多边形

分层纸

贴纸插图

故事书

蓝图

专利图

建筑绘图

植物插图

剖面图

神话地图

福因奇手稿

宜家手册

科学图

说明手册

Voroni diagram

等距三维

织物图案

纹身

刮画

曼陀罗

马赛克

黑丝天鹅绒(埃德加·利特格)

角色参考表

复古迪士尼

皮克斯

1970年代颗粒状复古插图

吉卜力工作室

1980年代卡通

1960年代卡通

Atmosphere / Feelings / Vibes

通过添加描述氛围和一般氛围的其他关键词,您可以创建更具表现力的图像。

例如,您可以通过添加以下内容来唤起宁静的氛围:

提示="beautiful landscape with a peaceful atmosphere"

或通过添加以下内容来唤起神秘的氛围:

提示="beautiful landscape with a mysterious atmosphere"

同样,您可以唤起喜悦、悲伤、希望或恐惧的情感。

例如,为了唤起希望的感觉:

提示="beautiful landscape with a feeling of hope"

或唤起恐惧的感觉:

提示="beautiful landscape with a feeling of fear"

以下是一些您可以尝试的随机关键词:

light

peaceful

calm

serene

tranquil

soothing

relaxed

placid

comforting

cosy

tranquil

quiet

pastel

delicate

graceful

subtle

balmy

mild

ethereal

elegant

tender

soft

light

muted

bleak

funereal

somber

melancholic

mournful

gloomy

dismal

sad

pale

washed-out

desaturated

grey

subdued

dull

dreary

depressing

weary

tired

dark

ominous

threatening

haunting

forbidding

gloomy

stormy

doom

apocalyptic

sinister

shadowy

ghostly

unnerving

harrowing

dreadful

frightful

shocking

terror

hideous

ghastly

terrifying

bright

vibrant

dynamic

spirited

vivid

lively

energetic

colorful

joyful

romantic

expressive

bright

rich

kaleidoscopic

psychedelic

saturated

ecstatic

brash

exciting

passionate

hot

您可以模仿具有显着艺术风格的电影的风格/氛围,比如:

from Dancer in the Dark movie

from Howl's Moving Castle movie

from Coraline movie

from Hanna movie

from Inception movie

from Thor movie

from The Lion King movie

from Rosemary's Baby movie

from Ocean's Eleven movie

from Lovely to Look At movie

from Eve's Bayou movie

from Tommy movie

from Chocolat movie

from TheGodfather movie

from Kill Bill movie

from The Lord of the Rings movie

from Legend movie

from The Abominable Dr. Phibes movie

from The Shining movie

from Pan's Labyrinth movie

from Blade Runner movie

from Lady in the Water movie

from The Wizard of Oz movie

颜色

您还可以为生成的图像指定颜色。例如,如果您想要红色的天空,可以将关键词“red”添加到提示中:

提示="beautiful landscape with a red sky"

当然,您也可以使用其他颜色:

蓝色

红色

绿色

黄色

紫色

粉色

橙色

黑色

白色

灰色

红色和绿色

黄色和紫色

橙色和蓝色

黑色和白色

粉红色和青色

棕色和石灰色

栗色和紫罗兰色

银色和深红色

米色和紫红色

金色和天蓝色

青色和洋红色

石灰色和栗色和紫罗兰色

深红色和银色和金色

天蓝色和米色和紫红色

洋红色和青色和青色

粉红色和青色和石灰色

黄色和紫色和栗色

橙色和蓝色和紫罗兰色

黑色和白色和银色

褪黑色

褪白色

褪灰色

褪红色

褪绿色

褪蓝色

褪黄色

褪紫色

褪粉色

褪橙色

红色和绿色渐变

黄色和紫色渐变

橙色和蓝色渐变

黑白渐变

粉红色和青色渐变

棕色和石灰色渐变

栗色和紫罗兰色渐变

银色和深红色渐变

米色和紫红色渐变

金色和天蓝色渐变

青色和洋红色渐变

等等

您还可以使用提示词,例如:“6位颜色”,“8位颜色”,“黑白”,以及“像素化颜色”等。

提示="beautiful landscape with 6-bit color" 分辨率

您可以尝试不同的分辨率:

2位颜色

4位颜色

8位颜色

16位颜色

24位颜色

4k分辨率

HDR

8K分辨率

百万种颜色

十亿种颜色

角度和位置

您可以自定义场景的视图。例如,如果您想要一个风景的俯视图:

提示="美丽的俯视风景" 或者一个风景的第一人称视角:

提示="美丽的第一人称视角风景" 或者一个风景的广角视图:

提示="带有广角视图的美丽风景" 您可以尝试更多的关键词:

极端特写

特写

中景

远景

极远景

高角度

俯视图

航拍视图

倾斜的画面

荷兰角度

肩膀上的镜头

无人机视图

平移镜头

跟踪镜头

手推车镜头

变焦镜头

手持镜头

吊杆镜头

低角度

反向角度

视角镜头

分屏

定格画面

回忆

快速剪辑

淡入

淡出

镜头类型

您可以使用描述不同类型镜头或摄影技巧的关键词。例如,您可以使用“整理”来获得一个整洁有序的场景:

提示="整理的美丽风景" 或者使用“长焦镜头”来获得放大的视图:

提示="带有长焦镜头的美丽风景" 或者使用“鱼眼镜头”来获得极端广角视图:

提示="带有鱼眼镜头的美丽风景" 或者使用“倾斜移轴镜头”来获得微型化的视图:

提示="带有倾斜移轴镜头的美丽风景" 或者使用“360度全景”来获得全景视图:

提示="带有360度全景的美丽风景" 您还可以使用“无人机视图”来获得空中视图:

提示="来自无人机视图的美丽风景" 或者使用“卫星图像”来获得卫星视图:

提示="来自卫星图像的美丽风景" 这些是您可以尝试的其他关键词:

高分辨率显微镜

显微镜

大景镜头

针孔镜头

整理

第一人称视角

广角镜头

镜头畸变

超广角镜头

鱼眼镜头

全景

360全景

倾斜移轴镜头

望远镜镜头

镜头光晕

如果您熟悉摄影以及不同的设置,您也可以使用它们。以下是一些随机示例:

光圈:f/5.6,快门速度:1/250秒,ISO:400,风景摄影,高质量DSLR

光圈:f/8,快门速度:1/60秒,ISO:800,街头摄影,低光条件

光圈:f/11,快门速度:1/1000秒,ISO:1600,体育摄影,快速

快门速度

光圈:f/16,快门速度:2秒,ISO:100,夜间摄影,长曝光

光圈:f/2.8,快门速度:1/500秒,ISO:1600,野生动物摄影,高灵敏度,高ISO

光圈:f/4,快门速度:1/60秒,ISO:100,人像摄影,浅景深

光圈:f/5.6,快门速度:1/60秒,ISO:100,微距摄影,特写

光圈:f/8,快门速度:1/15秒,ISO:100,艺术摄影,柯达Gold200胶片色彩,35mm

光圈:f/11,快门速度:4秒,ISO:200,建筑摄影,慢快门速度,长曝光。

照明

您可以使用关键词更好地控制光线,这在摄影和艺术中是一个重要方面。以下是一些示例:

温暖照明

侧面照明

高键照明

荧光照明

强烈闪光灯照明

低键照明

平照明

均匀照明

环境照明

多彩照明

柔和光

硬光

漫射光

直射光

间接光

工作室照明

红绿照明

闪光灯摄影

自然照明

逆光

边缘照明

冷色

逆光

发光

中性白光

高对比度

灯光

烟花

2700K灯光

4800K灯光

6500K灯光

胶片类型和滤镜

您还可以指定要使用的胶片类型。例如,要获得“青色印相”效果,您可以添加关键词:

提示="具有青色印相效果的美丽风景" 或者,要获得“黑白”效果,您可以使用关键词:

提示="具有黑白效果的美丽风景" 而要获得“Kodak tri-X 400TX”效果,您可以使用关键词:

提示="具有Kodak tri-X 400TX效果的美丽风景" 尝试更多示例,如“曝光过度”,“棕褐色”和“单色”等。

柯达克罗姆

奥托克罗姆

洛摄影

拍立得

Instax

相机手机

CCTV

一次性相机

达盖尔罗

摄影机暗室

双重曝光

青色印相

黑白

Tri-X400TX

红外摄影

漂白旁路

联系单

彩色飞溅

太阳化

立体视觉

您还可以尝试Instagram滤镜的名称:

Instagram Clarendon 滤镜

Instagram Juno 滤镜

Instagram Ludwig 滤镜

Instagram Lark 滤镜

Instagram Gingham 滤镜

Instagram Lo-fi 滤镜

Instagram X-Pro II 滤镜

Instagram Aden 滤镜

Instagram Perpetua 滤镜

Instagram Reyes 滤镜

Instagram Slumber 滤镜

### 构建随机图像生成器

除了我们已经提到的内容之外,我们还有足够的提示来为机会提供机会,使用Python构建随机图像生成器。

我们将创建多个列表,每个列表包含不同的提示集。程序可以随机选择每个列表中的一个提示,并将它们与用户提示组合以创建一个单一的提示。

工作原理如下:

# 定义列表
list1 = [keywords11, keywords12, ..]
list2 = [keywords21, keywords22, ..]
list3 = [keywords31, keywords32, ..]
list4 = [keywords41, keywords42, ..]

# 读取用户提示
userprompt = "loremipsum"

# 生成一些随机提示
somegeneratedprompts = "userprompt"+"keywords11"+"keywords21"+"keywords31"+"keywords42"
"userprompt"+"keywords12"+"keywords22"+"keywords32"+"keywords41"
"userprompt"+"keywords21"
"userprompt"+"keywords32"
"userprompt"+"keywords21"+"keywords41"
"userprompt"+"keywords22"+"keywords42"
"userprompt"+"keywords31"+"keywords41"

让我们看看这是如何工作的:

import os
import openai
import random
import time

def init_api():

    with open(".env") as env:

        for line in env:

            key, value = line.strip().split("=")

            os.environ[key] = value

    openai.api_key = os.environ.get("API_KEY")

    openai.organization = os.environ.get("ORG_ID")

init_api()

artists = ["MohammedAmin", "DorotheaLange", "YousufKarsh", "HelmutNewton", "DianeArbus", "EricLafforgue", "AnnieLeibovitz", "LeeJeffries", "SteveMcCurry", "DmitryAgeev", "RosieMatheson", "NancyGoldin", "DavidLachapelle", "PeterLindbergh", "RobertMapplethorpe", "DavidBailey", "TerryRichardson", "MartinSchoeller", "JuliaMargaretCameron", "GeorgeHurrell", "AnselAdams", "DorotheaLange", "EdwardWeston", "ElliottErwitt", "HenriCartier-Bresson", "RobertCapa", "W.EugeneSmith", "GarryWinogrand", "DianeArbus", "RobertFrank", "WalkerEvans", "RobertMapplethorpe", "PabloPicasso", "VincentVanGogh", "ClaudeMonet", "EdvardMunch", "SalvadorDali", "EdgarDegas", "PaulCezanne", "ReneMagritte", "SoniaDelaunay", "ZengFanzhi", "VittoNgai", "YojiShinkawa", "J.M.W.Turner", "GeraldBrom", "JackKirby", "Pre-Raphaelite", "AlphonseMucha", "CasparDavidFriedrich", "WilliamBlake", "WilliamMorris", "AlbrechtDurer", "RaphaelSanzio", "MichelangeloBuonarroti", "LeonardoDaVinci", "ReneMagritte"]

art_styles = ["ArtNouveau", "Impressionism", "AbstractExpressionism", "Orphism", "Neoclassicism", "Cubism", "Fauvism", "Surrealism", "Expressionism", "Dadaism", "PopArt", "Minimalism", "Postmodernism", "Futurism", "ArtDeco", "EarlyRenaissance", "ReligiousArt", "ChineseArt", "Baroque", "ArtNouveau", "Impressionism", "AbstractExpressionism", "Orphism", "Neoclassicism", "Cubism", "Fauvism", "Surrealism", "Expressionism", "Dadaism", "PopArt", "Minimalism", "Postmodernism", "Futurism", "ArtDeco", "EarlyRenaissance", "ReligiousArt", "ChineseArt", "Baroque", "3Dsculpture", "Comicbook", "Sketchdrawing", "Oldphotograph", "Modernphotograph", "Portrait", "Risograph", "Oilpainting", "Graffiti", "Watercolor", "Cyberpunk", "Synthwave", "Gouache", "Pencildrawing(detailed,hyper-detailed,veryrealistic)", "Pasteldrawing", "Inkdrawing", "Vector", "Pixelart", "Videogame", "Anime", "Manga", "Cartoon", "Illustration", "Poster", "Typography", "Logo", "Branding", "Etching", "Woodcut", "Politicalcartoon", "Newspaper", "Coloringsheet", "Fieldjournallineart", "Streetart", "Airbrush", "Crayon", "Child'sdrawing", "Acryliconcanvas", "Pencildrawing(colored,detailed)", "Ukiyo-e", "Chinesewatercolor", "Pastels", "CorporateMemphisdesign", "Collage(photo,magazine)", "Watercolor&pen", "Screenprinting", "Lowpoly", "Layeredpaper", "Stickerillustration", "Storybook", "Blueprint", "Patentdrawing", "Architecturaldrawing", "Botanicalillustration", "Cutaway", "Mythologicalmap", "Voynichmanuscript", "IKEAmanual", "Scientificdiagram", "Instructionmanual", "Voroni diagram", "Isometric 3D", "Fabric pattern", "Tattoo", "Scratch art", "Mandala", "Mosaic", "Blackvelvet(EdgarLeeteg)", "Characterreferencesheet", "VintageDisney", "Pixar", "1970sgrainyvintageillustration", "StudioGhibli", "1980scartoon", "1960scartoon"]

vibes = ["light", "peaceful", "calm", "serene", "tranquil", "soothing", "relaxed", "placid", "comforting", "cosy", "tranquil", "quiet", "pastel", "delicate", "graceful", "subtle", "balmy", "mild", "ethereal", "elegant", "tender", "soft", "light", "muted", "bleak", "funereal", "somber", "melancholic", "mournful", "gloomy", "dismal", "sad", "pale", "washed-out", "desaturated", "grey", "subdued", "dull", "dreary", "depressing", "weary", "tired", "dark", "ominous", "threatening", "haunting", "forbidding", "gloomy", "stormy",

"doom", "apocalyptic", "sinister", "shadowy", "ghostly", "unnerving", "harrowing", "dreadful", "frightful", "shocking", "terror", "hideous", "ghastly", "terrifying", "bright", "vibrant", "dynamic", "spirited", "vivid", "lively", "energetic", "colorful", "joyful", "romantic", "expressive", "bright", "rich", "kaleidoscopic", "psychedelic", "saturated", "ecstatic", "brash", "exciting", "passionate", "hot", "fromDancerintheDarkmovie", "fromHowl'sMovingCastlemovie", "fromCoralinemovie", "fromHannamovie", "fromInceptionmovie", "fromThormovie", "fromTheLionKingmovie", "fromRosemary'sBabymovie", "fromOcean'sElevenmovie", "fromLovelytoLookAtmovie", "fromEve'sBayoumovie", "fromTommymovie", "fromChocolatmovie", "fromTheGodfathermovie", "fromKillBillmovie", "fromTheLordoftheRingsmovie", "fromLegendmovie", "fromTheAbominableDr.Phibesmovie", "fromTheShiningmovie", "fromPan'sLabyrinthmovie", "fromBladeRunnermovie", "fromLadyintheWatermovie", "fromTheWizardofOzmovie"]

colors = ["Blue", "Red", "Green", "Yellow", "Purple", "Pink", "Orange", "Black", "White", "Gray", "RedandGreen", "YellowandPurple", "OrangeandBlue", "BlackandWhite", "PinkandTeal", "BrownandLime", "MaroonandViolet", "SilverandCrimson", "BeigeandFuchsia", "GoldandAzure", "CyanandMagenta", "LimeandMaroonandViolet", "CrimsonandSilverandGold", "AzureandBeigeandFuchsia", "MagentaandCyanandTeal", "PinkandTealandLime", "YellowandPurpleandMaroon", "OrangeandBlueandViolet", "BlackandWhiteandSilver", "FadetoBlack", "FadetoWhite", "FadetoGray", "FadetoRed", "FadetoGreen", "FadetoBlue", "FadetoYellow", "FadetoPurple", "FadetoPink", "FadetoOrange", "GradientofRedandGreen", "GradientofYellowandPurple", "GradientofOrangeandBlue", "GradientofBlackandWhite", "GradientofPinkandTeal", "GradientofBrownandLime", "GradientofMaroonandViolet", "GradientofSilverandCrimson", "GradientofBeigeandFuchsia", "GradientofGoldandAzure", "GradientofCyanandMagenta"]

resolution = ["2bitcolors", "4bitcolors", "8bitcolors", "16bitcolors", "24bitcolors", "4k resolution", "HDR", "8K resolution", "a million colors", "a billioncolors"]

angles = ["Extremeclose-up", "close-up", "mediumshot", "longshot", "extremelongshot", "highangle", "overheadview", "aerialview", "tiltedframe", "dutchangle", "over-the-shouldershot", "droneview", "panningshot", "trackingshot", "dollyshot", "zoomshot", "handheldshot", "craneshot", "lowangle", "reverseangle", "point-of-viewshot", "splitscreen", "freezeframe", "flashback", "flashforward", "jumpcut", "fadein", "fadeout"]

lens = ["high-resolutionmicroscopy", "microscopy", "macrolens", "pinholelens", "knolling", "firstpersonview", "wideanglelens", "lensdistortion", "ultra-wideanglelens", "fisheyelens", "telephotolens", "panorama", "360panorama", "tilt-shiftlens", "telescopelens", "lensflare", "Aperture:f/5.6,ShutterSpeed:1/250s,ISO:400, Landscape photography, high-quality DSLR", "Aperture: f/8, Shutter Speed: 1/60s,ISO:800,Streetphotography,lowlightconditions", "Aperture:f/11,ShutterSpeed:1/1000s,ISO:1600,Sportsphotography,fastshutterspeed", "Aperture:f/16,ShutterSpeed:2s,ISO:100,Nightphotography,longexposure", "Aperture:f/2.8,ShutterSpeed:1/500s,ISO:1600,Wildlifephotography,highsensitivity,highISO", "Aperture:f/4,ShutterSpeed:1/60s,ISO:100,Portraitphotography,shallowdepthoffield", "Aperture: f/5.6, Shutter Speed: 1/60s, ISO: 100, Macro photography, close-upshots", "Aperture:f/8,ShutterSpeed:1/15s,ISO:100,Fineartphotography,KodakGold200filmcolor,35mm", "Aperture:f/11,ShutterSpeed:4s,ISO:200,Architecturalphotography,slowshutterspeed,longexposure."]

light = ["Warmlighting", "Sidelighting", "High-keylighting", "fluorescentlighting", "Harshflashlighting", "Low-keylighting", "Flatlighting", "Evenlighting", "Ambientlighting", "Colorfullighting", "Softlight", "Hardlight", "Diffusedlight", "Directlight", "Indirectlight", "Studiolighting", "Redandgreenlighting", "Flashphotography", "Naturallighting", "Backlighting", "Edgelighting", "Cold", "Backlit", "Glow", "Neutralwhite", "High-contrast", "Lamplight", "Fireworks", "2700Klight", "4800Klight", "6500Klight"]

filter = ["Kodachrome", "Autochrome", ...]  # 一些滤镜选项

lists = [colors, resolution, angles, lens, light, filter]

user_prompts = [

    "Happy Darthabilia.",

    "Darth Vader rapping with 2Pac.",

    "Darth Vader playing the piano.",

    "Darth Vader playing the guitar.",

    "Darth Vader eating sushi.",

    "Darth Vader drinking a glass of milk.",

]

n = 5

for user_prompt in user_prompts:

    print("Generating images for prompt: " + user_prompt)

    for i in range(n):

        customizations = ""

        for j in range(len(lists)):

            list = lists[j]

            choose_or_not = random.randint(0, 1)

            if choose_or_not == 1:

                customizations += random.choice(list) + ", "

        kwargs = {

            "prompt": user_prompt + ", " + customizations,

            "n": n,

        }

        print("Generating image number: " + str(i+1) + ". Using prompt: " + user_prompt + "," + customizations)

        im = openai.Image.create(**kwargs)

        print(im.data[i].url)

        print("\n")

        time.sleep(1)

    print("Finished generating images for prompt: " + user_prompt)

这是一个生成的图像的示例:

使用GPT DALL-E,可以编辑图像

图像编辑端点允许您通过上传遮罩来修改和扩展图像。

遮罩的透明部分明确定义了图像应该进行编辑的精确位置。用户应该提供一个带有描述的提示,以完成缺失的部分,包括删除的部分。

OpenAI文档提供的示例是不言自明的。

编辑图像的示例

让我们尝试一个示例。

在此之前,有一些要求,我们需要两张图像:

  • 原始图像

  • 遮罩

这两张图像应该以PNG格式保存,并且具有相同的尺寸。OpenAI对图像大小有4MB的限制。

图像也应该是正方形的。

我们将要使用的图像如下:

然后,使用图像编辑器,我们可以删除图像的一些部分并将其保存到文件中。确保图像具有透明层。删除的部分应该是透明的。

这是我们要使用的内容:

我将第一张图像命名为without_mask.png,第二张图像命名为mask.png,并将它们保存到一个文件夹中。

我希望模型使用遮罩编辑图像并在其中添加一群正在徒步旅行的人。这是如何做的:

import os

import openai

def init_api():

    with open(".env") as env:

        for line in env:

            key, value = line.strip().split("=")

            os.environ[key] = value

    openai.api_key = os.environ.get("API_KEY")

    openai.organization = os.environ.get("ORG_ID")

init_api() 

image = open("../resources/without_mask.png", "rb")

mask = open("../resources/mask.png", "rb")

prompt = "A group of people hiking in green forest between trees"

n = 1

size = "1024x1024"

kwargs = {

    "image": image,

    "mask": mask,

    "prompt": prompt,

    "n": n,

    "size": size,

}

response = openai.Image.create_edit(**kwargs)

image_url = response['data'][0]['url']

print(image_url)

让我们逐行看看代码做了什么:

  • 该代码打开位于目录../resources/中的两个图像文件,分别命名为without_mask.png和mask.png。在open函数中使用"rb"模式打开文件,以二进制模式打开文件是在读取图像文件时所需的。

  • 将prompt变量赋予一个字符串值,描述图像的内容。

  • 将n变量赋予整数值1,表示要生成的图像数量。

  • 将size变量赋予字符串值"1024x1024",指定生成图像的尺寸。

  • 创建一个字典kwargs,将键"image"、"mask"、"prompt"、"n"和"size"映射到存储在image、mask、prompt、n和size变量中的相应值。此字典将在调用openai.Image.create_edit函数时用作关键字参数。

  • 然后,调用openai.Image.create_edit函数,传递kwargs字典中提供的参数。函数的响应存储在response变量中。

  • 最后,从响应字典中提取生成图像的URL,并将其存储在image_url变量中。

这就是我们需要做的一切。

API返回一个URL,但是我们可以通过更改response_format来以Base64格式编码获取它:

kwargs = {
    "image": image,
    "mask": mask,
    "prompt": prompt,
    "n": n,
    "size": size,
    "response_format": "b64_json",

}

从其他图像中汲取灵感

OpenAI使您能够生成同一图像的各种版本。您可以从另一幅图像中汲取灵感来创建新图像。该图像可以是您自己的作品,也可以是其他人的作品。在许多应用中,这个功能存在着版权问题;然而,这是一个我们在这里不讨论的单独话题。而且,考虑到我们正在学习和将图像用于个人和教育目的,我们不关心这些问题。

如何创建给定图像的变化。

该过程简单而直接。我们将使用Image模块调用模型并从变化端点请求新图像。

我们将从以下图像开始:

它是这样工作的:

import os

import openai

def init_api():

with open(".env") as env:

for line in env:

key, value = line.strip().split("=")

os.environ[key] = value

openai.api_key = os.environ.get("API_KEY")

openai.organization = os.environ.get("ORG_ID")

init_api()

image = open("../resources/original_image.png", "rb")

n = 3

size = "1024x1024"

kwargs = {

"image": image,

"n": n,

"size": size

}

response = openai.Image.create_variation(**kwargs)

url = response
  • 原始图像位于"../resources/original_image.png",以二进制模式打开open("../resources/original_image.png", "rb")。

  • 变量n设置为3,这意味着API将生成3个图像的变化版本。

  • 变量size设置为"1024x1024",指定输出图像的尺寸。

参数以键值对的形式存储在字典kwargs中,然后使用*kwargs语法传递给openai.Image.create_variation()方法作为关键字参数(正如我们在之前的示例中看到的,这允许该方法接收参数作为单独的关键字参数,而不是作为一个单一的字典)。

  • API的响应存储在response变量中,生成图像的URL存储在变量url中,url等于response。

输出应该类似于以下内容:

{

  "created": 1675440279,
  "data": [
    {
"url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-EDUZx9TX\ M1EWZ6oB5e49duhV/user-FloqMRrL7hkbSSXMojMpIaw1/img-DOvDuO09yEJpIE1Mf3al7dEf.png?st=2\ 023-02-03T15%3A04%3A39Z&se=2023-02-03T17%3A04%3A39Z&sp=r&sv=2021-08-06&sr=b&rscd=inl\ ine&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-48\ 4e-a814-9c849652bcb3&skt=2023-02-03T10%3A35%3A56Z&ske=2023-02-04T10%3A35%3A56Z&sks=b\ &skv=2021-08-06&sig=/cHOniYCg1IumjM0z%2BxDvUWkqTkGAYqDmPvSRGwfQnQ%3D"
  }, {
"url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-EDUZx9TX\ M1EWZ6oB5e49duhV/user-FloqMRrL7hkbSSXMojMpIaw1/img-yAgytDsIrL63OGAz56Xe6Xt6.png?st=2\ 023-02-03T15%3A04%3A39Z&se=2023-02-03T17%3A04%3A39Z&sp=r&sv=2021-08-06&sr=b&rscd=inl\ ine&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-48\ 4e-a814-9c849652bcb3&skt=2023-02-03T10%3A35%3A56Z&ske=2023-02-04T10%3A35%3A56Z&sks=b\ &skv=2021-08-06&sig=isKlxpHhlECaGvWxz6P0nE%2BgsGIOO2Ekg8kmVkCAzKo%3D"
}, {
"url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-EDUZx9TX\ M1EWZ6oB5e49duhV/user-FloqMRrL7hkbSSXMojMpIaw1/img-nC9fq67dsztGTsshIR6cJJSn.png?st=2\ 023-02-03T15%3A04%3A39Z&se=2023-02-03T17%3A04%3A39Z&sp=r&sv=2021-08-06&sr=b&rscd=inl\ ine&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-48\ 4e-a814-9c849652bcb3&skt=2023-02-03T10%3A35%3A56Z&ske=2023-02-04T10%3A35%3A56Z&sks=b\ &skv=2021-08-06&sig=49qiOTpxCW/CKgqrsL7MXy/A3GqkN2PR1ccwtOH4o2A%3D"
  } ]
}

我们可以更新代码仅打印URL:

image = open("../resources/original_image.png", "rb")
n = 3

size = "1024x1024"
kwargs = {
"image": image,
"n": n,
"size": size
}

response = openai.Image.create_variation(**kwargs)

urls = response["data"]
for i in range(n):
  print(urls[i]['url'])

这是一个生成图像的示例:

图像变化的用途

这个功能的一个有用用例是,当您使用提示生成图像并找到正确的关键字组合以获得所需的图像但仍然想要改进时。

与其他AI图像生成和文本转图像工具相比,DALL-E有一些限制,因此有时需要花些时间找到正确的提示。当您找到时,可以使用多个变化来完善您的结果(生成的图像)。

这个功能还可以在编辑图像时使用,尽管结果可能不完全令人满意。在这种情况下,使用不同的变化可能会获得更好的结果。

因此,无论是创建生成图像的变化还是编辑图像的变化,这个功能可以与其他功能链接以获得更好的结果和更多的选择。



评论