Opencv: Detect Color And Draw Line On Color
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:
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:
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:
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:
Post a Comment for "Opencv: Detect Color And Draw Line On Color"