Solving Instagram’s Unshredder with Mechanical Turk and $0.50

By now you’ve probably seen the Instagram Engineering Challenge: The Unshredder and a few solutions including one written purely in Canvas and Javascript. I don’t know any company code blogs that solve other company code blogs’ engineering challenges but that sounds meta enough to be awesome, so let’s do it.

The Solution

First I took the source image and sliced it into 20 slices:

#!/bin/bash for i in {0..19} do offset=$[$i*32] index=$[$i+1] convert -crop "32x359+$offset" TokyoPanoramaShredded.png "$index.jpg" done

Then I made a simple page that lets someone drag-and-drop the slices into the correct order:

This uses some simple jquery UI to make the slices draggable. We bind an event after each slice is moved that saves the order of the images to a hidden input and then we POST that data when they click the button. PHP then takes that order and saves it into a text file like this:

9.jpg 11.jpg 15.jpg 17.jpg 19.jpg 14.jpg 8.jpg 4.jpg 3.jpg 12.jpg 5.jpg 20.jpg 18.jpg 13.jpg 7.jpg 16.jpg 2.jpg 6.jpg 1.jpg 10.jpg

ImageMagick can then reconstruct the image using these params:

params=`cat out/order.txt` convert +append $params unshredded.jpg

Next I downloaded Amazon Mechanical Turk Command Line Tools and installed them. I cloned the helloworld example using hits/makeTemplate.sh and modified it to create a HIT template with these parameters:

unshred.properties

title:Move strips of an image around until the original image is formed description:An image will be sliced into 20 vertical slices and randomized, you will need to put them back in the right order keywords:puzzle image slices reward:0.50 assignments:1

unshred.question

<?xml version="1.0" encoding="UTF-8"?> <QuestionForm xmlns="http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2005-10-01/QuestionForm.xsd"> <Question> <QuestionIdentifier>answer</QuestionIdentifier> <QuestionContent> <FormattedContent><![CDATA[<h1>Move strips of an image around until the original image is formed</h1> <p>An image will be sliced into 20 vertical slices and randomized, you will need to put them back in the right order.</p> <p>Here is an example of an image you will need to solve: </p> <p><img alt="" src="http://unshred.recollect.com/example.jpg" /></p> <p>When you're ready, go this this url:</p> <h1><a href="http://unshred.recollect.com" target="_blank">http://unshred.recollect.com</a></h1> <p>and drag the slices around until the original image is formed, then click the <b>I'm done</b> button. </p> <p> </p> <p>Enter your solution ID in the box below:</p>]]></FormattedContent> </QuestionContent> <AnswerSpecification> <FreeTextAnswer/> </AnswerSpecification> </Question> </QuestionForm>

When we run the script using run.sh , this submits a task to Mechanical Turk which looks like this to the end user:

If they want to make a whopping $0.50, they can accept the task of unshredding our image.

Then I wrote a bash script that brings it all together:

#!/bin/bash if [ -z "$1" ] then echo "Usage: $0 file_to_process" exit fi for i in {0..19} do offset=$[$i*32] index=$[$i+1] convert -crop "32x359+$offset" "$1" "$index.jpg" done FILE=out/order.txt rm -f $FILE rm -f unshredded.jpg START=$(date +%s) cd /var/www/recollect/unshred.recollect.com/mturk/aws-mturk-clt-1.3.0/hits/unshred/ ./run.sh cd /var/www/recollect/unshred.recollect.com/ echo "Waiting for someone to solve the puzzzle..." while [ ! -f "$FILE" ] do inotifywait -t 86400 -e create -e move_to "$(dirname $FILE)" &>/dev/null done END=$(date +%s) DIFF=$(( $END - $START )) echo "Puzzle solved in $DIFF seconds." sleep 2 params=`cat $FILE` convert +append $params unshredded.jpg

Does it work? Yes, yes it does.

Starting with the source image:

We run our script:

Then if we open unshredded.jpg, we get:

This also works on other images:

Source image (flickr):

We run our script:

And open unshredded.jpg:

That’s it! It’s blazingly fast, taking about 5 to 10 minutes to run. Check out the landing page or browse the code on Github.

Bertrand Fan, co-founder