1. AnimatedRotor
  2. Resolution 200.0
    1. 1
    2. 3
    3. 2
  3. Resolution 490.0
    1. 1
    2. 2
    3. 3
    4. 3.0
    5. 2.0
  4. Resolution 1200.0
    1. 1
    2. 2.0

AnimatedRotor

Paints a series of images, each to match the content of one while in the style of another using:
  1. Random noise initialization
  2. Standard VGG16 layers
  3. Operators to match content and constrain and enhance style
  4. Progressive resolution increase
  5. Rotational symmerty constraint caused by a kaliedoscopic image layer
  6. A content seed image to guide the aspect ratio
The parameters for each frame are fixed, but due to the random initialization and loose constraints we can achive a dynamic effect.

Color Permutations:

  1. Order: 1
    • 1,2,3
  2. Order: 2
    • -1,-3,-2
    • -3,-2,-1
    • -2,-1,-3
    • -1,-2,-3
    • 1,-2,-3
    • 1,-3,-2
    • -1,2,-3
    • -3,2,-1
    • 1,2,-3
    • 2,1,-3
    • -2,-1,3
    • -1,-2,3
    • 3,-2,1
    • 1,-2,3
    • -1,2,3
    • -1,3,2
    • 3,2,1
    • 1,3,2
    • 2,1,3
  3. Order: 3
    • -3,1,-2
    • -2,-3,1
    • -2,3,-1
    • 2,3,1
  4. Order: 4
    • -3,-2,1
    • -2,1,-3
    • -1,-3,2
    • 1,-3,2
    • -3,2,1
    • -2,1,3
  5. Order: 6
    • -2,-3,-1
    • 2,-3,1
    • -3,1,2
    • -2,3,1

Tiling Aspect Ratios:

  1. Triangular or Hexagonal: 1.732 or 0.5774
  2. Square: 1.0

Subreport: com.simiacryptus.mindseye.art.examples.AnimatedRotorEC2%24_b7130bd2-f241-4256-877f-862c64d3af8b_log_com.simiacryptus.ref.lang.ReferenceCountingBase

Code from AnimatedRotor.scala:71 executed in 0.00 seconds (0.000 gc):

    () => {
      implicit val implicitLog = log
      // First, basic configuration so we publish to our s3 site
      log.setArchiveHome(URI.create(s"s3://$s3bucket/$className/${log.getId}/"))
      log.onComplete(() => upload(log): Unit)
      ImageArtUtil.loadImages(log, styleUrl, (maxResolution * Math.sqrt(magnification)).toInt).foreach(x=>log.p(log.jpg(x, "Input Style")))
      log.p(log.jpg(ImageArtUtil.loadImage(log, contentUrl, maxResolution), "Input Content"))
  
      def frames = keyframes * 2 - 1
  
      val canvases = (1 to frames).map(_ => new RefAtomicReference[Tensor](null)).toList.toBuffer
      // Execute the main process while registered with the site index
      val registration = registerWithIndexGIF_Cyclic(canvases.map(_.get()).map(t => {
        val kaleidoscope = getKaleidoscope(t.getDimensions)
        val transformed = kaleidoscope.eval(t).getData.get(0)
        kaleidoscope.freeRef()
        transformed
      }))
      try {
        paintEveryOther(
          contentUrl,
          initUrl,
          canvases,
          (1 to frames).map(f => f.toString -> {
            new VisualStyleNetwork(
              styleLayers = List(
                // We select all the lower-level layers to achieve a good balance between speed and accuracy.
                VGG16.VGG16_0b,
                VGG16.VGG16_1a,
                VGG16.VGG16_1b1,
                VGG16.VGG16_1b2,
                VGG16.VGG16_1c1,
                VGG16.VGG16_1c2,
                VGG16.VGG16_1c3
              ),
              styleModifiers = List(
                // These two operators are a good combination for a vivid yet accurate style
                new GramMatrixEnhancer(),
                new MomentMatcher()
              ),
              styleUrls = Option(styleUrl),
              magnification = magnification,
              // Our optimization network should be built with a kaliedoscope appended to the canvas
              viewLayer = dims => getKaleidoscope(dims.toArray)
            )
          }).toList.toBuffer,
          new BasicOptimizer {
            override val trainingMinutes: Int = 60
            override val trainingIterations: Int = 10
            override val maxRate = 1e9
  
            // The canvas result should be processed by the kaliedoscope
            override def renderingNetwork(dims: Seq[Int]) = getKaleidoscope(dims.toArray)
  
            // By default, we use a trust region that constrains the canvas pixel values from 0-256.
            // This conflicts with using a kaliedoscope, whose output is bounded and input may be out of that range.
            override def trustRegion(layer: Layer): TrustRegion = null
          },
          (dims: Seq[Int]) => getKaleidoscope(dims.toArray),
          new GeometricSequence {
            override val min: Double = minResolution
            override val max: Double = maxResolution
            override val steps = AnimatedRotor.this.steps
          }.toStream.map(_.round.toDouble): _*)
        null
      } finally {
        registration.foreach(_.stop()(s3client, ec2client))
      }
    }

Returns:

    <function0>

Input Style

Input Style

Input Content

Resolution 200.0

1

Subreport: Optimization

3

Subreport: Optimization

2

Subreport: Optimization

Resolution 490.0

1

Subreport: Optimization

2

Subreport: Optimization

3

Subreport: Optimization

3.0

Subreport: Optimization

2.0

Subreport: Optimization

Resolution 1200.0

1

Subreport: Optimization

2.0

Subreport: Optimization