A Winter Break Exploration into AI-Driven Image Generation

We get a rather substantial winter break at SUNY Brockport, and I often use this time to do something “different”. This year, I wanted to explore image generation using AI (since everything AI is all the rage right now). Furthermore, I upgraded my computer recently and purchased a high(er) end graphics card. I got to thinking that running AI generation software locally might be a good test of my system, but needed a project. Then, I found this in my inbox:

I tend not to trust NY Times emails (if you trust blocked content, then any ads in the email are shown; however if I go directly to the website, my adblockers do their job). What is interesting is that the alt text for the image seems very AI-like. I wonder why a company focused on writing words needs to use an AI to generate a caption for an image they created (hopefully that is the case). It got me thinking: if they used AI to generate this caption, I would like to see what AI does with those words as a prompt to generate images.

I would not say that getting my computer set up for image generation was trivial; however, the documentation at huggingface has been extremely helpful with clear and concise examples. Knowing a bit of python – and knowing that ChatGPT can generate the code I don’t know, has made creating a simple locally-driven image generation app fairly straightforward.

Anyway, on to the results. I took the caption above and used that to prompt some image generation models. There are a bunch out there, including stable diffusion, open journey, and open dalle. I’ve got a version of each stored locally, and here’s what they came up with.

Continue reading

FeAtHEr-Cm update

Previously, I announced my latest project in The start of FeAtHEr-Cm. Over the past several weeks, I’ve been iterating through the potentiostat design and I think I’m at a point that the design will stay more or less in place, allowing me to shift my focus to documentation, instrument use and lesson plans.

I’ve also spent some time building a website that contains the documentation for building the instrument, writing code and using the potentiostat in an educational setting. Rather than re-write all of that information here, head on over to this page for a summary of what’s been done and what’s in the pipeline.

Example CVs from 0.01 to 0.5 V/s of potassium ferrocyanide in 0.1 M KCl at a 2 mm diameter Pt electrode. Obtained using the gamma version of the bob173 potentiostat.

BoBthebot Teaser

I’m working on creating a chatbot for Discord. Why? Well, in part because I want to, but also I’m trying to figure out if bots can be used to improve instructional delivery in Chemistry. I’ve got a way to go, but I’ve only been at it a week. My bot can’t converse very well, but it can integrate, provide weather forecasts and give you the nutritional information of peanut M&Ms. That’s something, I guess.

How deep are your pixels?

As I mentioned earlier, I just received my first Adabox, and I’ve been having fun getting back into blinky lights (as well as my favorite past time: procrastinating from grading). Now that I’ve gone through most of the tutorials, I am venturing out on my own.

One thing I noticed when playing around with drawing shapes of different colors, is that the default settings for the MatrixPortal resulted in the RGB LEDs being either on or off (essentially). My goal in this exercise it to figure out why that is the case and to find the settings that changed this behavior.

Once I learned how to navigate the documentation, it became clear that the bit_depth parameter was the culprit. It defaults to 2, which means that each color will have 4 different “shades” (my term), inclusive of completely on and completely off. Changing this value to a larger number (max = 6) allows for a deeper gradient.

Here’s the final version of the program I used to work through the problem.

import board # Required
import time
import displayio
from adafruit_display_shapes.circle import Circle
from adafruit_matrixportal.matrixportal import MatrixPortal

matrixportal = MatrixPortal(status_neopixel=board.NEOPIXEL,
    bit_depth=5, debug=False)
display = matrixportal.display

group = displayio.Group(max_size=32)

def makegroup(n):
    global group 
    group = displayio.Group(max_size=32)
    s = (8, 2048, 524288)
    for j in range(0,4):
        for i in range(0,8):
            group.append(Circle(i*8+4,4+8*j,2,fill=s[n]*(i+8*j)))

counter = 0

while True:
    makegroup(counter % 3)
    display.show(group)
    counter += 1
    time.sleep(3)
    

This code creates 32 filled circles on the 64×32 pixel matrix. The circles cycle through the three colors and increase in intensity from 00 (off) to FF (on). Rather than use more human readable (if you are a human that reads HTML color codes) colors, I noticed that a simple linear relationship with an appropriately chosen slope s, allows me to streamline the code.

Once we get to about half intensity (80 in hexadecimal), I have a hard time differentiating the colors. This might be helpful in future designs as it will allow me to back off on power requirements if I don’t need to run the LEDs with high current and deal with image saturation.

Sure, it’s not riveting; however, sometimes you need to work on the basics, and (hopefully) putting those basics to words helps me remember them.

post

Microwolf – running Mathematica on a Pi Zero

Wolfram’s Mathematica can run on a $5 Raspberry Pi zero. While it may be painfully slow, it does open up opportunities to use Mathematica in low-power, remote-sensing applications. This blog post is a first in a series highlighting the design challenges I’ve encountered (and in some cases overcome) building Mathematica on Pi (MoP) devices. (Hey, I think I just created a new acronym.)

Continue reading