A few ways to quickly and automatically binarize an image

For my wife’s Spell To Write and Read (SWR) homeschooling we have a bunch of scanned worksheets.  A sample of the scanned image is shown below:

10letter_aandc

As you can see its entirely readable and fine for our purposes.  However it is not gentle on our laser printer toner budget.  What we really want is the background to be white, and the foreground to be black – nothing inbetween. This process is called binarization – and scanner software often has a feature that lets you do this during scantime.

We didn’t use that feature (or maybe our software didnt support it) at scantime. As such we need to resort to postprocessing. I have a Master’s in computer graphics and vision, and everytime I use something I learned the value of that degree goes up. It therefore behoves me to use it every chance I get.

As a good computer vision student, when I think binarization my mind jumps straight to Otsu!  He came up with a great way of automatically determining a good threshold value (meaning, when we look at each pixel in the image, everything below a value turns black, all else turns white).

My first thought is to check for an easy button somewhere. In gimp, for example, I found you can load the image, click on “Image -> Mode -> Indexed” then select “Use black and white (1 bit)”. Looks ok!

Now how to automate this, given I have 60+ images? Turns out there is a threshold option in imagemagick. I could go through each image in the directory and manually threshold, but I might get the threshold wrong, and I don’t really want to train my wife on picking a threshold value. Plus I know Otsu is better!

Turns out some guy named Fred has a bunch of ImageMagick scripts, including an Otsu one. I downloaded his script and ran it, yielding the following image:

10letter_aandc

Pretty nice – just black and white.  Thanks Fred… sorry I cannot call him “Fast Freddy” since it took around 18 seconds per image.  I know we can do better! Time to dust off those computer vision skills of Master.

Here’s what I came up with using python/opencv:


#!/usr/bin/python
import cv2
import sys
img=cv2.imread(sys.argv[1],0)
ret,imgThresh=cv2.threshold(img, 0, 255, cv2.THRESH_OTSU)
cv2.imwrite(sys.argv[2], imgThresh)

Short and sweet! And performance is way better: about 3 seconds per image.  But it looks like most of the program runtime is spent loading cv2.  Based on that assumption I decided to add a bulk processing mode:

import cv2
import sys
if len(sys.argv) == 1 or "-h" in sys.argv:
    print "Usage: %s [-inplace] image1 [image2 [image 3 ...]]"
    print " %s inImage outImage"
    sys.exit(0)
if "-inplace" == sys.argv[1]:
    inOut = [ (arg, arg) for arg in sys.argv[2:] ]
else:
    inOut = [ (sys.argv[1], sys.argv[2]) ]
for inImage, outImage in inOut:
    print "Converting %s to %s" % (inImage, outImage)
    img=cv2.imread(inImage,0)
    ret,imgThresh=cv2.threshold(img, 0, 255, cv2.THRESH_OTSU)
    cv2.imwrite(outImage, imgThresh)

When I run this script on the whole directory it takes an average of 2 seconds per image. Better, but longer than needed. What gives? It turns out I have all my data on a QNAP and opening, reading, and writing lots of files is not its forte. When I copy the data to my local SSD on the MAC, the cost per image is now 140ms. Much better.

Since, as often happens, I have found my assumptions totally flawed, can I vindicate Freddy? After rerunning the test it appears he is still a “steady Freddy” at about 2.7 seconds when running straight on the hard drive. Sorry Fred; opencv just beat the pants off you.

Using raspberry pi for two-way video/audio streaming

I am currently writing custom software to create a variety of distributed media solutions.  One of these involves a raspberry-pi security camera.  Right now my software isn’t finished, but I wanted to prove the concept out using existing software.  System requirements:

Raspberry pi:

  • Broadcast audio (over the LAN) to a server
  • Broadcast video (over the LAN) to a server
  • Receive (and play over the speaker) audio

Laptop:

  • Receive audio/video from the raspberry pi (and display it)
  • Send audio (from the laptop’s own microphone) to the pi.

I bought a raspberry pi b+, cheapo USB microphone, and IR camera (with built-in LEDs), and some speakers.  The whole package was around $100, which is just plain awesome.  Im sure my grandkids will marvel, 40 years down the road, that for the cost of an Obama-approved school lunch, I could buy so much.

Here’s a schematic of the setup:

design

This can be accomplished with a few scripts, which i based heavily on those found here: http://blog.tkjelectronics.dk/2013/06/how-to-stream-video-and-audio-from-a-raspberry-pi-with-no-latency/

Run the following on the pi:

function on_signal (){
    launch "kill -9 $piVideoPid $piAudioPid $osxAudioPid"
}
trap 'on_signal' EXIT

# Receive os x audio
gst-launch-1.0 -v udpsrc port=9102 caps=\"application/x-rtp\" ! queue ! rtppcmudepay ! mulawdec ! audioconvert ! alsasink device=plughw:ALSA sync=false &
osxAudioPid=$!

# Send pi audio
gst-launch-1.0 -v alsasrc device=plughw:Device  ! mulawenc ! rtppcmupay ! udpsink host=$broadcastIp port=$piAudioPort &
piAudioPid=$!

# Send pi video
raspivid -t 999999 -w 1080 -h 720 -fps 25 -hf -b 2000000 -o - |  gst-launch-1.0 -v fdsrc ! h264parse ! rtph264pay config-interval=1 pt=96  ! gdppay ! tcpserversink host=$localIp port=$piVideoPort

Run the following on the laptop (a macbook in my case).  Note if this were a linux box you would probably use “autoaudiosrc”.

function on_signal (){
    launch "kill -9 $piVideoPid $piAudioPid $osxStreamPid"
}
trap 'on_signal' EXIT

piIp=<raspberryPiIp>

# Stream OSX microphone (note the capsfilter, apparently needed due to os x bug)
launch "gst-launch-1.0 -v osxaudiosrc ! capsfilter caps=audio/x-raw,rate=44100 ! audioconvert ! audioresample ! mulawenc ! rtppcmupay ! udpsink host=$broadcastIp port=$macAudioPort" "ASYNC"
osxStreamPid=$!

# Receive audio
launch "gst-launch-1.0 -v udpsrc port=$piAudioPort caps="application/x-rtp" ! queue ! rtppcmudepay ! mulawdec ! audioconvert ! osxaudiosink" "ASYNC"
piAudioPid=$!

# Receive video
launch "gst-launch-1.0 -v tcpclientsrc host=$piIp  port=$piVideoPort ! gdpdepay ! rtph264depay ! avdec_h264 ! videoconvert ! autovideosink sync=false" "ASYNC"
piVideoPid=$!

echo "Waiting on $piVideoPid $piAudioPid $osxStreamPid"
wait

You should be able to see and talk to whoever is on the other end of the pi. Biggest problem is audio feedback, if the laptop and pi are close to one another.  I havent even begin to think about this, but the coolest things to note are:

  • You get a silky-smooth h264 video
  • The audio is acceptable
  • It works almost entirely using gstreamer.  The cool thing about that is gtreamer has a very easy programmatic API.  So… that makes my job easy when I get to that part of my project.

Enjoy!

FenBackup Through the Years

This is more of a tour of the past six years or so of various iterations of Fenimore backup solutions.

 

  • Solution 1.  Soon after I got married I found that between my wife and I we had around 1TB of movies, images, and documents from school.  We were also accruing around 5-10GB a week on family videos and pictures (hey, 1080p video cameras are readily available, and generate fairly big, hi-res videos).   Around Oct 2010 the price of 1.5TB drives was pretty low – around $80 each (this was right before the huge price spike a year or so later due to some disaster in the Pacific).  So I built a 3TB software-RAID 6 array with linux and a large tower.  I also had two 3TB RAID 5 arrays that plugged into hot-swap bays.  I periodically rotated these arrays to an offsite location.  By “periodically,” I mean it was every week or so for a month, then exponentially decayed to about once or twice a year towards the end.  backup_schemes
  • Solution 2. Enter the QNAP.  By this point I had upgraded to 3TB drives in my consolidated linux solution.  I took those drives out of my linux box and moved them into a 4-bay QNAP (TS-453 Pro).  I found that all of these 3TB WD Green drives started dying.  As I write this I am actually not sure what the heck happened, but soon I found myself buying some 5TB WD RED (NAS-grade) drives to replace the WD Greens.  These have worked much better.  This solution has also been nice because anytime I need to do work on my linux box or on the NAS it doesn’t take down my whole network.  It was also nice because I ended up making all my files accessible (in theory) via QNAPs cloud software.  The only flaw is that I tried to continue my offsite backup scheme wherein a drive was cycled to an offsite location; this actually was worse with QNAP, because QNAP doesn’t like the drives to be removed. backup_schemes2
  • Solution 3: Redundant QNAPs over VPN.  This is basically an upgrade to my QNAP solution where I bought a cheaper 2-bay QNAP.  The second QNAP fulfills my offsite backup goals. It sits on the other side of the country and is available 24/7 for my main qnap to push a copy of my data to it.backup_schemes3

Overall I’d say this solution is just about flawless.  It at least seems secure, works well, etc.  I found, for example, I could get to my files when I am not home.  I was even able to stream video from my qnap via PLEX to my laptop in my hotel; this turned out to be useful, for example, when my daughter wanted to watch tangled, which worked fairly well.

 

 

Key-based OpenVPN for OSX/Linux/QNAP Howto

I’ve had excellent luck setting up a key-based authentication VPN for my home network, which is distributed across the country and consists of Linux, Mac (OS X), and QNAP nodes.  What, you ask, does “key-based authentication” refer to?  It means that I do not allow people to enter passwords.  Instead, clients must possess the proper key, which is exchanged automatically by openvpn.   I think key-based authentication can be more secure in some cases, however I mainly wanted to do it “just because.”

Generally speaking the OpenVPN HOWTO is excellent and should suffice for setting up your VPN.  Ill briefly parrot this guide here.  To set things up you:

  • Pick a vpn network.  E.g. something that won’t conflict with any of the LAN networks of the nodes on your distributed network.  For example, one of my nodes sits on a 192.168.x.x/16 network, another sits on a 10.246.75.x/24 network, etc.  Pretty much anything, other than 10.246.75.x/24, from the 10.x.x.x/8 space can be used.
  • Generate keys:
    • From /etc/openvpn/easy-rsa run . ./vars
    • ./clean-all
    • ./build-ca  – basically accept everything as is, but remember the common-name for the server (as <servername>)
    • ./build-key-server <servername>
    • For each of my clients (i have 5 or 6): ./build-key <clientName>
    • Build the diffie-hellman stuff: ./build-dh
  • I chose to enable client-client communication, so I added the following in my server config:
    • client-to-client (to let clients talk to eachother)
    • push “redirect-gateway def1” (to redirect all traffic through my vpn)
    • client-config-dir /etc/openvpn/clients  (to let me specify static ips for all my clients).  For each client (identified by the common name, during the setup above, I create a like-named file with a single line like this:
      • ifconfig-push 10.9.1.22 10.9.1.23 (meaning this client will be accessible within the vpn via the 10.9.1.22 address)

On each client I scp’d over the ca, crt, key files, and made up a quick config script (based on the sample provided with openvpn).  I really only changed the following lines:

  • remote <hostname> <port> (this line has the hostname/port of your server)
  • ca /abs/path/to/vpn/directory/ca.crt
  • cert /abs/path/to/vpn/directory/fenimac.crt
  • key /abs/path/to/vpn/directory/fenimac.key

With that both the server and client should connect; all connected clients should have statically-assigned ips, and they should be able to talk to eachother.

What makes this a bit tricky is QNAP.  They only provide password-based authentication.  Thankfully you can just make a crontab to create the vpn connection, if its not up.  I made a script that looks something like:

VPNLOG=/mnt/HDA_ROOT/vpndir/vpn.log
if [[ `ps ax | grep openvpn | grep vpndir | grep -v grep` ]]; then
    echo "`date` Already running" | tee -a $VPNLOG
    ping -c 1 &lt;server'sVPNIp&gt;
    PINGRET=$?
    if [[ "0" = "$PINGRET" ]]; then
        echo "`date` Link is good!" | tee -a $VPNLOG
        exit 0
    else
        echo "`date` Link is down (ping gave $PINGRET) - killing current vpn" | tee -a $VPNLOG
        ps ax | grep vpndir | tr -s " " | cut -f 1 -d ' ' | xargs kill -9
    fi
fi
echo "`date` Run this thing!" | tee -a $VPNLOG
/usr/sbin/openvpn  --config /mnt/HDA_ROOT/vpndir/qnap.conf | tee -a $VPNLOG

A few important notes:

  • I run this script on the QNAP every couple minutes in a crontab.  Just editing crontab (“crontab -e”) doesn’t do the trick – qnap wipes those entries away upon reboot. To make this work, even across reboots, I followed a guide i found somewhere on the internet.  Basically you do the following:
    1. Edit /etc/config/crontab and add your custom entry.
    2. Run 'crontab /etc/config/crontab' to load the changes.
    3. Restart cron, i.e. '/etc/init.d/crond.sh restart'
  • I couldn’t get the vpn to stay up unless I turned on the vpn server inside the qnap.  It wasn’t my favorite thing to just leave that on, but for now im ok with it.

 

Avios Adventures

I had a chance to to head out to California on business and, in keeping with tradition, decided it would be fun to bring the family.  Work will pay for my flight, the hotel, and rental car, however it is up to me to get flights for the family.  Its precisely for moments like this that we like to keep 50-100 thousand points laying around, usually the result of a sign-up bonuses for credit cards.

This time around I had an arsenal of 100k southwest points, about 40k american airlines points, and 50k avios points.  I wanted to save the southwest points, so i focused on aa and avios.  Here’s what I did:

First, I looked for flights on avios and had mixed luck.   It turns out, as the “Points Guy” points out, that it is because the avios website doesn’t work well with multi-hop routes. In my case the route was IAD -> DFW -> SFO.  The trick is to look up the individual legs and book them separately.

BA.com showed that I could get three family members from IAD to DFW for 30,000 points, then with my remaining 20,000 i could get two people from DFW to SFO, meaning I’d have to pay for the third person for that leg.  Before booking i checked on prices and found that the price tag for DFW->SFO was $530!  In contrast, IAD to DFW was only $78.  I quickly switched the order, using 30k points to pay for the more expensive DFW->SFO leg  Then I booked 20k points for the IAD->DFW link for two members.

Things got a little interesting when I tried to buy tickets for my daughter (the third member of the IAD->DFW.)  Since she is under 16, AA.com would not let me book her alone.  Of course, she wasn’t alone, but aa.com doesn’t let you link her to another person on the same flight (which, incidentally, i had booked with ba.com).  So i called aa and, after bypassing the annoying robot, found a helpful lady.  She let me know she was waiving the $25 phone reservation fee, then helped link my daughter to my wife so she could get a ticket.

My opinion of avios is not so great, at least for cross-country domestic flights.  I ended up barely getting 50% as far as I would have with delta, aa, united, etc. for the same points.  To be fair to avios, I’ll just chock this up to ignorance on my part.  I think one can “work” avios better, but i didn’t find a way.  In the end, excluding 9/11 fees (which you always pay, regardless of your points program), the trip cost me around $78.  If I had purchased it on my own dime, it would have cost over $800 (excluding my flight, which is paid for by work).  This is why getting points is so worth it.

Based on my research avios just works “differently” than most other domestic programs (like aa or delta); avios are “distance based” – in theory they are fantastic for short-haul flights, since they charge less points than, say, aa might charge.  For example, i consider it standard to that 12.5k points gets one person one way in the US.  Since most credit cards that are worth getting have a 50k sign-on bonus, i expect to get two round-trip tickets per card.  In the end, with my 50k avios points, I got a family of three only MOST of the way from virginia to california.  Kinda crumby!  However if I were hoping from, say, virginia to new york, avios might charge less than the standard 12.5k points, and therefore be a better deal.  So the theory goes.

One last thing: I was planning on using aa points to fly back to virginia, but in order to align with flights allowed by work ended up having to go with southwest.   Before i decided on using southwest, i thought I would book with points from a pair of AA accounts.  Unfortunately I found I was short about 800 points in one of my aa accounts.  However,  I had an excess of several thousand points in another account.  AA lets you “share” points, but at an exorbitant (IMHO) cost.  To transfer 1000 points between accounts ended up costing over $30 ($12 for the 1000 points, and a flat $20 processing fee.)  sheesh!  But i now have the points where i need them, and can send my family in one direction anywhere in the USA.

So there you have it – a coast-to-coast trip for the whole family for under $100.

Ubiquitous Encryption with GPG

Because its easy, and because it provides so many benefits, i now try to use encryption everywhere. GPG is my tool of choice; i actually don’t even know what other options there are. Here are some things I have found to be useful:

  • Password management.  I use the pass application for this.  After installing gpg, i just do a “pass init <keyid>” and from there i am good to go.  I use qtpass as a graphical frontend.  The way this works is as follows: you add a password “pass insert blah”, which then asks you for the password to store.  Later you can ask for the password by typing “pass blah”. Storing passwords sure is a good idea, but even better is to just have pass generate good ones for you.  To do this i type “pass generate foobar 12” and a 12-char password is generated and stored.  Now i can have unique passwords for all my websites, and pass will remember them.  The one thing that weired me out is that after unlocking any password i could get at any others without entering my passphrase.  This worried me a bit because it looked like you only had to unlock things once and then they remained unlocked.  Turns out it was because gpg-agent is running and caching passwords for up to 10 min (default).  I figure its ok to leave things open for 10 min, in fact it would essentially mean if youre checking a lot of websites and you dont remember their passwords, you dont have to keep typing your passphrase over and over.
  • GPG also has great integration into mac os x.  I use this for mail and file encryption.  For mail, it lets me sign all my emails, regardless of where they go.  If the recipients are also using encryption, i can encrypt the messages.  When i receive an encrypted email i can decrypt it, etc.  Its literally 1-button email encryption for free.  Not bad!

As for my philosophy: “why encrypt?” I think the burden is more on people to answer: “why not encrypt?”  It takes almost no effort, and the benefit is that emails sent directly to you are no longer viewable by anyone else along their way.

Builtin Bookshelves

Last winter or so we decided to build bookshelves.   After much pondering we decided to make them built into the wall and have a window seat.   Here’s what we came up with (we never really got a good picture of it before leaving to the EC):

P1020674.JPG

Since this was my first woodworking project there was a fair amount of ramup.  I dedicated myself to the study of Norm Abram, watching as many New Yankee Workshop episodes as the Internet would yield unto me.

Step 1: Pedestal

The  process begin by pulling up the carpet and built a small platform of 2x4s.  This platform was needed to bring the shelves up high enough so the baseboard moulding could run under the shelves and connect up with the moulding on the connecting walls.

Step 2: Carcasses

Essentially the carcass is the cabinet / bookshelf – it forms the entire structure.  Virtually everything else is cosmetic.  This surprised me because people charge a ton for furniture work, but essentially you are just building boxes.  How’s that for a deprecating simplification of cabinet making!

Another surprise has to do with the building material.  Whenever I hear people talk about furniture it is clear that quality and hardwood are synonymous.  Yet all the guidlines for building furniture involve plywood.  How could this be?  It turns out plywood is stronger – much stronger – than using plain old hardwood.  And far less expensive.  I think I got my sheets of plywood for around $60 each.  The bulk of the cabinets were built for around $500 total!

One thing you appreciate from watching Norm Abram and others is joinery.  There are all kinds of ways to bind two peices of wood together: pocket screws, dowels, rabbet, mortise and tenon, etc.  I chose to join the carcasses with double rabbet joints.  To do this I bought a Diablo Dado Kit  for the table saw.  I passed the plywood edges through to take away half the width on each side.  I then glued the sides, held them in place with pipe clamps, and screwed them together.  As Norm would often say, the screws are not really there to hold the thing together – just to keep it from moving while the glue dried.  I think they do add strength, but they’re not the main source.

On that note, may i say: wood glue is amazing stuff.  I used a variety of glues: basically Tightbond II and Gorilla Glue.  Im not sure if Tightbond III would have made a difference – in looking at the bond strength, Tightbond II and III seemed about equal.  Essentially you’d have to be the incredible hulk to separate two fully-cured bonded pieces of wood.  The Gorilla Glue is also a  good option, but I didn’t find it any better (but it was more expensive).

Another amazing tool: the table saw.   Its the main tool to use in woodworking.  A few table saw truths now resonate with me:

  • The bigger the better.  Ideally you want to hold a full sheet of plywood on each side of the table saw.  Barring a big enough saw for that, at least buy a few roller stands to balance the plywood as you push it through
  • Buy a high-quality blade.  I tried using the stock blade that came with my Father-in-laws saw, and found it chipped the wood.  So I promptly went and bought a nice 90-some tooth diablo blade.  Cuts through the wood like butter!
  • Vacuum is essential.  You end up getting tons of sawdust in the air without a vacuum system.  I think even just using a shopvac is good – you can tape it into the output of the table saw.  Or just wear a mask.  The sawdust will get everywhere though.

To complete the boxes I glued in some 1/4″ plywood into a rabbet I had made to the back of the boxes (before joining them).

That brings me to my two main regrets about the carcasses:

  1. Not using 3/4″ for the backing.  I guess even 1/2″ would have been OK.  But building quality furniture just to skimp on the backing doesn’t make sense.  The only justification seems to be cost.  The 3/4″ white oak panels I got from home depot cost around $50 a sheet.  I think the 1/4″ panels were half that.  So all in all, I might have saved $100 total – big deal.   If I would have went with thicker backing I might have also been able to drill holes in it for supporting the middle of those large shelves, who knows.
  2. Not properly wiping glue of the carcasses.   Every woodworking tutorial mentions wiping the glue off once you’ve stuck the shelves together.  I did a good job at this later on, but not at first.    As a result there were parts of the shelves I had to vigorously sand just so the stain would apply evenly.  Just wipe it clean!

As can be seen below, I formed four carcases: 1) The left cabinet, with 1/3 of the window seat attached, 2) the left bookshelf, placed atop the left cabinet, 3) the right cabinet, and 4) the right bookshelf, also placed atop the right cabinet.  This left the middle section, which I finished after screwing the bookshelves to the pedestal.   To make that work, before bringing the caracses in I formed a rabbet on both the top and bottom edges of the window seat portions of the cabinet.  I also formed rabbets on two pieces of plywood.  I then slide one of the peices on the bottom of the middle area, and nailed it to the pedestal.  The other one went on top.

When this was all done I put another sheet of plywood on top of the window seat, to cover up the seams on the layer below.    When that was done I basically had the following:

 

P1070281 P1070089 P1070064

Step 3: Facade

I think they call this the face plate.  Its the only part that is actually solid hardwood.  I chose 3/4″ white oak from home depot.  It was fairly expensive – I’d say I spent at least as much on the faceplate as all the caracases, if not more.

I joined the faceplate using mortise and tenons.  I am proud to say I made a single faceplate for the bottom half that went from the left side of the room to the right .

To form the joints I used the table saw to form the tenons.  I used a drill press to form the mortises.  One note on that:  I bought a fairly cheap drill press, but it worked very well.  It just took a long time.  I investigated using mortising drill bits, however these really didnt make a ton of sense – the idea is they chisle as you go down.  Well, maybe that makes sense, but in the end the drill worked just fine.

Of course I applied copious glue in joining the mortise and tenon joints.  I also bought some pipe clamps to hold them in place as they dried.  A note on that: it is really important to let the glue dry in a warm room.  I tried doing it in the cold garage and found it didn’t dry at all.  I guess you have to follow the manufacturers recommendations – who knew!

I placed glue along the back of the faceplate and used finishing nails to hold it in place to the carcass.  Note again the nails really just hold it in place while the glue dries.

I also formed solid hardwood table tops for the bookshelves. Im not entirely sure why I did this.  Those things could hold a tank: two layers of 3/4″ plywood with a 3/4″ layer of hardwood.

Step 4: Shelves and Doors

The shelves are brain-dead easy.  I took plywood and cut some hardwood strips as a faceplate.  I then glued the faceplate to the hardwood, using a few finishing nails.  I filled the nail holes with putty.  Oh, and I did round the hardwood (before affixing it to the plywood) using some rounding bits on my router table.

As for the doors, this was the fancy part – the one that requires precision.  You have three elements to each door: stiles, rails, and panels.  The rails are the top part of the frame, the stiles are the sides, and the panel fills the middle.

For the panel I joined together three  6″ slabs of oak.  If I were Norm, and had his setup, I would have used a joiner to make sure the edges of the plywood were perfectly flat.  I don’t have joiner, but the stuff from Home Depot seemed pretty flat.  So I glued it together and clamped it tightly with some pipe clamps.

I then carefully measured, remeasured, marked the size of the panels.  It turns out you want the panel to float a bit inside of the rails/stiles.  You do this to allow for expansion in the panel.  The wood grain of the panel runs vertically.  Wood tends to expand with the grain, so the panels are supposed to be cut such that there is about 1/8″ wiggle room on each side.  Wood does not expand much against the grain, so only 1/16″ wiggle room is needed.

Cutting the panels wasn’t tricky, but it was a bit time consuming.  This is because I wanted to avoid ruining my router as it chomped through really thick wood with a big bit.  So i took two or three passes, each time getting closer and closer to the router bit.   I did end up burning the wood a bit on one panel, as can be seen below.

A note on router tables: I bought the Bench Dog router table from Amazon.  I was torn on this purchase – there were so many high quality expansive options.  For example, I would have loved to have one with a precise lift mechanism. In the end I think it would have saved time, but the cheap bench worked very well.  My only real regret with it was the size – it was hard to do these panels, as the bench couldnt support them.

Another note on improvising: The fun part of woodworking is being able to make anything.  Along the way, you have to make jigs and guides.  I think I made several for this project, including my own cross-cut sled for the table saw.  When i went to use the panel router, for example, i found it didn’t fit through the hole of the one that came with the router bench.  So i made my own!  It worked just fine.

Step 5: Staining and Finish

There were lots of other little steps, including forming a two-layer crown moulding along the top, but within a few months I was ready to stain things.   I tried to sand everything well with a palm sander.  We then decided to use a darker stain, partly because it actually looked nice, partly because i wanted to cover up some of my mistakes.

This part was actually fairly easy – i just applied a lot of stain, then wiped it off.  I did that twice or so in most cases, except on the hardwood where i had to do it three times or so.

My main regret here is not protecting the carpet.  I should have covered it with a thick drop cloth.  But i didnt, and of course ended up getting the carpet in several places.

Another note on stain: to make it more even, some people recommend using a diluted laqueer or pre-stain treater.  That might have been a great idea, but it made things too light for my likes.  Maybe next time.

Once the stain was dry (i gave it the recommended week or two) I applied a varnish.  I did two layers almost everywhere – three or four layers on high-impact areas like the window seat.

IMG_20140530_071124 IMG_20140530_071119 P1070431

 

 

IMG_20140517_181403

The first picture in this post is the best picture I have of the finished product.  Note there is some kind of a posterboard sitting atop the cabinet on the right – that’s not the crown moulding.  Pretty nice for a first timer!

Return of Blog

Here it is, my first post of the new blog!

My nephew inspired the thought that led me to bring back the blog.  I told him he could easily setup something on my website if he wants to learn web programming.  Then I realized that for me to share the website, I’d have to figure out how to actually setup apache for subdomains.  I also wanted it to support https and http.

Turns out this is fairly simple:

  • Add an A record to DNS for each subdomain
  • Inside apache, include at least the following:

NameVirtualHost *:80

NameVirtualHost *:443

  • For each subdomain make a conf file (in /etc/httpd/conf.d/) that includes a VirtualHost entry for each subdomain:

<VirtualHost *:80>
ServerName carson.fenimorefamily.com

# Index file and Document Root (where the public files are located)
DirectoryIndex index.html index.php
DocumentRoot <directoryForYourSubdomain>
</VirtualHost>

<VirtualHost *:443>
SSLEngine on
SSLCertificateFile <crtFileName>
SSLCertificateKeyFile <keyFileName>

ServerName carson.fenimorefamily.com

DirectoryIndex index.html index.php
DocumentRoot <directoryForYourSubdomain>
</VirtualHost>

Note that I basically repeat the same section for SSL and normal.  Why? Because in the SSL virtual host you actually turn on the SSL engine.  All the rest of the innards of each section could be placed in a separate file and included, I suppose, but prudence (or laziness) suggests otherwise for now.

Here’s looking forward to blogging about useful technical stuff; I’m purposefully not sharing juicy tidbits from my personal life, as I think the only interested parties for those things are web bots and terrorists.

I’ll even try to do some retroactive blogging of projects from the past eight years.  To that end I’ll write a TODO list here and see how well I do at whittling it down.

  • Mapping out the East Coast – Really keeping a log of places we’ve been and interesting facts
  • Becoming landlords
  • The chicken pi – my solution for monitoring a bunch of chickens
  • Some woodworking stuff – I have pictures, why not post
  • My recent raspberry-pi camera solutions
  • Some details from my thesis
  • My latest discoveries in web programming (oh how i used to loathe web, until angular came along)
  • Programming a game with my nephew