Hough Circle with trackbars

asked 2015-09-20 00:06:30 -0500

SCBEAR gravatar image

updated 2015-09-20 03:13:22 -0500

There are a few parameters in the HoughCirclefunction. Is there a way to use the trackbars to change these parameters? so that I would not need to run the program every time i want to change them.

Thank you.

using opencv 3.0.0 C++ on Ms VS 2013 on Win 8 laptop

#include <sstream>
#include <string>
#include <iostream>
#include <vector>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <opencv\cv.h>
#include <opencv\highgui.h>
#include <stdlib.h>
#include <stdio.h>

using namespace std;
using namespace cv;


int main(int argc, char** argv) {

    //Create a window for trackbars
    namedWindow("Trackbar Window", CV_WINDOW_AUTOSIZE);

    //Create trackbar to change brightness
    int iSliderValue1 = 50;
    createTrackbar("Brightness", "Trackbar Window", &iSliderValue1, 100);

    //Create trackbar to change contrast
    int iSliderValue2 = 50;
    createTrackbar("Contrast", "Trackbar Window", &iSliderValue2, 100);

    int param1 = 100;
    createTrackbar("param1", "Trackbar Window", &param1, 300);

    int param2 = 200;
    createTrackbar("param2", "Trackbar Window", &param2, 300);

    int minR = 0;
    createTrackbar("minRadius", "Trackbar Window", &minR, 300);

    int maxR = 0;
    createTrackbar("maxRadius", "Trackbar Window", &maxR, 300);


    cout << "All trackbars created" << endl;


    Mat src;

    VideoCapture capture;

    //capture.open("GOPR0496.MP4");
    capture.open(0);
    capture.read(src);
    capture.set(CV_CAP_PROP_FRAME_HEIGHT, 480);
    capture.set(CV_CAP_PROP_FRAME_WIDTH, 640);

    cout << "Vidoe opened" << endl;

    if (!src.data) {
        std::cout << "ERROR:\topening image" << std::endl;
        return -1;
    }
    cv::namedWindow("image1", CV_WINDOW_AUTOSIZE);

    cv::namedWindow("image2", CV_WINDOW_AUTOSIZE);

    while (true){

        capture.read(src);

        int iBrightness = iSliderValue1 - 50;
        double dContrast = iSliderValue2 / 50.0;
        src.convertTo(src, -1, dContrast, iBrightness);
        cout << "1" << endl;

        cv::imshow("image1", src);

    Mat src_gray2;
    cvtColor(src, src_gray2, CV_BGR2GRAY);

    GaussianBlur(src_gray2, src_gray2, cv::Size(9, 9), 2, 2);

    vector<Vec3f> circles;
    cout << "2" << endl;

    double dparam1 = param1 / 1.0;
    double dparam2 = param2 / 1.0;
    HoughCircles(src_gray2, circles, CV_HOUGH_GRADIENT,
        2,   // accumulator resolution (size of the image / 2)
        5,  // minimum distance between two circles
        dparam1, // Canny high threshold
        dparam2, // minimum number of votes
        minR, maxR); // min and max radius
    cout << "3" << endl;

    std::cout << circles.size() << std::endl;
    std::cout << "end of test" << std::endl;


    for (size_t i = 0; i < circles.size(); i++)
    {
        Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
        int radius = cvRound(circles[i][2]);
        circle(src, center, 3, Scalar(0, 255, 0), -1, 8, 0);
        // circle outline
        circle(src, center, radius, Scalar(0, 0, 255), 3, 8, 0);
        putText(src, "Circle Found", Point(0, 50), 1,2,Scalar(0, 255, 0),2);
    }

    /*std::vector<cv::Vec3f>::
        const_iterator itc = circles.begin();

    while (itc != circles.end()) {

        cv::circle(src_gray2,
            cv::Point((*itc)[0], (*itc)[1]), // circle centre
            (*itc)[2],       // circle radius
            cv::Scalar(0,0,0), // color
            2);              // thickness

        ++itc;
    }*/

    cv::imshow("image2", src_gray2);
    imshow("image1", src);
    cout << "5" << endl;
    cvWaitKey(33);
    }
    return 0;
}

I have the cout expression to help me with locating the bug. In the window, it is showing like this enter image description here CMD window

And there is a problem with the HoughCircle function.

The code stops at number 2, and after like 10 seconds, it jump to 3 and loop over. I can't see what is the problem. The ... (more)

edit retag flag offensive close merge delete

Comments

1
  • i do not think, there's any real error in your prog, it's just damn slow.
  • using your default values, it detects a good 1000 circles, so try to increase the default values for param1 to ~50 and param2 to ~150 (less circles, will make huge speedup)
  • you probably will need sliders for min/max radius, too !
  • to actually see the circles drawn, you will need another cv::imshow("image1", src); at the end

  • good luck !

berak gravatar imageberak ( 2015-09-20 02:13:02 -0500 )edit

Hi Thank you very very much for your reply Is there anywhere explain how different values of param1 and 2 will affect the number of circles?

Min max radius yes, was only trying on param1 and 2.. but somewhere on the internet, it says if the radius is unknown, put both as 0?

Thank you again

SCBEAR gravatar imageSCBEAR ( 2015-09-20 02:33:24 -0500 )edit
1

btw, docs .

"it says if the radius is unknown, put both as 0" - yes, true.

specifying min/max radius will let you restrict the number of found circles further, so you only keep the ones in the right size.

berak gravatar imageberak ( 2015-09-20 02:42:59 -0500 )edit

Thank you Is it normal to experience lags when detecting circle through the laptop built-in webcam? I used param 1 and 2 = 100 and 150 +- and i experience lags of about 3 seconds. is there a way to reduce such lag? the circle i am detecting is of different radius, i kept both min and max to zero anyway. updated the code above

SCBEAR gravatar imageSCBEAR ( 2015-09-20 03:12:28 -0500 )edit

"Is it normal to experience lags" - yes. though 3 seconds is really unfortunate.

if you can, try to use a smaller image (CAP_PROP_FRAME_HEIGHT/WIDTH) , and again, keep param1 and param2 as high as ever possible

berak gravatar imageberak ( 2015-09-20 03:19:01 -0500 )edit