幾何学的なプリミティブで画像を再現します。
ターゲット画像が入力として提供されます。アルゴリズムは、ターゲット画像と描画された画像の間のエラーを最小限に抑えるために描画できる単一の最も最適な形状を見つけようとします。このプロセスを繰り返し、一度に1つの形状を追加します。認識可能でありながら芸術的で抽象的な結果に達するには、約50〜200の形状が必要です。
ネイティブMacアプリケーションとして利用可能になりました!
https://primitive.lol/
Twitterで@PrimitivePicをフォローして、30分ごとに新しいプリミティブ画像をご覧ください!
Twitterボットは、Flickr APIを使用して興味深い写真を探し、ランダム化パラメーターを使用してアルゴリズムを実行し、Twitter APIを使用して画像を投稿します。
写真をボットにツイートすると、それがあなたのためにそれを処理します。
自分の画像で実行してください!まず、インストールします。
go get -u github.com/fogleman/primitive
primitive -i input.png -o output.png -n 100
小さな入力画像を使用する必要があります(256x256pxなど)。とにかく詳細は必要ありません。コードはより速く実行されます。
フラグ | デフォルト | 説明 |
---|---|---|
i | n/a | 入力ファイル |
o | n/a | 出力ファイル |
n | n/a | 形状の数 |
m | 1 | モード:0 =コンボ、1 =三角形、2 = rect、3 = ellipse、4 = circle、5 = rotatedRect、6 = beziers、7 = rotatedellipse、8 = polygon |
rep | 0 | 検索を減らして各反復を追加するnを追加します(主にbeziersに適しています) |
nth | 1 | すべてのn番目のフレームを保存します( %d 出力パスにある場合のみ) |
r | 256 | 処理する前に、このサイズに大きな入力画像をサイズ変更します |
s | 1024 | 出力画像サイズ |
a | 128 | カラーアルファ( 0 使用してアルゴリズムが各形状のアルファを選択できるようにします) |
bg | 平均 | 背景色の開始(ヘックス) |
j | 0 | 並列労働者の数(デフォルトはすべてのコアを使用します) |
v | オフ | 冗長出力 |
vv | オフ | 非常に冗長出力 |
提供される出力ファイル名拡張機能に応じて、さまざまな種類の出力を生成できます。
PNG
:ラスター出力JPG
:ラスター出力SVG
:ベクトル出力GIF
:追加されている形状を示すアニメーション出力-ImageMagick(特にconvert
コマンド)が必要ですPNGおよびSVG出力の場合、ファイル名に%d
、 %03d
などを含めることもできます。この場合、各フレームは個別に保存されます。
-o
フラグを複数回使用できます。これにより、たとえばPNGとSVGの両方を保存できます。
このGIFは、アルゴリズムの反復性を示しており、一度に1つの形状を追加することで平均の平方エラーを最小限に抑えようとします。 (「.gif」出力ファイルを使用して自分で生成してください!)
アルゴリズムにはランダムなコンポーネントがあるため、同じ入力画像に対して複数回実行して、寿命を静的画像に導くことができます。
コードに手を出そうとする場合は、形状の制約を強制して、さらに興味深い結果を生み出すことができます。ここでは、ピラミッドの夕日のこの写真では、長方形が太陽を指すように制約されています。
下のマトリックスは、それぞれ50、100、200の反復での三角形、楕円、長方形を示しています。
Target Image
あるとします。これが私たちが再作成に向けて取り組んでいるものです。空白のキャンバスから始めますが、単一の固体で満たします。現在、これはTarget Image
の平均色です。この新しい空白のキャンバスをCurrent Image
と呼びます。次に、形状の評価を開始します。形状を評価するために、 Current Image
の上に描画し、 New Image
作成します。このNew Image
スコアを計算するためにTarget Image
と比較されます。スコアにルート平均平方エラーを使用します。
Current Image + Shape => New Image
RMSE(New Image, Target Image) => Score
形状はランダムに生成されます。ランダムな形状を生成してスコアリングできます。その後、形状を変異させることができます(三角形の頂点を微調整し、楕円半径や中心を微調整するなど)。突然変異がスコアを改善した場合、私たちはそれを保持します。それ以外の場合は、前の状態にロールバックします。このプロセスを繰り返すことは、ヒルクライミングとして知られています。ヒルクライミングはローカルミニマイに閉じ込められる傾向があるため、実際にいくつかの異なるスターティングシェイプでこれほど多くの異なる時間を実行します。また、ヒルクライミングを開始する前に、nランダムな形を生成して、最高の形状を選ぶこともできます。シミュレートされたアニーリングももう1つの良い選択肢ですが、私のテストでは、少なくともこの特定の問題については、ヒルクライミングテクニックも同じくらい速くてもわかりました。
良いスコアの形状を見つけたら、それをCurrent Image
に追加し、そこで変更されません。次に、プロセスを再度開始して、次の形状を描画します。このプロセスは、何度も繰り返されます。
次のプリミティブがサポートされています。
次のインターフェイスを実装することにより、より多くの形状を追加できます。
type Shape interface {
Rasterize () [] Scanline
Copy () Shape
Mutate ()
Draw ( dc * gg. Context )
SVG ( attrs string ) string
}
このプロジェクトはもともと、ロジャー・ヨハンソンの人気のある優れた作品 - 遺伝子プログラミング:モナリサの進化に触発されました。その記事が非常に新しいときに見たので、私は長年にわたってあちこちでこの問題をいじくり回しました。しかし、今だけ、私は自分の結果に満足しています。
ロジャーの元の作品と比較して、私の実装には大きな違いがあることに注意する必要があります。鉱山は遺伝的アルゴリズムではありません。鉱山は一度に1つの形状でのみ動作します。鉱山ははるかに高速(AFAIK)であり、多くの種類の形状をサポートしています。
Flickrで見つかった興味深い写真のより多くの例を以下に示します。