時間が経つにつれて、デジタルコレクションの分野はますます熱くなっています。クリプトパンクのアバターがVisaに15万ドルで販売されたとき、人々はさまざまなチャネルを通じて徐々にNFTを知るようになりました。
方法論
このジェネレーターの背後にあるアプローチはシンプルです。さまざまな特性を組み合わせてユニークなアバターを作成します。
データを取得する
のリポジトリのデータをusetech-llc
使用します。"Substrapunks "
以下のリンクからリポジトリをダウンロードし、zip ファイルをローカル コンピュータに解凍します。
https://github.com/usetech-llc/substrapunks/archive/refs/heads/master.zip
インポートパッケージ
このプロジェクトでは次のパッケージを使用します。
ピル
IPython
ランダム
ジェイソン
OS
from PIL import Image
from IPython.display import display
import random
import json
import os
NFTプロパティの希少性を指定します
それぞれのユニークなアバターは 5 つの特徴で構成されています。
顔
耳
髪
口
鼻
希少性が重要なのは、それが希少性を生み出し、それが価値を生み出すからです。特徴内のさまざまなタイプに重みを割り当てることで、特徴の希少性を実現します。重みの合計は常に 100 になる必要があります。
顔は白と黒の2種類あります。プログラムでは、写真が白い顔を取得する確率が 60%、黒い顔が取得される確率が 40% であると規定できます。
# Each image is made up a series of traits
# The weightings for each trait drive the rarity and add up to 100%
face = ["White", "Black"]
face_weights = [60, 40]
ears = ["No Earring", "Left Earring", "Right Earring", "Two Earrings"]
ears_weights = [25, 30, 44, 1]
eyes = ["Regular", "Small", "Rayban", "Hipster", "Focused"]
eyes_weights = [70, 10, 5 , 1 , 14]
hair = ['Up Hair', 'Down Hair', 'Mohawk', 'Red Mohawk', 'Orange Hair', 'Bubble Hair', 'Emo Hair',
'Thin Hair',
'Bald',
'Blonde Hair',
'Caret Hair',
'Pony Tails']
hair_weights = [10 , 10 , 10 , 10 ,10, 10, 10 ,10 ,10, 7 , 1 , 2]
mouth = ['Black Lipstick', 'Red Lipstick', 'Big Smile', 'Smile', 'Teeth Smile', 'Purple Lipstick']
mouth_weights = [10, 10,50, 10,15, 5]
nose = ['Nose', 'Nose Ring']
nose_weights = [90, 10]
機能を分類する
辞書は、機能名をファイル名にリダイレクトするために使用されます。署名ファイル名は次の場所にあります。
...\substrapunks-master\scripts\face_parts\ 。
プロパティ名「White」は face1 に向けられ、「Black」は face2 に向けられます。
#Classify traits
face_files = {
"White": "face1",
"Black": "face2"
}
ears_files = {
"No Earring": "ears1",
"Left Earring": "ears2",
"Right Earring": "ears3",
"Two Earrings": "ears4"
}
eyes_files = {
"Regular": "eyes1",
"Small": "eyes2",
"Rayban": "eyes3",
"Hipster": "eyes4",
"Focused": "eyes5"
}
hair_files = {
"Up Hair": "hair1",
"Down Hair": "hair2",
"Mohawk": "hair3",
"Red Mohawk": "hair4",
"Orange Hair": "hair5",
"Bubble Hair": "hair6",
"Emo Hair": "hair7",
"Thin Hair": "hair8",
"Bald": "hair9",
"Blonde Hair": "hair10",
"Caret Hair": "hair11",
"Pony Tails": "hair12"
}
mouth_files = {
"Black Lipstick": "m1",
"Red Lipstick": "m2",
"Big Smile": "m3",
"Smile": "m4",
"Teeth Smile": "m5",
"Purple Lipstick": "m6"
}
nose_files = {
"Nose": "n1",
"Nose Ring": "n2"
}
画像のプロパティを定義する
作成する各アバターは、顔、鼻、口、耳、目の 6 つの画像を組み合わせたものになります。
したがって、これらの機能を 1 つのピクチャに結合し、ピクチャの総数を指定する for ループを作成できます。
関数は、各画像の特徴を指定する辞書を作成します。
これらの特徴はrandom.choice()
関数。
この関数は、顔の特徴 (白、黒) のリストを反復処理し、白 (確率 60%) または黒 (確率 40%) を返します。
## Generate Traits
TOTAL_IMAGES = 100 # Number of random unique images we want to generate
all_images = []
# A recursive function to generate unique image combinations
def create_new_image():
new_image = {} #
# For each trait category, select a random trait based on the weightings
new_image ["Face"] = random.choices(face, face_weights)[0]
new_image ["Ears"] = random.choices(ears, ears_weights)[0]
new_image ["Eyes"] = random.choices(eyes, eyes_weights)[0]
new_image ["Hair"] = random.choices(hair, hair_weights)[0]
new_image ["Mouth"] = random.choices(mouth, mouth_weights)[0]
new_image ["Nose"] = random.choices(nose, nose_weights)[0]
if new_image in all_images:
return create_new_image()
else:
return new_image
# Generate the unique combinations based on trait weightings
for i in range(TOTAL_IMAGES):
new_trait_image = create_new_image()
all_images.append(new_trait_image)
一意性の検証
NFT アバター プロジェクトの場合、各アバターが固有であることが重要です。したがって、すべての画像が一意であるかどうかを確認する必要があります。すべての画像をループしてリストに保存し、繰り返された画像を返す単純な関数を作成します。
次に、各画像に一意の識別子を追加します。
# Returns true if all images are unique
def all_images_unique(all_images):
seen = list()
return not any(i in seen or seen.append(i) for i in all_images)
print("Are all images unique?", all_images_unique(all_images))
# Add token Id to each image
i = 0
for item in all_images:
item["tokenId"] = i
i = i + 1
print(all_images)
特性カウント
特徴は、所定の重みとランダム関数に従って割り当てられます。これは、白い顔の重みを 60 と定義したとしても、ちょうど 60 の白い顔を持つことはできないことを意味します。各特徴の出現回数を正確に知るには、画像のコレクションに存在する特徴の数を追跡する必要があります。
これを行うには、次のコードを記述します。
0 から始まるそれぞれのカテゴリを使用して、各特徴の辞書を定義します。
作成した画像を循環し、特徴が見つかった場合は、それぞれの特徴辞書に追加します。
# Get Trait Counts
face_count = {}
for item in face:
face_count[item] = 0
ears_count = {}
for item in ears:
ears_count[item] = 0
eyes_count = {}
for item in eyes:
eyes_count[item] = 0
hair_count = {}
for item in hair:
hair_count[item] = 0
mouth_count = {}
for item in mouth:
mouth_count[item] = 0
nose_count = {}
for item in nose:
nose_count[item] = 0
for image in all_images:
face_count[image["Face"]] += 1
ears_count[image["Ears"]] += 1
eyes_count[image["Eyes"]] += 1
hair_count[image["Hair"]] += 1
mouth_count[image["Mouth"]] += 1
nose_count[image["Nose"]] += 1
print(face_count)
print(ears_count)
print(eyes_count)
print(hair_count)
print(mouth_count)
print(nose_count)
画像を生成する
これが最も驚くべき部分です。画像ごとに、スクリプトは次の処理を実行します。
特性を定義する画像特徴ファイルを開きます
PIL パッケージを使用して、ディレクトリ内の対応する特性イメージを選択します。
すべての特性を 1 つの画像に結合する
最も伝統的なカラー モデルである RGB に変換します。
コンピュータに保存します
#### Generate Images
os.mkdir(f'./images')
for item in all_images:
im1 = Image.open(f'./scripts/face_parts/face/{face_files[item["Face"]]}.png').convert('RGBA')
im2 = Image.open(f'./scripts/face_parts/eyes/{eyes_files[item["Eyes"]]}.png').convert('RGBA')
im3 = Image.open(f'./scripts/face_parts/ears/{ears_files[item["Ears"]]}.png').convert('RGBA')
im4 = Image.open(f'./scripts/face_parts/hair/{hair_files[item["Hair"]]}.png').convert('RGBA')
im5 = Image.open(f'./scripts/face_parts/mouth/{mouth_files[item["Mouth"]]}.png').convert('RGBA')
im6 = Image.open(f'./scripts/face_parts/nose/{nose_files[item["Nose"]]}.png').convert('RGBA')
#Create each composite
com1 = Image.alpha_composite(im1, im2)
com2 = Image.alpha_composite(com1, im3)
com3 = Image.alpha_composite(com2, im4)
com4 = Image.alpha_composite(com3, im5)
com5 = Image.alpha_composite(com4, im6)
#Convert to RGB
rgb_im = com5.convert('RGB')
file_name = str(item["tokenId"]) + ".png"
rgb_im.save("./images/" + file_name)
-コミュニティメンバーに参加するには、以下をクリックして原文を読んでください-