Making Maps, Version 2.1: Recognizing location by pixel color

Map of the travels on Day 66

Map of the travels on Day 66

So it turns out now the most tedious thing to do when creating the maps is renaming the files with their tile position information.  I’m not a fan of tedious.

I figured Imagemagick’s -subimage recognition might be the way to go and went as far as writing a script that could pull out the maps from screenshots and (assuming I only ever fed it properly named files) snag off the 6 character file prefix to preserve as the file name.

Once I had some example subimages to compare my screen shots to, I ran a test of the compare.

compare -metric MAE -subimage-search 29-12-2014_08.52.24.png ./cnrkeys/07y07x_cnrkey.png null: 2>&1

After 10 minutes of letting that process run in the background I did some more research on subimage-search and why it might be sooooooo sloooowwwwww. It turns out compare is trying to find all best possible matches. I can’t limit where ImageMagick will to look without cropping the main image in the exactly same way. Another recommendation beside croping would be to downsample them both. A combination downsample and crop would be the fastest of all.

Since that kind of multistep processing seemed like overkill for my problem, I changed tactics. I just need to know if a certain spot on the screen is green. If the pixel is green then I am in the corresponding location.

#What color on the legend indicates where I am. 
#This result will be based on the formatting used below.
TRUECOLOR="136,216,0"

#Get one pixel XCORD,YCORD in from the top left and spit out its
#color information in the format requested. 
mycolor=$(convert $p[1x1+${XCORD}+${YCORD}] -format "%[fx:floor(255*u.r)],%[fx:floor(255*u.g)],%[fx:floor(255*u.b)]" info:-)

#An example of what to do with the information
if [ "$mycolor" == "$TRUECOLOR" ]; then
    found=1
fi

Took a little doing, but I got it working with a row-column scan (gist shown at the end). With a few changes I can use a very similar script to see if Link is dead, what weapon is enabled… it all depends on figuring out a unique pixel color at a unique location.  It is still slow, about 2 to 10 seconds per image depending on its position. To recognize location 07y15x  convert will be called 128 times. It would be faster processing time wise to figure out a way to load a pixel array, but not, it think, faster in people time. I’m not doing millions of these suckers.

As a bonus I can have the script generate my travel route. Seems handy. Not sure how I’ll use it yet.

Current Process

  1. Organize the potential images I want to use for the map (include duplicates if I went through and area twice) in iPhoto or in Finder.
  2. Run the rename script on the folder
  3. Cull the duplicates for any tile position
  4. Run the map-making script on the folder

I do the rename script after organizing now because it changes the order they get processed in and I am thinking about how to preserve route information.

#!/bin/bash
#Reduce time by running process for just the part of the
#grid actually represented
Y1=$1
Y2=$2
X1=$3
X2=$4
#used in prefix generation
ZPAD=2
#folder files saved into
MYDIR="named_tiles"
#About the image being processed and where to look
#on the legend for the location information.
#How far from the top left corner
XOFFSET=193
YOFFSET=90
#How big of an area am I searching from that offset?
let KEYWIDTH=497-$XOFFSET
let KEYHEIGHT=210-$YOFFSET
#How many possible tiles represented in that region?
NUM_X_POS=16 #how many tiles wide?
NUM_Y_POS=8 #how many tiles tall?
#How big will each tiles representative area be?
let XMULTIPLIER=${KEYWIDTH}/${NUM_X_POS}
let YMULTIPLIER=${KEYHEIGHT}/${NUM_Y_POS}
#Look in the middle of that area.
let XOFFSET=XOFFSET+XMULTIPLIER/2
let YOFFSET=YOFFSET+YMULTIPLIER/2
#What color on the legend indicates where I am.
#This result will be based on the formating used below.
TRUECOLOR="136,216,0"
#Some variables needed to generate the route from I took if all
#my origin, which is not the top left.
#Will only work if the files are from the same day.
NL=$'\n'
MYROUTE="MY ROUTE:$NL"
ROUTEX=7 #if not far left tile, 0, then where?
ROUTEY=7 #if not top tile, 0, then where?
#The defaults if no variables are passed into the script.
if [[ -z $Y1 ]]; then Y1=0 ; fi
if [[ -z $Y2 ]]; then let Y2=${NUM_Y_POS}-1 ; fi
if [[ -z $X1 ]]; then X1=0 ; fi
if [[ -z $X2 ]]; then let X2=${NUM_X_POS}-1 ; fi
if [ ! -d ./${MYDIR} ]; then mkdir ./${MYDIR}; fi
#————– START LOOP ———————-#
# If there are PNG files… get them.
if ls | grep png; then for p in *.png; do
echo "Processing $p"
found=0
#Begin row-col scan with first row.
for i in $(seq $Y1 $Y2); do
let YCORD=${YOFFSET}+${i}*${YMULTIPLIER}
#FOR ROUTE TEXT
let YLOC=ROUTEY-${i}
#Begin col scan with first col
for j in $(seq $X1 $X2); do
let XCORD=${XOFFSET}+${j}*${XMULTIPLIER}
#FOR ROUTE TEXT
let XLOC=ROUTEX-${j}
if [ "$XLOC" -ge 0 ]
then XDESC="E"
else XDESC="W"
fi
XLOC=${XLOC#-}
#The format of this line should match pattern of TRUECOLOR.
mycolor=$(convert $p[1×1+${XCORD}+${YCORD}] -format "%[fx:floor(255*u.r)],%[fx:floor(255*u.g)],%[fx:floor(255*u.b)]" info:-)
#echo "I look $mycolor at $XCORD, $YCORD"
if [ "$mycolor" == "$TRUECOLOR" ]; then
found=1
#FOR ROUTE TEXT
printf -v location "%0*dN, %0*d%s" $ZPAD $YLOC $ZPAD $XLOC $XDESC
MYROUTE="${MYROUTE}${location}$NL"
#echo "I am at $location"
#FILE RENAME AND MOVE
printf -v fileprefix "%0*dy%0*dx" $ZPAD $i $ZPAD $j
#copy the file while preserving timestamps
cp -p $p ./${MYDIR}/${fileprefix}_${p}
#echo "I am at $filename"
break 2
fi
done
done
#If I don't belong anywhere… Death images will trigger this.
if [ "$found" -lt 1 ]
then
cp -p $p ./${MYDIR}/HELP_${p}
fi
done
fi
#—————— END LOOP ————————#
#Save the route to file.
#Will only work if complete sequence runs. That is a
#feature for now.
echo "$MYROUTE" > route.txt

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s