Skip to content Skip to sidebar Skip to footer

Opencv: Detect Color And Draw Line On Color

My application is going to calculate the bounce height of the battery, I intend to use the blue strip to define the 'base' in which i use to calculate the number of pixels away it

Solution 1:

You can perform color filtering with the built-in OpenCV method inRange() which will allow you to create a mask containing white wherever any pixel values fall between a defined lower bound and upper bound, and black otherwise. From there you can simply find the location of the white pixels in the mask.

Refer to this tutorial for an example.

Also, my previous answer here gives some suggestions for finding good lower and upper bounds---in particular, find an area in an image you know (like the one linked) with the color you want, and find the mean and standard deviation of those values (in any colorspace, but I would probably suggest starting with HSV or HLS). Then you can easily set the lower bound to mean-a*stddev and upper bound to mean+b*stddev where a and b are some values you can experiment with to see what works best at selecting the blue (and only the blue). You can start with a=b and use integer values for them (1, 2, 3, ...) and hone in from there.

Once you have the mask, it's likely you'll have a few holes in it or extraneous white pixels elsewhere in the image. You can use contour detection, Hough line detection, or blob detection to get the correct rectangle. In this case, I would suggest using contour detection on the mask with findContours(), find the largest contour, find the boundingRect around it, and that will give you the pixel locations directly.


Python example

You're working in C++ but Python is faster for giving examples, so you'll have to translate. I'll use a resized version of your first image:

Starting image

import numpy as np
import cv2

img = cv2.imread('image.jpg')
img = cv2.resize(img, None, fx=0.1, fy=0.1)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
roi = hsv[430:450, 20:170]

Here I'm just resizing the image (mostly so I can display it easily), converting the colorspace, and defining a region of interest (ROI) that only includes blue pixels. In BGR, the ROI looks like this:

Blue ROI

This ROI contains only blue pixels, so I can find the mean blue value, and the standard deviation of the blue values to use as the values for inRange().

mu, sig = cv2.meanStdDev(roi)
a = 9

blue_mask = cv2.inRange(hsv, mu-a*sig, mu+a*sig)

Thus we have a mask of just the blue values:

Blue mask

From here you can do your normal contour detection and find the bounding box around it:

_, contours, _ = cv2.findContours(blue_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
x, y, w, h = cv2.boundingRect(contours[0])
cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)

And now we have a bounding rectangle (we have the location of the upper left corner, and the width and height) around the litmus paper in the original image:

Detected blue

Post a Comment for "Opencv: Detect Color And Draw Line On Color"