Basic Color Tracking with OpenCV

OpenCV is a fantastic library for use in everything computer vision. It has pretty good documentation and support, as well as being completely open source. Here’s an introduction to implementing a basic OpenCV program, which we’ll use to track a red circle.

A complete version of the code is at the end of this post.

To start our OpenCV code, we need access to an image.

import cv2

def main():
  cap = cv2.VideoCapture(0)
  while True:
    ret, frame = cap.read()
    cv2.imshow("camera", frame)
    c = cv2.waitKey(1)

if __name__ == '__main__':
  main()

We open a connection to the webcam at index 0 (this number changes if you have multiple camera devices on your system) returning the image to the frame variable that we’ve set from before. We use imshow to show the frame to the screen, then pause for a second for the image to display. Run the code, and you should see a window with your webcam input pop up on the screen.

cv_1

Cool! So we have a frame for our OpenCV script to work with. Now, in image processing, we have to treat images as an array of numbers. In our case, the camera returns a 640×480 array of pixels with values from (0,0,0) to (255,255,255)–RGB color space. We’ll want to convert the RGB image into HSV for color filtering.

Typically, we visualize RGB(right) as a cube and HSV(left) as a cone.

RGB visualization HSV visualization

Note that RBG combines intensity and color. However, HSV separates the intensity of the color from the hue, which means we can simply filter one channel of the HSV image to get the color we want. Super useful!

**Note that OpenCV orders the channels as BRG instead of RGB**

Let’s convert the image to HSV, then filter for red.

import cv2
import cv2.cv as cv
import numpy as np

def main():
	cap = cv2.VideoCapture(0)
	while True:
		ret, frame = cap.read()

		hsv_image = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
		red_image = cv2.inRange(hsv_image, (0,50,50), (8,170,200))
		cv2.imshow("camera", frame)
		cv2.imshow("red image", red_image)
		c = cv2.waitKey(1)

if __name__ == '__main__':
	main()

cv_2

Woah! So cool right!? Note that there’s a bit of red from my face, as well as my my little red friend in the background is highlighted as well. However, the majority of the filtered image is around the red pokeball. As a brief aside: The reason why color filtering isn’t the best way do object recognition is that color changes drastically with the lighting conditions. (Remember the blue/black, gold/white dress scandal earlier this year? Hahaha). To change the color that the code will filter for, change the value inside the cv2.inRange function.

With the red image filtered out now, we can do some basic shape detection to find where our ball is. The function can use for this is HoughCircles. The method behind circle detection is rather complex, but we can treat it like a black box for now and just run the code over our image.

import cv2
import cv2.cv as cv
import numpy as np

def main():
	cap = cv2.VideoCapture(0)
	while True:
		ret, frame = cap.read()

		hsv_image = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
		red_image = cv2.inRange(hsv_image, (0,50,50), (8,170,200))

		circles = cv2.HoughCircles(red_image, cv.CV_HOUGH_GRADIENT,1,20,
		param1=50,param2=30,minRadius=0,maxRadius=0)

		if circles != None:
			circles = np.uint16(np.around(circles))
			for i in circles[0,:]:
				# draw the outer circle
				cv2.circle(frame,(i[0],i[1]),i[2],(0,255,0),2)
				# draw the center of the circle
				cv2.circle(frame,(i[0],i[1]),2,(0,0,255),3)

		cv2.imshow("camera", frame)
		cv2.imshow("red image", red_image)
		c = cv2.waitKey(1)

if __name__ == '__main__':
	main()

The result is a function that can largely find red circular objects in a scene.

cv_3A caveat:
This is a crazy basic implementation of color filtering + HoughCircles. As a result, this code only filters for a limited range of red colors, then runs the hough algorithm with fairly loose parameters over the resulting image. Due to this, this code is inflexible in different lightning conditions and is unreliable for the circle detected output. There are several ways to do object detection/color filtering, the intracacies of which I’ll cover another day. ūüôā

Adding new packages directly to python path

As an aside:

When installing libraries for python not through pip install, it’s a good idea to note that the “import” command from python imports from the Python/2.x/site-packages directory. For things like homebrew, you can tell Python where to look for the package by creating symlinks.

For example, when I was trying to link OpenCV installed from Homebrew into my Python path:

cd /Library/Python/2.7/site-packages
ln -s /usr/local/Cellar/opencv/2.4.9/lib/python2.7/site-packages/cv.py cv.py
ln -s /usr/local/Cellar/opencv/2.4.9/lib/python2.7/site-packages/cv.py cv.py

-Sophie

He speaks in thumbtacks.

I never know if I’ll have to wear a helmet when I talk with him. Sometimes, his haphazard words fly like bullets, pelting the air around him with the staccato of indifference. Sometimes his words are exactly what I need, ¬†a sharp jab at the side¬†to pull¬†me¬†back together.

I don’t know if he can feel the thumbtacks spilling out of his mouth when he speaks. Even though he’s mastered positioning the tacks so the sharp ends shoot straight out of his mouth instead of poking him, I know the pins prick his cheek anyway.¬†I¬†wonder if he winces at blood pooling in his mouth, wishing he could speak in feathers.

When he’s careful, his thumbtack arrangements are almost art. He can pin anything together, be it art, ideas, people, dreams. Sit down for a moment with him, and he can arrange fuzzy dreams into color. Come with a broken heart, and he can pin it back into shape. I love watching him talk, watching him pluck¬†ideas from the air and mounting them to reality.

When he’s¬†not careful, he spills his thumbtacks everywhere. He says he doesn’t mean to, but every time he opens his mouth he pours another box of tacks over my head. One cut is nothing, but a hundred little cuts smolder for the next week as I quietly water the fire in my heart with tears. I’m not the first.¬†He will never see my tears, but I wonder¬†if he’s ever watched someone cry with his thumbtacks pinned¬†to their bleeding chest.

He speaks in thumbtacks.¬†And though¬†I know it’s important in keeping everything together,¬†sometimes, I wish he would speak in feathers.

-Sophie

Making Space

Ahhh, it’s beginning again. Breathe in, and you can smell the iCals and the anticipation in the air as Olin gears up for another semester of accomplishments and memories.

As¬†I ink in the white spaces of my calendar with all my plans, I realize that being overcommitted is a very real thing, and that my time is becoming quite a precious commodity.¬†I’m no longer able to throw hours at activities like a teenager with her first credit card. Anything not on my calendar is not on my mind… which is kind of sucky, because God is very clearly not on my calendar.

Prayer has always been an on the spur of the moment sort of thing like other spur of the moment things. I like guitar, so when I have lots of time I play lots of guitar. When I don’t, well, my guitar gets dusty and really flat. But I can’t afford to let my relationship with God get dusty and flat–how else I can make sure I’m building my life the way He wants me to? There’s a saying that if something is important for you, you’ll find a way. If it’s not, you’ll find an excuse.

No more excuses! God is on my calendar, and I’ll have time for Him, even if it means taking a minutes from other places.

-Sophie

One of Us

What if God was one of us?
Just a slob like one of us?
Just a stranger on a bus, trying to make his way home?

-Eric Bazilian (But sung by Joan Osborne)
Music video is kind of creepy–er outdated, but hey, play it in another tab and read this instead of watching it.


I was mulling over a conversation with my mother the other day, when this song came up on a Spotify generated playlist. I liked the melody, so I sought it out and played it a couple more times, before the meaning of the words actually sunk in.

See, when I pray, I’m praying to a great heavenly Father or to a majestic God on his all-powerful cosmic throne.¬†I’d like to think that if God were “one of us”, I’d be able to recognize him right away due to his sheer presence. And if I were to meet him, well, I would most definitely be on my best behavior. If God wanted to borrow a dollar, I’d give him a twenty and tell him not to worry about it.

Yet, what if I couldn’t recognize him? What if God was that man I pretended not to see huddled on that street corner? What if God was the person sleeping under the makeshift igloo on that muddy Cambridge curb? Would God have watched me with sad eyes as I briskly walked by to attend to something more important?

[Read more…]

She’s the sunset air at the beach.

I haven’t taken a photo of a sunset beach yet, but I do have this pretty one of sunset on a mountain! Hope it’ll suffice. ūüôā

IMG_0145 (1)

She reminds me of home. Not my home, or her home, just the idea of “home”. She can talk for ages and I can sit for just as long, basking in the drama of her escapades. As I’ve gotten to know her better, I’ve realized that a few of her stories are tinted blue. When she tells them, I can almost hear the way the words tilt towards the past.

Sometimes, I can catch a glimpse of her soul between the syllables of her tales and the sound of her laughter. It’s exactly the way the ocean bends sunlight at dusk. I’d like to keep looking at the glitter on the horizon, the seafoam on the shore, but the glimpse lasts only a moment before I’m reminded that sunset means its time to return home.

I think, perhaps, she likes the peace of the empty twilight beach, which is why sunset is so clearly demarcated in her stories. So, when she begins to speak with those notes of sunset playing against her breath, I know it’s time to leave her home for mine.

-Sophie

He is a cloud.

I thought it’d be fun to challenge myself to writing every once in a while, even though I don’t really have much to say. So here’s the idea: I’ll pick one person that I know, either personally or tangentially, and write a short passage on them.


The first time I saw him, I had to blink twice because it was almost like he wasn’t there. He was dressed in all black, but I felt like he was see-through. Though he sat in the corner of the cafeteria with his book and his lunch, he was somewhere beyond the quiet din of the college campus.

I wanted to approach him, to see if he was lonely and wanted to chat, but couldn’t find the right words to use. He looked happy enough by himself, though I couldn’t understand why, so much so that my voice felt out of place in his world. As the year passed,¬†he and his book would become a fixture of that corner, as much a constant as the six clocks on the back wall of our cafeteria.

Once, we called him over for some homemade seafood soup. We had to ask twice, because the first time our words drifted away before they could reach him. He came back with a bowl, wordlessly filling it while scooting into a waiting chair. As I watched him eat, all the questions I wanted to ask came floating up.
“What are you reading?”
“How are you doing?”
“Are you lonely?”

However, the wind was blowing him away from me, whipping the questions from my mouth before I got a chance to speak. I wanted to tie this enigma down so I could understand him, but I passed right through him. He was bound by nothing, could be affected by nothing, seemed impervious to this world and all it’s implications. His only variable was a wind, invisible to everyone,¬†yet urgently pushing him towards a¬†future that’ll forever remain a mystery to me.

-Sophie

Automatically updating your website with Git and git-hooks

*This process works with sites hosted on NearlyFreeSpeech.net. I’m not sure how well it’ll work on other hosts, though I assume the process should be similar.

I was jealous of all of my friends with their pretty websites, so I decided that I would go ahead and build my own. Looking into all the options out there, I decided that I’d host my site on NearlyFreeSpeech.net(NFS) because it was cheapest (literally $0.01 a day!), and gave me the most control over my site.

After buying the “justsophie.com” domain, I had nice little space on the internet where I could make myself cozy. I just had to populate it! Typically, updating a site requires one to SSH or FTP assets to the server, which is really annoying if you make lots of changes. And because I’m lazy, I decided to automate this process by using Git hooks. (Laziness FTW :D)

What we have to do is create an empty Git repo on your website with a post-receive hook that will take the updated files and put them in the public facing folder! I’m assuming you know how push/pull, commits, etc work in Git. Let me know if you don’t!

On your computer:
We’ll need to create a new git folder for all the assets of our website. Go on and create a new repo on Github and clone it to your local computer. I’m just going to use this website as an example.

git clone https://github.com/srli/Pomelo

All set for now, let’s go set up the stuff on NFS.
[Read more…]

Color

Finding pictures like this make me really happy to be outside. (I’ll stop taking pictures of flowers someday, haha!)

Color