1. 程式人生 > >Using OpenCV, Python and Template Matching to play "Where's Waldo?"

Using OpenCV, Python and Template Matching to play "Where's Waldo?"

This is a guest post by Adrian Rosebrock from PyImageSearch, a blog all about computer vision, image processing, and building image search engines.

Where's Waldo

Figure 1: How long does it take you to find Waldo in this puzzle?

Take a look at the Where’s Waldo puzzle above. How long does it take you to find Waldo? 10 seconds? 30 seconds? Over a minute?

Waldo is the ultimate game of hide and seek for the human eye. He’s actually “hiding” in plain sight — but due to all the noise and distraction, we can’t pick him out immediately!

At the core, Waldo is just a visual pattern. He wears glasses. A hat. And his classic white and red horizontally striped shirt. It might take us a little bit of time to scan up and down and left to right across the page, but our brain is able to pick out this pattern, even amongst all the distraction.

The question is, can computers do better? Can we create a program that can automatically find Waldo?

In fact, we can.

Using computer vision techniques we can find Waldo in under a second, much faster than any of us could!

In this blog post I’ll show you how to use the OpenCV and template matching functions to find that pesky Waldo who is always hiding in plain sight.

Here’s a quick overview of what we’re going to do:

  • What we’re going to do: Build a Python script using OpenCV that can find Waldo in a “Where’s Waldo?” puzzle.
  • What you’ll learn: How to utilize Python, OpenCV, and template matching using cv2.matchTemplate and cv2.minMaxLoc. Using these functions we will be able to find Waldo in our puzzle image.
  • What you need: Python, NumPy, and OpenCV. A little knowledge of basic image processing concepts would help, but is definitely not a requirement. This how-to guide is meant to be hands on and show you how to apply template matching using OpenCV. Don’t have these libraries installed? No problem. I created a pre-configured virtual machine with all the necessary computer vision, image processing, and machine learning packages pre-installed. Click here to learn more.
  • Assumptions: I’ll assume that you have NumPy and OpenCV installed in either the python2.6 or python2.7 environment. Again, you can download a pre-configured virtual machine with all the necessary packages installed here.

Need help with Machine Learning in Python?

Take my free 2-week email course and discover data prep, algorithms and more (with code).

Click to sign-up now and also get a free PDF Ebook version of the course.

The Goal:

So what’s the overall goal of the Python script we are going to create?

The goal, given a query image of Waldo and the puzzle image, is to find Waldo in in the puzzle image and highlight his location.

As you’ll see later in this post, we’ll be able to accomplish this in only two lines of Python code. The rest of the code simply handles logic such as argument parsing and displaying the solved puzzle to our screen.

Our Puzzle and Query Image

We require two images to build our Python script to perform template matching.

The first image is the Where’s Waldo puzzle that we are going to solve. You can see our puzzle image in Figure 1 at the top of this post.

The second image is our query image of Waldo:

Our Waldo query image

Figure 2: Our Waldo query image

Using our Waldo query image we are going to find him in the original puzzle.

Unfortunately, here is where the practicality of our approach breaks down.

In order to find Waldo in our puzzle image, we first need the image of Waldo himself. And you may be asking, if I already have the image of Waldo, why I am I playing the puzzle?

Good point.

Using computer vision and image processing techniques to find Waldo in a image is certainly possible.

However, it requires some slightly more advanced techniques such as:

  1. Filtering out colors that are not red.
  2. Calculating the correlation of a striped pattern to match the red and white transitions of Waldo’s shirt.
  3. Binarization of the regions of the image that have high correlation with a striped pattern.

This post is meant to be an introduction to basic computer vision techniques such as template matching. Later on we can dive into more advanced techniques. Where’s Waldo was just a cool and simple way to perform template matching that I just had to share with you!

Getting Our Hands Dirty

Ready to see some code? Alright, let’s do this:

A How-To Guide to Template Matching with OpenCV and Python Python
123456789101112131415161718 # import the necessary packagesimportnumpy asnpimportargparseimportimutilsimportcv2# construct the argument parser and parse the argumentsap=argparse.ArgumentParser()ap.add_argument("-p","--puzzle",required=True,help="Path to the puzzle image")ap.add_argument("-w","--waldo",required=True,help="Path to the waldo image")args=vars(ap.parse_args())# load the puzzle and waldo imagespuzzle=cv2.imread(args["puzzle"])waldo=cv2.imread(args["waldo"])(waldoHeight,waldoWidth)=waldo.shape[:2]

Lines 1-13 simply imports the packages we are going to use and configures our argument parser. We’ll use NumPy for array manipulations, argparse to parse our command line arguments, and cv2 for our OpenCV bindings. The package imutils is actually a set of convenience functions to handle basic image manipulations such as rotation, resizing, and translation. You can read more about these types of basic image operations here.

From there, we need to setup our two command line arguments. The first, --puzzle is the path to our Where’s Waldo puzzle image and --waldo is the path to Waldo query image.

Again, our goal here is to find the query image in the puzzle image using template matching.

Now that we have the paths to our images, we load them off of disk on Line 16 and 17 using the cv2.imread function — this method simply reads the image off disk and then stores it as a multi-dimensional NumPy array.

Since images are represented as NumPy arrays in OpenCV, we can easily access the dimensions of the image. On Line 18 we grab the height and the width of the Waldo query image, respectively.

We are now ready to perform our template matching:

A How-To Guide to Template Matching with OpenCV and Python Python
202122 # find the waldo in the puzzleresult=cv2.matchTemplate(puzzle,waldo,cv2.TM_CCOEFF)(_,_,minLoc,maxLoc)=cv2.minMaxLoc(result)

We accomplish our template matching on Line 21 by using the cv2.matchTemplate function. This method requires three parameters. The first is our puzzle image, the image that contains what we are searching for. The second is our query image, waldo. This image is contained within the puzzle image and we are looking to pinpoint its location. Finally, the third argument is our template matching method. There are a variety of methods to perform template matching, but in this case we are using the correlation coefficient which is specified by the flag cv2.TM_CCOEFF.

So what exactly is the cv2.matchTemplate function doing?

Essentially, this function takes a “sliding window” of our waldo query image and slides it across our puzzle image from left to right and top to bottom, one pixel at a time. Then, for each of these locations, we compute the correlation coefficient to determine how “good” or “bad” the match is. Regions with sufficiently high correlation can be considered “matches” for our waldo template.

From there, all we need is a call to cv2.minMaxLoc on Line 22 to find where our “good” matches are.

That’s really all there is to template matching!

And realistically, it only took us two lines of code.

The rest of our source code involves extracting the region that contains Waldo and then highlighting him in the original puzzle image:

A How-To Guide to Template Matching with OpenCV and Python Python
24252627282930313233 # grab the bounding box of waldo and extract him from# the puzzle imagetopLeft=maxLocbotRight=(topLeft[0]+waldoWidth,topLeft[1]+waldoHeight)roi=puzzle[topLeft[1]:botRight[1],topLeft[0]:botRight[0]]# construct a darkened transparent 'layer' to darken everything# in the puzzle except for waldomask=np.zeros(puzzle.shape,dtype="uint8")puzzle=cv2.addWeighted(puzzle,0.25,mask,0.75,0)

Line 26 grabs the top-left (x, y) coordinates of the image that contains the best match based on our sliding window. Then, we compute the bottom-right (x, y) coordinates based on the width and height of our waldo image on Line 27. Finally we extract this roi (Region of Interest) on Line 28.

The next step is to construct a transparent layer that darkens everything in the image but Waldo. We do this by first initializing a mask on Line 32 with the same shape as our puzzle filled with zeros. By filling the image with zeros we are creating an image filled with black.

In order to create the transparent effect, we use the cv2.addWeighted function on Line 33. The first parameter is our puzzle image, and the second parameter indicates that we want it to contribute to 25% of our output image.  We then supply our mask as the third parameter, allowing it to contribute to 75% of our output image. By utilizing the cv2.addWeighted function we have been able to create the transparency effect.

However, we still need to highlight the Waldo region! That’s simple enough:

A How-To Guide to Template Matching with OpenCV and Python Python
3536373839404142 # put the original waldo back in the image so that he is# 'brighter' than the rest of the imagepuzzle[topLeft[1]:botRight[1],topLeft[0]:botRight[0]]=roi# display the imagescv2.imshow("Puzzle",imutils.resize(puzzle,height=650))cv2.imshow("Waldo",waldo)cv2.waitKey(0)

Here we are just placing the Waldo ROI back into the original image using some NumPy array slicing techniques on Line 37. Nothing to it.

Finally, Lines 40-42 display the results of our work by displaying our Waldo query and puzzle image on screen and waiting for a key press.

To run our script, fire up your shell and execute the following command:

A How-To Guide to Template Matching with OpenCV and Python Shell
1 $python find_waldo.py--puzzle puzzle.png--waldo waldo.png

When your script is finished executing you should see something like this on your screen:

We have successfully found Waldo

Figure 3: We have successfully found Waldo!

We have found Waldo at the bottom-left corner of the image!

So there you have it!

Template matching using Python and OpenCV is actually quite simple. To start, you just need two images — an image of the object you want to match and an image that contains the object. From there, you just need to make calls to cv2.matchTemplate and cv2.minMaxLaoc. The rest is just wrapper code to glue the output of these functions together.

Learn Computer Vision In A Single Weekend

Of course, we are only scratching the surface of computer vision and image processing. Template matching is just the start.

Luckily, I can teach you the basics of computer vision in a single weekend.

I know, it sounds crazy.

But my method really works.

See, I just finished writing my new book, Practical Python and OpenCV. I wanted this book to be as hands-on as possible. I wanted something that you could easily learn from, without all the rigor and details associated with a college level computer vision and image processing course.

The bottom line is that Practical Python and OpenCV is the best, guaranteed quick start guide to learning the fundamentals of computer vision and image processing.

Plus, I have created a downloadable Ubuntu VirtualBox virtual machine with OpenCV, PIL, mahotas, scikit-image, scikit-learn, and many other computer vision and image processing libraries pre-configured and pre-installed.

So go ahead, jump start your computer vision education. Don’t waste time installing packages…invest your time learning!

To learn more about my new book and downloadable virtual machine, .

Frustrated With Python Machine Learning?

Master Machine Learning With Python

Develop Your Own Models in Minutes

…with just a few lines of scikit-learn code

Covers self-study tutorials and end-to-end projects like:
Loading data, visualization, modeling, tuning, and much more…

Finally Bring Machine Learning To
Your Own Projects

Skip the Academics. Just Results.

相關推薦

Using OpenCV, Python and Template Matching to play "Where's Waldo?"

Tweet Share Share Google Plus This is a guest post by Adrian Rosebrock from PyImageSearch, a blo

識別簡單的答題卡(Bubble sheet multiple choice scanner and test grader using OMR, Python and OpenCV——jsxyhelu重新整編)

該部落格轉自www.pyimagesearch.com,進行了相關修改補充。 Over the past few months I’ve gotten quite the number of requests landing in my inbox to build a bubble sheet/

Using Python and Linear Programming to Optimize Fantasy Football Picks

Using Python and Linear Programming to Optimize Fantasy Football PicksI’m not a big sports fan but I always liked the numbers. That’s why I was interested

How to automatically segment customers using purchase data and a few lines of Python

How to automatically segment customers using purchase data and a few lines of PythonA small educative project for learning “Customer Segmentation” with a s

mysql更新字段值提示You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column To disable safe mode

error without 使用 using ble mod code span set 1 引言 當更新字段缺少where語句時,mysql會提示一下錯誤代碼: Error Code: 1175. You are using safe update mode and yo

How to Fix “Failed to play test tone” error on Windows 7, 8 and 10

rem item route audio laptop imu right answer tom 轉自: https://appuals.com/how-to-fix-failed-to-play-test-tone-error-on-windows-7-8-and-10/

更新資料庫中資料時出現: Error Code: 1175. You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column To disable safe m

在資料庫中更新資料時報錯: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column  To disable safe mode, toggle

No matching distribution found for opencv-python

No matching distribution found for opencv-python sudo pip3 install opencv-python [email protected]:~$ sudo pip3 install opencv-python T

python leetcode Best Time to Buy and Sell Stock

經典的關於陣列的DP題目 121. Best Time to Buy and Sell Stock class Solution(object): def maxProfit(self, prices): """ :type prices: L

資料分析文摘:Reading and Writing JSON to a File in Python

原文地址:https://stackabuse.com/reading-and-writing-json-to-a-file-in-python/   Over the last 5-10 years, the JSON format has been one of, if

MySQL Workbench批量修改資料報錯:Error Code: 1175. You are using safe update mode and you tried to update a t

批量修改資料SQL:update sys_menu set menu_extralink = true     錯誤資訊: Error Code: 1175. You are using safe update mode and you tried to upd

Python 102: An Intro to TDD and unittest

Python code testing is something new to me. It’s not required where I work, so I haven’t spent much time looking into it, besides reading a book on the sub

Hacking up a reporting pipeline using Python and Excel

Hacking up a reporting pipeline using Python and ExcelWhen I arrived at Online Drinks, the reporting process was manual, prone to errors and was taking ove

How AI is Learning to Play Dota 2 — and Win – Noteworthy

How AI is Learning to Play Dota 2 — and WinIn August, a team of bots developed by California-based AI company OpenAI competed against some of the world’s b

Using machine learning and optimization to improve refugee integration

IMAGE: Andrew Trapp, an associate professor in the Foisie Business School at Worcester Polytechnic Institute (WPI), and PhD student Narges Ahani are workin

Android Developers Blog: Improving app security and performance on Google Play for years to come

Posted by Edward Cunningham, Product Manager, Android [Edit: Updated post on Dec 21 to clarify that when the 64-bit requirement is introduced in August 2

How to predict likes and shares based on your article’s title using Machine Learning

Some of the most used platforms to spread ideas nowadays are Twitter and Medium (you are here!). On Twitter, articles are normally posted including externa

Face Detection in Go using OpenCV and MachineBox @ Alex Pliutau's Blog

I found a very nice developer-friendly project MachineBox, which provides some machine learning tools inside Docker Container, including fac

Image Segmentation Using Color Spaces in OpenCV + Python – Real Python

It may be the era of deep learning and big data, where complex algorithms analyze images by being shown millions of them, but color spaces are still sur

Getting Started With the Slack API Using Python and Flask

The slick hosted chat application Slack is all the rage this year. The tool’s adoption isn’t empty hype - it’s incredibly useful for communicating with