Detect colored spheres with OpenCV using HSV and HoughCircles

goTAN picture goTAN · Apr 19, 2013 · Viewed 7.3k times · Source

I am trying to detect colored spheres with openCV using an Iphone. For the first test case I was using one single yellow marble with the given code:

cv::Mat thresholdHSV;
cv::Mat imgHSV;

cv::cvtColor(inputFrame, imgHSV, CV_BGR2HSV);

cv::inRange(imgHSV,cv::Scalar(20,100,100),cv::Scalar(30,255,255),thresholdHSV);

std::vector<std::vector<cv::Point> > contours;

findContours(thresholdHSV.clone(), contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);


//Draw them
cv::Mat destinationSource = cv::Mat::zeros(inputFrame.size(), inputFrame.type());
drawContours(destinationSource, contours, -1, cv::Scalar(255,255,255), CV_FILLED);

This gave me already good results: enter image description here

However I will need to detect the circle shape somehow. Ideally I want to apply HoughCircle on however I get the OpenCv error: "Bad argument(the source image must be 8-bit, single-channel).

I also tried to apply

HoughCircles(thresholdHSV, detectedCircles, CV_HOUGH_GRADIENT, 1, thresholdHSV.rows / 8, 200, 100, 0, 0);

but I don't get any result at all.

How can apply HoughCircle on the destinationSource image or is there any other way to detect circular shapes? (I have also to consider when there are more spheres of the same color very close to each other since findContours will find just one countour then)

any help is highly appreciated and thank you for your time.

Answer

Abid Rahman K picture Abid Rahman K · Apr 19, 2013

The error says your input image should be single channel 8-bit image, so color images are not applicable.

Below is a small code for circle detection with HoughCircles (but in Python, but you will understand it).

import cv2
import numpy as np
import sys

img = cv2.imread('img.jpg',0)
if img==None:
    print "cannot open ",filename

else:
    img = cv2.medianBlur(img,5)
    cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)
    circles = cv2.HoughCircles(img,cv2.cv.CV_HOUGH_GRADIENT,1,10,param1=100,param2=30,minRadius=5,maxRadius=50)
    circles = np.uint16(np.around(circles))
    for i in circles[0,:]:
        cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),1) # draw the outer circle
        cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3) # draw the center of the circle

    cv2.imshow('detected circles',cimg)
    cv2.waitKey(0)
    cv2.imwrite('output.png',cimg)
    cv2.destroyAllWindows()

Below is the output :

enter image description here

You can find the C++ code here : https://github.com/Itseez/opencv/blob/master/samples/cpp/houghcircles.cpp