Part 2 – Working with Images Using OpenCV

Full image ahead. Today we’re continuing the WordCloud Generator. If you haven’t taken a look at the web-crawling portion of our code, I recommend you visit Part 1 – How to Crawl Your Website and Extract Key Words.

What is OpenCV?

OpenCV is a very powerful image processing library in Python (and other languages). If you want to see what other cool things you can do with it, I’d recommend Adrian’s blog. He’s done some really cool stuff.

Why Do We Need OpenCV?

Remember from our objective in Part 1, we are creating a WordCloud generator that can ingest both a URL and a raw image. The only thing about Python’s WordCloud package (pip install wordcloud) is that it’s best to supply it with a mask image. Uh…what is a mask image? Well, masking an image is where you take a color image and transform it into a binary image based upon a color threshold between 1 to 255.  See below for what I mean:

colorToBinary




The WordCloud generated is not what I was looking for. After diving into some of the wordcloud package examples, I confirmed that the words replace the black area and not the other way around.

grumpyCatWC

Grumpy Cat WordCloud – Not Exactly as Expected

I also realized that any color image I would like to use will need to be converted into a mask image before executing the wordcloud generation. We also have another issue with the Grumpy Cat image, the black space seems to merge into the body of Grumpy Cat. That’s also why the words take over Grumpy Cat’s body. There are some other things we can do to fix this, but that’s for another blog post in the future.

Using OpenCV to Fix the Problem

By defining a function called getGrayImage(imageFname), we are now able to take in any color image, create the gray image, and return a binary image. The operation cv2.imread(imagePath,cv2.CV_LOAD_IMAGE_GRAYSCALE) creates the gray image but we are not finished. How do we know what makes a black and white pixel? That’s where the real power of OpenCV shines. Without having to know any threshold, we can use the cv2.THRESH_BINAR | cv2.THRESH_OTSU flags to create the mask image. As before, the mask image will also need to be inverted so we can assign the words to the correct location. That is what cv2.bitwise_not() returns. See below:

def getGrayImage(imageFname):
"""this converts any color image to binary - black and white - for wordcloud"""
imagePath = os.path.join(os.getcwd(),'imgs',imageFname)
im_gray = cv2.imread(imagePath,cv2.CV_LOAD_IMAGE_GRAYSCALE)
im_gray = imutils.resize(im_gray,width=2000)
#this calculates the threshold for you and makes it black and white
(thresh, im_bw) = cv2.threshold(im_gray,0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
#bw image is great but wordcloud assigns words to black space - need inverse
mask_inv = cv2.bitwise_not(im_bw)
#cv2.imshow('Orig',im_gray)
#cv2.imshow('Gray',im_bw)
#save to call the files
outF1 = os.path.join(os.getcwd(),"imgs","gray_"+imageFname)
outF2 = os.path.join(os.getcwd(),"imgs","bw_"+imageFname)
cv2.imwrite(outF1,im_gray)

Using a Different Image

Although Grumpy Cat was an awesome fail, maybe a different image would be better for our first run. In the next blog post, we’ll finish up the app with a beautiful WordCloud.

Continue with Part 3 of the tutorial –> Part 3 – Creating the Word Cloud

-j

Leave a Reply

Your email address will not be published. Required fields are marked *