Monday, 4 February 2013

The Big Bang Theory!

When I say "The Big Bang Theory!" I mean, of course, these lovable scamps:


who are always witty (and often hilarious), and not this scientific bibble-babble:




which makes my head hurt.

Being based in the UK, I am (un)blessed with always being several months behind on TV releases of popular shows, so it's only recently that Season 6 has started being aired over here... 

When it started, I was reminded of one of the less obvious features of the show: after the credits there is always a kind of message flashed up for a few seconds, which looks like one of those standard copyright notices or something like that. However, after watching a few episodes you'll notice that they vary, so can't be some random legalese, and may actually be interesting. Now, obviously, in this shiny modern world we live in, we can simply press 'pause' on our 'live' TV and read the thing. Doing so reveals that they are what Chuck Lorre calls a vanity card.

They are themselves (sometimes) quite amusing, and worth reading, and here is an example:



but this left me with a small dilemma: it's all very well reading the new ones as the new season is aired, but what about all the old ones on the 100 or so episodes that have come before? I'd quite like to read those too (and I do have the entire set as digital recordings), but not to the extent that I'm going to go back and fast forward to the end of every episode...

No, what I want is to occasionally have one of these presented to me, with little or no effort, read it, and move on. Eventually, I will have read them all.

So, how to achieve this? Well, as I said, I have every episode as a digital recording, so it should be a doddle to just frame-grab the relevant frame from each episode... But hang on - isn't that going to be even more trouble than the aforementioned fast forwarding etc.? Erm... yes.

But wait! OpenCV to the rescue! Yes, python rocks and not least because there are amazing libraries that literally do all the work for you...

"You want to grab the (nearly) last frame from a bunch of videos? 10 lines of code OK with you? No problem Sir, step this way... "

OK, fair enough, it ended up as more like 30 lines with comments and spacing to make it readable, and we always get feature-creep. But you get my point... The bit of the code that does the job is extremely simple...

#! /usr/bin/env python
import cv2.cv as cv
import sys

video= cv.CaptureFromFile(sys.argv[1])


try:
     cardimage= sys.argv[1][sys.argv[1].rindex('/')+1:]+'.'+sys.argv[2]
except:
    cardimage= sys.argv[1]+'.'+sys.argv[2]
 

skip= int(sys.argv[3])

frames= int(cv.GetCaptureProperty(video, cv.CV_CAP_PROP_FRAME_COUNT))

for x in range(frames / skip):

    frames -= skip
    cv.SetCaptureProperty(video, cv.CV_CAP_PROP_POS_FRAMES, frames)
    image= cv.QueryFrame(video)
    cv.ShowImage("freezeframe", image)
    key= chr(cv.WaitKey(0)).upper()
    # save image and exit
    if key == 'Q':
        cv.SaveImage(cardimage, image)
        break
    # exit without saving.
    if key == 'X':
        break

    # oops, overshot
    if key == '-':
        frames += skip * 2


So you simply call this script with an appropriate find command which provides all the videos to be examined, the output image type desired and the number of frames to skip backwards each time a key is pressed. e.g.:

find /media/TV/The_Big_Bang_Theory -type f -exec ./tailvid.py {} png 34 \;

and for each video, a window will pop up with an image of a frame somewhere near the end. Any key press will skip backwards by the number of frames you specified and so you should quickly find the one you're looking for. Once you've found it, you press 'q' and the frame is saved, the window closed and the next one will pop up. This process is extremely quick and effortless and it took under two minutes to grab the relevant images from all 112 episodes in my collection.

Now Chuck Lorre is clearly a very forward thinking guy, as well as extremely funny, as the first image I encountered when testing this script was this one (obviously, as it's the one that was broadcast with Series 1 Episode 1):


Spooky. :)

So, Chuck... Sorry about this, and thank you for not being bitter.

As far as viewing them goes, the obvious candidate is a screensaver. Most screensavers have the option to pick a random image from a specified location, so now I get one of these whenever I come back to my desk, read it, and get on with my life (yes, I know, I'm a geek and therefore have no life, but you know what I mean).

I thought this was cool enough to warrant posting to a UK geeky mailing list that I'm on, so I did. I was surprised by some of the reactions, which mostly revolved around how over-complicated a solution this was to a simple problem, and how much time I'd wasted.

This got me to thinking how often I find examples of people settling for an imperfect solution rather than tackling the problem head on. In this case, the respondent was right in one respect: there was an apparently 'simpler' solution. Go and read them here. However, it is not, IMHO, a 'better' solution as it ultimately takes more effort: I have to go to the site, click on a card I want to read, read it, repeat. At some point I'll get bored and go do something else. I now have to make the effort to go back and carry on at some later date, and also to remember where I got to. A gigantic pain in the arse, and a complete waste of time. i.e. the opposite of what he said. It appeared simpler because a result was got quickly: a Google search, a few mouse clicks and Bingo, we're reading Vanity Cards, but as a solution it was incomplete at best.

With my solution, the actual time 'wasted' was about 20 minutes to write the code (including going to my laptop, finding an example of how to grab a frame, doing a bit of testing to find the right number of frames to skip, etc.), and about 2 minutes to grab the images. Maybe another couple to set up the screensaver. I will now 'waste' no more than a minute or so (sometimes) when I come back to a locked screen. In the process I learned something new about OpenCV and got myself a fancy screensaver. Ironically, I actually ended up wasting more time discussing the time-wasting on the mailing list than I did creating the screensaver in the first place. Ho hum. :)

Now, back to the kitchen - I can smell my bacon burning in the George Foreman!

1 comment:

  1. Your solution accomplishes 2 things.

    1. You were intrigued by an issue that you found interesting enough to pursue in a world full of distractions. (hard sometimes)

    2. You flexed your smarticles by standing on others shoulders (i.e. not re-inventing the wheel).

    - sorry -
    3. You posted the results and found another reader for your blog.

    P.S. You write much more coherently than I do on my blog, so I will study it as well.

    ReplyDelete