March 12th, 2010

Simplicity and complexity


It’s a treat to occasionally read something that’s at the exact right level for me. Not talking about intelligence vs. stupidity — I’m talking about where I am in a learning curve. Everything we read starts with some assumption about what we already know, and it’s nice when this assumption gets it exactly right… starting slightly lower, so that we get a quick recap of the basics, can nod our heads in agreement, and then be ready to absorb the next thing.

But, I also like to read things that are not at my level, and I will tell you why.

If something is at too low of a level — let’s say a book about the basics of using a computer — I find it fascinating to see how this information is communicated to people who don’t have that basic understanding. It’s interesting to be reminded of what knowledge I take for granted, and even think of it in a different way. And it’s also helpful to get some perspective on what goes on in the mind of a person who doesn’t understand computers, so that I might learn to communicate better with those people.

If something is at too high of a level, I still can get something out of it. Reading stuff that’s too advanced helps to plant terms in my head. It’s very much like planting seeds; if I see terms frequently enough, I get a sense of them being important somehow. And then when the time has finally come to learn the meaning of that term, there is that much more satisfaction to it, and probably more retention. Off the top of my head, I’m having trouble thinking of a current example of this, but for a past example: I’m sure I heard/read the phrase “object oriented” a zillion times before ever writing my first class. The more instances there were of me hearing/reading “object oriented” and not having a clue what it meant, the more neurons were primed to joyfully fire off once the lightbulb switched on. In other words, the more I “tortured myself” by exposing myself to the unfamiliar term, the more exciting it was to finally learn it.

When I write posts like my previous one, the reactions tend to be along the lines of “I don’t understand a word of that”. And so it might help for me to try to tie my thoughts above to your experience reading this blog… which kind of centers around whatever creative breakthrough I’m having, or trying to have, at any given moment, and then occasionally goes way off topic so I can talk about my pets, or drop my two cents into the big political conversation.

I definitely don’t write in a way that I expect any reader to completely understand every word. That might seem off-putting, as if I don’t care whether you enjoy reading this or not, but that’s absolutely not the case here! I do try to write in a way that at least amuses you between the parts that make you scratch your head, and hopefully paints some more general overview of why I’m excited about what I’m doing. You might not understand what C++ code has to do with processing video images, but hopefully you can pick up on the feeling of freedom and liberation I get from building my own tools. You might not know what a sharp-ninth chord is, but hopefully you pick up on the idea that it’s a unique sound — and ultimately a unique feeling — that you can’t get from a straight major or minor chord. (Reading about a chord is one thing… but if you hear an unusual chord and like it, there’s no excuse for not finding out what it is so you can use it in your own songs!)

While I’m apparently very good at conveying how “complex” my interests are, I might be terrible at conveying how simple they also are, at least in my head — the point where an idea comes together and finally makes sense, and becomes useful and powerful. Complexity is just a middle stage in the development of a good idea:

1. SIMPLE (but unoriginal)
2. COMPLEX
3. SIMPLE (and original)

So if it still appears complex, then from your standpoint, I’m just not done yet. But from my standpoint, I’ve carved out this little section of code where I can do much more powerful things with the images, with very few lines of code. (And besides, I’m the one that’s going to be using the darn thing.) So, the point of my last post was, hey, I just created this tool that will help to make future toolbuilding quicker and more powerful. And I’m excited about it, and want to share that excitement.

I am NOT evangelizing that this is the path for you. I happen to have been experimenting with C++ code for audio and image manipulation since the turn of the century, was drawn into it on an emotional level (”there’s power in this stuff, I’m determined to sort it all out”, etc.), and I’ve created an ever-expanding arsenal of building blocks over that time. If you jumped into it cold, without patience or motivation — especially motivation — you would be dead stuck. The point for you is to take it as inspiration for some way in which you can create some kind of thing, system, or procedure that you will be able to benefit from, in a way that makes sense to you.

I have no idea what that would be, but I hope you make that connection.

Home-brewed “color spacing”


Note: apparently, not all the code below displays correctly via RSS.

Here’s a home-brewed way to get some of those expensive looking “color aware” effects.

In addition to the original hue/saturation/brightness components, I create six new variables each for hue, saturation, and value (brightness), plus six “weight” values, each corresponding with one of the six colors of a preschooler’s rainbow, ROYGBV (red, orange, yellow, green, blue — fuck “indigo”, but if you wanted me to take it seriously as a color, you should have taught it to me sooner — and violet, even though we called it “purple”):

double h, hueR, hueO, hueY, hueG, hueB, hueV;
double s, satR, satO, satY, satG, satB, satV;
double v, valR, valO, valY, valG, valB, valV;
double wR, wO, wY, wG, wB, wV;

Then at each pixel, you set up the “weight” values depending on what it’s closest to:

wR = wO = wY = wG = wB = wV = 0.0;
if (h >= 0 && h < = 21 ){wO = h /21.0; wR = 1.0 - wO;}
if (h > 21 && h < = 42 ){wY = (h - 21.0 )/21.0; wO = 1.0 - wY;}
if (h > 42 && h < = 85 ){wG = (h - 42.0 )/43.0; wY = 1.0 - wG;}
if (h > 85 && h < = 170){wB = (h - 85.0 )/85.0; wG = 1.0 - wB;}
if (h > 170 && h < = 212){wV = (h - 170.0)/42.0; wB = 1.0 - wV;}
if (h > 212 && h < = 255){wR = (h - 212.0)/43.0; wV = 1.0 - wR;}

Notice that it’s not just selecting one color and going with that; if it’s halfway between red and orange, the red weight would be 0.5, the orange weight would be 0.5, and all the other weights would be zero. After this point in the code, you’re now free to experiment with each value separately. For example, if you want to kill all saturation for the yellow areas, and just turn them grayscale, you would code it this way:

satY = 0;

Similarly, if I want to pump the heck out of the blue areas, I put a line like this:

satB *= 2;

(That’s C++ for “multiply by two”.)

Additionally, I “limit” the red saturation, so that it stays the same up to a point, but doesn’t go any higher; so that skin still looks the same, but bright red ribbons are muted:

if (satR > 96.0) satR = 96;

This example only plays with saturation. I could also mess around with brightness, contrast, etc. in the same way. After this designated “fun sandbox” section is the code that puts together the final values, using the “weight” values:

h = wR*hueR + wO*hueO + wY*hueY + wG*hueG + wB*hueB + wV*hueV;
s = wR*satR + wO*satO + wY*satY + wG*satG + wB*satB + wV*satV;
v = wR*valR + wO*valO + wY*valY + wG*valG + wB*valB + wV*valV;
setpixel(x, y, h, s, v);

I’m not sure exactly how this stacks up against the “color spacing” technology the big companies charge lots of money for, since like I said, it’s based on a Crayola-level color awareness. That considered though, it’s free in both senses of the word… free as in no expensive software to pay for, and free as in freedom to experiment on any of those 18 values with all kinds of math and logic before reducing them back to the original three components.

Much thanks to Darel Rex Finley, since I’m now using his HSP Color Model code to switch the images back and forth between RGB mode and HSP mode. “P” in this case is “perceived brightness”, and more psychovisually accurate than standard “V” or “L” values, but serves the same purpose. Check out his clear and well-illustrated HSP page for an explanation of the difference.

Is this thing on?


So, like, I’m supposed to be posting to this thing, right? Is that how it works?

The experts would probably suggest that I break my blogger’s block by shooting for ephemeral, disposable, and monk-like, and not trying to make each post a timeless work of art. I’d still like to have an amusing picture for every post — because reading is more enjoyable when there’s a pretty picture to lure you in — but that’s seriously a pain in the ass to do consistently. I could outline the extra steps here, but then I’d be subjecting you to the same torture.

So, after writing the previous paragraph, I put my jacket on, got in my car, and drove 1.8 miles out and back in icy, windy, finger-shattering weather, to pick up a latte. See? This is exactly what I’m talkin’ about, peoples. I can’t even write a danged blog post without interrupting it for something “important” — like a latte.

I suppose when you’re spending more and more time doing something that falls outside your previously defined identity, there’ll be some mental re-integration work to do. Right now, it’s about all the free hours eaten up by improv rehearsals. It’s all positive, but it does force me to ask questions like, “will I actually accomplish the other stuff I started?”

And the answer to that is, yes, that’s actually part of the reason I got involved in the first place.

Leonardo da Vinci would have coded in C++.


If I don’t post something now, I’ll never get back into the habit. Test one, test two. Hello!

Imhotep theme designed by Chris Lin (and then bastardized by the webmaster). Proudly powered by Wordpress.
XHTML | CSS | RSS | Comments RSS