Quantcast
Channel: Tutorials Archives - PyImageSearch
Viewing all articles
Browse latest Browse all 432

How to find functions by name in OpenCV

$
0
0

opencv_func_names_examples

OpenCV can be a big, hard to navigate library, especially if you are just getting started learning computer vision and image processing.

The release of OpenCV 3 has only further complicated matters, moving a few important functions around and even slightly altering their names (the

cv2.cv.BoxPoints
  vs.
cv2.boxPoints
  methods come to mind off the top of my head).

While a good IDE can help you search and find a particular function based on only a few keystrokes, sometimes you won’t have access to your IDE. And if you’re trying to develop code that is compatible with both OpenCV 2.4 and OpenCV 3, then you’ll need to programmatically determine if a given function is available (whether via version detection or function listing).

Enter the

find_function
  method, now part of the imutils library, that can help you search and lookup OpenCV methods simply by providing a query string.

In the rest of this blog post I’ll show you how to quickly and programmatically search and lookup functions in the OpenCV library using only simple Python methods.

Looking for the source code to this post?
Jump right to the downloads section.

Dumping all OpenCV function names and attributes

A quick way to view all OpenCV functions and attributes exposed to the Python bindings is to use the built-in Python 

dir
  function, which is used to return a list of names in the current local scope.

Assuming you have OpenCV installed and a Python shell ready, we can use the

dir
  method to create a list of all OpenCV methods and attributes available to us:
>>> import cv2
>>> funcs = dir(cv2)
>>> for f in funcs:
...     print(f)
... 
ACCESS_FAST
ACCESS_MASK
ACCESS_READ
ACCESS_RW
ACCESS_WRITE
ADAPTIVE_THRESH_GAUSSIAN_C
ADAPTIVE_THRESH_MEAN_C
AGAST_FEATURE_DETECTOR_AGAST_5_8
AGAST_FEATURE_DETECTOR_AGAST_7_12D
AGAST_FEATURE_DETECTOR_AGAST_7_12S
AGAST_FEATURE_DETECTOR_NONMAX_SUPPRESSION
AGAST_FEATURE_DETECTOR_OAST_9_16
AGAST_FEATURE_DETECTOR_THRESHOLD
AKAZE_DESCRIPTOR_KAZE
AKAZE_DESCRIPTOR_KAZE_UPRIGHT
AKAZE_DESCRIPTOR_MLDB
AKAZE_DESCRIPTOR_MLDB_UPRIGHT
AKAZE_create
...
waitKey
warpAffine
warpPerspective
watershed
xfeatures2d
ximgproc
xphoto

While this method does indeed give us the list of attributes and functions inside OpenCV, it requires a manual scan or a grep of the list to find a particular function.

Personally, I like to use this raw list of method names if I have a rough idea of what you’re looking for (kind of like a “I’ll know it when I see it” type of situation); otherwise, I look to use the

find_function
  method of
imutils
  to quickly narrow down the search space — similar to grep’ing the output of
dir(cv2)
 .

Searching the OpenCV library for (partial) function names

Let’s start off this section by defining our

find_function
  method:
# import the necessary packages
from __future__ import print_function
import cv2
import re

def find_function(name, pretty_print=True, module=None):
	# if the module is None, initialize it to to the root `cv2`
	# library
	if module is None:
		module = cv2

	# grab all function names that contain `name` from the module
	p = ".*{}.*".format(name)
	filtered = filter(lambda x: re.search(p, x, re.IGNORECASE), dir(module))
	
	# check to see if the filtered names should be returned to the
	# calling function
	if not pretty_print:
		return filtered

	# otherwise, loop over the function names and print them
	for (i, funcName) in enumerate(filtered):
		print("{}. {}".format(i + 1, funcName))

if __name__ == "__main__":
	find_function("blur")

Lines 2-4 start off by importing our necessary packages. We’ll need

cv2
  for our OpenCV bindings and
re
  for Python’s built-in regular expression functionality.

We define our

find_function
  method on Line 6. This method requires a single required argument, the (partial)
name
  of the function we want to search
cv2
  for. We’ll also accept two optional arguments:
pretty_print
  which is a boolean indicating whether the results should be returned as a list or neatly formatted to our console; and
module
  which is the root-module or sub-module of the OpenCV library.

We’ll initialize

module
  to be
cv2
 , the root-module, but we could also pass in a sub-module such as
xfeatures2d
 . In either case, the
module
  will be searched for partial function/attribute matches to
name
 .

The actual search takes place on Lines 13 and 14 where we apply a regular expression to determine if any attribute/function name inside of

module
  contains the supplied
name
 .

Lines 18 and 19 make a check to see if we should return the list of

filtered
  functions to the calling function; otherwise, we loop over the function names and print them to our console (Lines 22 and 23).

Finally, Line 26 takes our

find_function
  method for a test drive by searching for functions containing the
blur
  in their name.

To see our

find_function
  method in action, just open a terminal and execute the following command:
$ python find_function.py
1. GaussianBlur
2. blur
3. medianBlur

As our output shows, it seems there are three functions inside of OpenCV that contain the text

blur
 , including
cv2.GaussianBlur
 ,
cv2.blur
 , and
cv2.medianBlur
 .

A real-world example of finding OpenCV functions by name

As I already mentioned earlier in this post, the

find_functions
  method is already part of the imutils library. You can install
imutils
  via
pip
 :
$ pip install imutils

If you already have

imutils
  installed on your system, be sure to upgrade it to the latest version:
$ pip install --upgrade imutils

Our goal in this project is to write a Python script to detect the hardcopy edition of Practical Python and OpenCV + Case Studies (which is set to be released on Wednesday, August 16th at 12:00 EST, so be sure to mark your calendars!) in an image and draw a its bounding contour surrounding it:

Our goal is to find the outline (i.e. contours) of the original book (left) and then draw the outline on the book (right).

Figure 1: Our goal is to find the original book in the image (left) and then draw the outline on the book (right).

Open up a new file, name it

find_book.py
 , and let’s get coding:
# import the necessary packages
import numpy as np
import cv2

# load the image containing the book
image = cv2.imread("ppao_hardcopy.png")
orig = image.copy()

# convert the image to grayscale, threshold it, and then perform a
# series of erosions and dilations to remove small blobs from the
# image
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 40, 255, cv2.THRESH_BINARY)[1]
thresh = cv2.erode(thresh, None, iterations=2)
thresh = cv2.dilate(thresh, None, iterations=2)

We start off by loading our image from disk on Line 6. We then do some basic image processing on Lines 12-15, including conversion to grayscale, thresholding, and a series of erosions and dilations to remove any small blobs from the thresholded image. Our output thresholded image looks like this:

Figure 3: The thresholded, binary representation of the book image.

Figure 3: The thresholded, binary representation of the book image.

However, in order to draw the contour surrounding the book, I first need to find the outline of the book itself.

Let’s pretend that I’m stuck and I don’t know what the name of the function is that finds the outline of an object in an image — but I do recall that “outlines” are called “contours” in OpenCV.

By firing up a shell and using the

find_function
  in
imutils
 , I quickly ascertain that that I am looking for the
cv2.findContours
  function:
$ python
>>> import imutils
>>> imutils.find_function("contour")
1. contourArea
2. drawContours
3. findContours
4. isContourConvex

Now that I know I am using the

cv2.findContours
  method, I need to figure out what contour extraction flag should be used for the function. I only want to return external contours (i.e the outer-most outlines) so I’ll need to look up that attribute as well:
>>> imutils.find_function("external")
1. RETR_EXTERNAL

Got it. I need to use the

cv2.RETR_EXTERNAL
  flag. Now that I have that settled, I can finish up my Python script:
# import the necessary packages
import numpy as np
import cv2

# load the image containing the book
image = cv2.imread("ppao_hardcopy.png")
orig = image.copy()

# convert the image to grayscale, threshold it, and then perform a
# series of erosions and dilations to remove small blobs from the
# image
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 40, 255, cv2.THRESH_BINARY)[1]
thresh = cv2.erode(thresh, None, iterations=2)
thresh = cv2.dilate(thresh, None, iterations=2)

# find contours in the thresholded image, keeping only the largest
# one
(_, cnts, _) = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
	cv2.CHAIN_APPROX_SIMPLE)
c = max(cnts, key=cv2.contourArea)
cv2.drawContours(image, [c], -1, (0, 255, 255), 3)

# show the output image
thresh = np.dstack([thresh] * 3)
cv2.imshow("Output", np.hstack([orig, thresh, image]))
cv2.waitKey(0)

Lines 19 and 20 makes a call to

cv2.findContours
  to find the external outlines of the objects (thanks to the
cv2.RETR_EXTERNAL
  attribute) in the thresholded image.

We’ll then take the largest contour found (which is presumed to be the outline of the book) and draw the outline on our image (Lines 21 and 22).

Finally, Lines 25-27 show our output images.

To see my script in action, I just fire up a terminal and issue the following command:

$ python find_book.py

Figure 2: Our original input image (left), the thresholded, binary representation of the image (center), and the contour drawn surrounding the book (right).

Figure 3: Our original input image (left), the thresholded, binary representation of the image (center), and the contour drawn surrounding the book (right).

Sure enough, we’ve been able to detect and draw the outline of the book without a problem!

Summary

In this blog post we learned how to get the names of all functions and attributes in OpenCV that are exposed to the Python bindings.

We then built a Python function to programmatically search these function/attribute names via a text query. This function has been included in the imutils package.

Finally, we explored how OpenCV function filtering can be used in your every-day workflow to increase productivity and facilitate quick function lookup. We demonstrated this by building a small Python script detect the presence of a book in an image.

Downloads:

If you would like to download the code and images used in this post, please enter your email address in the form below. Not only will you get a .zip of the code, I’ll also send you a FREE 11-page Resource Guide on Computer Vision and Image Search Engines, including exclusive techniques that I don’t post on this blog! Sound good? If so, enter your email address and I’ll send you the code immediately!

The post How to find functions by name in OpenCV appeared first on PyImageSearch.


Viewing all articles
Browse latest Browse all 432

Trending Articles