4

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.

goTAN
  • 587
  • 1
  • 7
  • 15
  • Look at [this link][1], that should do it for you. [1]: http://stackoverflow.com/a/11427501/2194309 – Safir Apr 19 '13 at 10:15
  • Thank you for the link. I tried to use cv::approxPolyDP to detect circles but I did not get very precise results. I still think HoughCircle would give me the best results but I still can't figure out how to use it in my problem. – goTAN Apr 19 '13 at 12:40

1 Answers1

4

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

Abid Rahman K
  • 51,886
  • 31
  • 146
  • 157
  • thank you for the reply, and sorry for the late response.However I still can't get it working.I get: OpenCV Error: Assertion failed (scn == 1 && (dcn == 3 || dcn == 4)) in cvtColor. I also don't understand why you want to convert from Gray to RGB?Should't it be the other way round?However when I try to use COLOR_RGB2GRAY and just display the result I strangly have the image 4 times (smaller) on the right side of the screen. The left side is just noisy (stripes and stuff) – goTAN Apr 23 '13 at 11:01
  • i Loaded the image in grayscale. And I made a BGR copy of that to draw the circle in green color. Or you can load BGR image and convert it into grayscale. Check if your image is loaded correctly. – Abid Rahman K Apr 23 '13 at 11:50
  • You get this error when you try to apply HoughCircles on non-gray scale image. Try `Imgproc.cvtColor(mat, mRgba2, Imgproc.COLOR_BGR2GRAY, 0);` before applying HoughCircle. – Abhijith Oct 18 '17 at 10:31