1

So I've been working on recognizing a yoga ball with Hough Circles. Now, when converted to grayscale, it works straight away. Unfortunately, I have to take a more complicated procedure due to there being multiple of these coloured balls and only wanted to detect the blue.

Unfiltered ball:

unfiltered ball

Filtered ball:

filtered ball

Steps of my algorithm:

  1. convert from BGR to HSV
  2. blur the image
  3. filter HSV for only select values (in my case dark blue to light blue due to lighting)
  4. invert the image
  5. use morphology to fill in the part that was lighted
  6. blur again
  7. filter the blur so it's a solid shape instead of unrecognisable blurry grayscale
  8. detect with hough-circles. The MAT is still Grayscale so that isn't the problem.

Code:

#include <iostream>
#include <string>
#include <iomanip>
#include <sstream>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace std;
using namespace cv;

int main(int argc, char *argv[])
{
    // Morphology stuff
    Mat element5(30, 30, CV_8U, Scalar(1));
    int morph_elem = 1; // 2
    int morph_size = 33;// 30
    int morph_operator = 2; // 2
    Mat element = getStructuringElement(morph_elem, Size(2 * morph_size + 1, 2 * morph_size + 1), Point(morph_size, morph_size));
    int const max_operator = 4;
    int const max_elem = 2;
    int const max_kernel_size = 21;
    Mat kernel;
    // Display Windows Name
    namedWindow("Testing Purposes", CV_WINDOW_AUTOSIZE);
    Mat src; // loaded image
    Mat hsv; // changed src into HSV
    Mat Filtered; // filtered w/ inRange for blue ball
    Mat Gray; // gray filter for src
    Mat dst; // destination for canny edge
    Mat detected_edges; // matrix of edges w/ canny
    // thresholds for canny
    int edgeThresh = 45;
    int lowThreshold;
    int const max_lowThreshold = 100;
    src = imread(argv[1]);
    cvtColor(src, Gray, CV_BGR2GRAY);
    cvtColor(src, hsv, CV_BGR2HSV);
    /*
    // CannyEdge Testing
    blur(Gray, detected_edges, Size(3, 3)); // blur the grayimage
    Canny(detected_edges, detected_edges, lowThreshold, lowThreshold * ratio, kernel_size);
    dst = Scalar::all(0);
    src.copyTo( dst, detected_edges);
    imshow(window_name,dst);
    */
    // hsv blur and then thresholds
    blur(hsv,hsv,Size(4, 4), Point(-1, -1));
    inRange(hsv, Scalar(100, 100, 0), Scalar(200, 200, 255), Filtered); //filtering after blur
    vector<Vec3f> circles; //vector for holding info on circles
    // houghcircles - attempts to detect circles in the Filtered image we passed it

    // morphology defintion for Kernel
    bitwise_not(Filtered, Filtered);
    // imwrite("/home/bjacobs/Desktop/Testing.jpg", Filtered);
    imwrite("/home/bjacobs/Desktop/Testingg.jpg", Filtered);
    morphologyEx(Filtered, dst, MORPH_OPEN, element);
    blur(dst, dst, Size(20, 20), Point(-1, -1));
    Mat baw = dst > 128;
    HoughCircles(baw ,circles, CV_HOUGH_GRADIENT, 1, baw.rows/8,200,100,0,0);
    imwrite("/home/bjacobs/Desktop/Testing.jpg", baw);

    // Draw the circles detected onto the SRC file
    for(size_t i = 0; i < circles.size(); i++)
    {
        Point center(cvRound(circles[i][0]), cvRound(circles[i][3]));
        int radius = cvRound(circles[i][2]);
        // circle center
        circle(src, center, 3, Scalar(0, 255, 0), -1, 8, 0);
        // circle outline
        circle(src, center, radius, Scalar(0, 0, 255), 3, 8, 0);
    }
    imwrite("/home/bjacobs/Desktop/Test.jpg", hsv);
    imshow("Testing Purposes", src);
    waitKey(0);
}

I've already read as much as I possibly could online on this matter, and nothing I've found so far has helped. Forgive the sloppy commenting, and there are some failed algorithms included with using Canny Edge detection, so don't pay too much mind to them. Does anyone know of a solution to this detection issue?

4

1 回答 1

0

您可以执行以下操作,而不是使用 houghcircle。

  1. 分割蓝色。

  2. 找到轮廓(最大)。

  3. 轮廓的最小封闭圆。

于 2014-02-09T11:04:03.573 回答