diff --git a/doc/tutorials/imgproc/generalized_hough_ballard_guil/generalized_hough_ballard_guil.markdown b/doc/tutorials/imgproc/generalized_hough_ballard_guil/generalized_hough_ballard_guil.markdown new file mode 100644 index 0000000000..edf18b3844 --- /dev/null +++ b/doc/tutorials/imgproc/generalized_hough_ballard_guil/generalized_hough_ballard_guil.markdown @@ -0,0 +1,92 @@ +Object detection with Generalized Ballard and Guil Hough Transform {#tutorial_generalized_hough_ballard_guil} +================================================================== + +@tableofcontents + +@prev_tutorial{tutorial_hough_circle} +@next_tutorial{tutorial_remap} + +Goal +---- + +In this tutorial you will learn how to: + +- Use @ref cv::GeneralizedHoughBallard and @ref cv::GeneralizedHoughGuil to detect an object + +Example +------- + +### What does this program do? + +1. Load the image and template + +![image](images/generalized_hough_mini_image.jpg) +![template](images/generalized_hough_mini_template.jpg) + +2. Instantiate @ref cv::GeneralizedHoughBallard with the help of `createGeneralizedHoughBallard()` +3. Instantiate @ref cv::GeneralizedHoughGuil with the help of `createGeneralizedHoughGuil()` +4. Set the required parameters for both GeneralizedHough variants +5. Detect and show found results + +@note +- Both variants can't be instantiated directly. Using the create methods is required. +- Guil Hough is very slow. Calculating the results for the "mini" files used in this tutorial + takes only a few seconds. With image and template in a higher resolution, as shown below, + my notebook requires about 5 minutes to calculate a result. + +![image](images/generalized_hough_image.jpg) +![template](images/generalized_hough_template.jpg) + +### Code + +The complete code for this tutorial is shown below. +@include samples/cpp/tutorial_code/ImgTrans/generalizedHoughTransform.cpp + +Explanation +----------- + +### Load image, template and setup variables + +@snippet samples/cpp/tutorial_code/ImgTrans/generalizedHoughTransform.cpp generalized-hough-transform-load-and-setup + +The position vectors will contain the matches the detectors will find. +Every entry contains four floating point values: +position vector + +- *[0]*: x coordinate of center point +- *[1]*: y coordinate of center point +- *[2]*: scale of detected object compared to template +- *[3]*: rotation of detected object in degree in relation to template + +An example could look as follows: `[200, 100, 0.9, 120]` + +### Setup parameters + +@snippet samples/cpp/tutorial_code/ImgTrans/generalizedHoughTransform.cpp generalized-hough-transform-setup-parameters + +Finding the optimal values can end up in trial and error and depends on many factors, such as the image resolution. + +### Run detection + +@snippet samples/cpp/tutorial_code/ImgTrans/generalizedHoughTransform.cpp generalized-hough-transform-run + +As mentioned above, this step will take some time, especially with larger images and when using Guil. + +### Draw results and show image + +@snippet samples/cpp/tutorial_code/ImgTrans/generalizedHoughTransform.cpp generalized-hough-transform-draw-results + +Result +------ + +![result image](images/generalized_hough_result_img.jpg) + +The blue rectangle shows the result of @ref cv::GeneralizedHoughBallard and the green rectangles the results of @ref +cv::GeneralizedHoughGuil. + +Getting perfect results like in this example is unlikely if the parameters are not perfectly adapted to the sample. +An example with less perfect parameters is shown below. +For the Ballard variant, only the center of the result is marked as a black dot on this image. The rectangle would be +the same as on the previous image. + +![less perfect result](images/generalized_hough_less_perfect_result_img.jpg) diff --git a/doc/tutorials/imgproc/generalized_hough_ballard_guil/images/generalized_hough_image.jpg b/doc/tutorials/imgproc/generalized_hough_ballard_guil/images/generalized_hough_image.jpg new file mode 100644 index 0000000000..06f53823b2 Binary files /dev/null and b/doc/tutorials/imgproc/generalized_hough_ballard_guil/images/generalized_hough_image.jpg differ diff --git a/doc/tutorials/imgproc/generalized_hough_ballard_guil/images/generalized_hough_less_perfect_result_img.jpg b/doc/tutorials/imgproc/generalized_hough_ballard_guil/images/generalized_hough_less_perfect_result_img.jpg new file mode 100644 index 0000000000..4f6bf315a8 Binary files /dev/null and b/doc/tutorials/imgproc/generalized_hough_ballard_guil/images/generalized_hough_less_perfect_result_img.jpg differ diff --git a/doc/tutorials/imgproc/generalized_hough_ballard_guil/images/generalized_hough_mini_image.jpg b/doc/tutorials/imgproc/generalized_hough_ballard_guil/images/generalized_hough_mini_image.jpg new file mode 100644 index 0000000000..bcc8b9e414 Binary files /dev/null and b/doc/tutorials/imgproc/generalized_hough_ballard_guil/images/generalized_hough_mini_image.jpg differ diff --git a/doc/tutorials/imgproc/generalized_hough_ballard_guil/images/generalized_hough_mini_template.jpg b/doc/tutorials/imgproc/generalized_hough_ballard_guil/images/generalized_hough_mini_template.jpg new file mode 100644 index 0000000000..69ab30eed3 Binary files /dev/null and b/doc/tutorials/imgproc/generalized_hough_ballard_guil/images/generalized_hough_mini_template.jpg differ diff --git a/doc/tutorials/imgproc/generalized_hough_ballard_guil/images/generalized_hough_result_img.jpg b/doc/tutorials/imgproc/generalized_hough_ballard_guil/images/generalized_hough_result_img.jpg new file mode 100644 index 0000000000..782f730fbc Binary files /dev/null and b/doc/tutorials/imgproc/generalized_hough_ballard_guil/images/generalized_hough_result_img.jpg differ diff --git a/doc/tutorials/imgproc/generalized_hough_ballard_guil/images/generalized_hough_template.jpg b/doc/tutorials/imgproc/generalized_hough_ballard_guil/images/generalized_hough_template.jpg new file mode 100644 index 0000000000..393db734ef Binary files /dev/null and b/doc/tutorials/imgproc/generalized_hough_ballard_guil/images/generalized_hough_template.jpg differ diff --git a/doc/tutorials/imgproc/imgtrans/hough_circle/hough_circle.markdown b/doc/tutorials/imgproc/imgtrans/hough_circle/hough_circle.markdown index 497215794b..0a2ba8843e 100644 --- a/doc/tutorials/imgproc/imgtrans/hough_circle/hough_circle.markdown +++ b/doc/tutorials/imgproc/imgtrans/hough_circle/hough_circle.markdown @@ -2,7 +2,7 @@ Hough Circle Transform {#tutorial_hough_circle} ====================== @prev_tutorial{tutorial_hough_lines} -@next_tutorial{tutorial_remap} +@next_tutorial{tutorial_generalized_hough_ballard_guil} Goal ---- diff --git a/doc/tutorials/imgproc/imgtrans/remap/remap.markdown b/doc/tutorials/imgproc/imgtrans/remap/remap.markdown index ac2b879171..eb34be4bb1 100644 --- a/doc/tutorials/imgproc/imgtrans/remap/remap.markdown +++ b/doc/tutorials/imgproc/imgtrans/remap/remap.markdown @@ -1,7 +1,7 @@ Remapping {#tutorial_remap} ========= -@prev_tutorial{tutorial_hough_circle} +@prev_tutorial{tutorial_generalized_hough_ballard_guil} @next_tutorial{tutorial_warp_affine} Goal diff --git a/doc/tutorials/imgproc/table_of_content_imgproc.markdown b/doc/tutorials/imgproc/table_of_content_imgproc.markdown index b0a8b8260b..9545cd2155 100644 --- a/doc/tutorials/imgproc/table_of_content_imgproc.markdown +++ b/doc/tutorials/imgproc/table_of_content_imgproc.markdown @@ -173,6 +173,16 @@ In this section you will learn about the image processing (manipulation) functio Where we learn how to detect circles +- @subpage tutorial_generalized_hough_ballard_guil + + *Languages:* C++ + + *Compatibility:* \>= OpenCV 3.4 + + *Author:* Markus Heck + + Detect an object in a picture with the help of GeneralizedHoughBallard and GeneralizedHoughGuil. + - @subpage tutorial_remap *Languages:* C++, Java, Python diff --git a/doc/tutorials/objdetect/traincascade.markdown b/doc/tutorials/objdetect/traincascade.markdown index d78de2ec9a..1528c02211 100644 --- a/doc/tutorials/objdetect/traincascade.markdown +++ b/doc/tutorials/objdetect/traincascade.markdown @@ -3,6 +3,7 @@ Cascade Classifier Training {#tutorial_traincascade} @prev_tutorial{tutorial_cascade_classifier} + Introduction ------------ diff --git a/samples/cpp/tutorial_code/ImgTrans/generalizedHoughTransform.cpp b/samples/cpp/tutorial_code/ImgTrans/generalizedHoughTransform.cpp new file mode 100644 index 0000000000..dca52b1339 --- /dev/null +++ b/samples/cpp/tutorial_code/ImgTrans/generalizedHoughTransform.cpp @@ -0,0 +1,108 @@ +/** + @file generalizedHoughTransform.cpp + @author Markus Heck + @brief Detects an object, given by a template, in an image using GeneralizedHoughBallard and GeneralizedHoughGuil. +*/ + +#include "opencv2/highgui.hpp" +#include "opencv2/imgproc.hpp" + +using namespace cv; +using namespace std; + +int main() { + //! [generalized-hough-transform-load-and-setup] +// load source image and grayscale template + Mat image = imread("images/generalized_hough_mini_image.jpg"); + Mat templ = imread("images/generalized_hough_mini_template.jpg", IMREAD_GRAYSCALE); + +// create grayscale image + Mat grayImage; + cvtColor(image, grayImage, COLOR_RGB2GRAY); + +// create variable for location, scale and rotation of detected templates + vector positionBallard, positionGuil; + +// template width and height + int w = templ.cols; + int h = templ.rows; + //! [generalized-hough-transform-load-and-setup] + + + //! [generalized-hough-transform-setup-parameters] +// create ballard and set options + Ptr ballard = createGeneralizedHoughBallard(); + ballard->setMinDist(10); + ballard->setLevels(360); + ballard->setDp(2); + ballard->setMaxBufferSize(1000); + ballard->setVotesThreshold(40); + + ballard->setCannyLowThresh(30); + ballard->setCannyHighThresh(110); + ballard->setTemplate(templ); + + +// create guil and set options + Ptr guil = createGeneralizedHoughGuil(); + guil->setMinDist(10); + guil->setLevels(360); + guil->setDp(3); + guil->setMaxBufferSize(1000); + + guil->setMinAngle(0); + guil->setMaxAngle(360); + guil->setAngleStep(1); + guil->setAngleThresh(1500); + + guil->setMinScale(0.5); + guil->setMaxScale(2.0); + guil->setScaleStep(0.05); + guil->setScaleThresh(50); + + guil->setPosThresh(10); + + guil->setCannyLowThresh(30); + guil->setCannyHighThresh(110); + + guil->setTemplate(templ); + //! [generalized-hough-transform-setup-parameters] + + + //! [generalized-hough-transform-run] +// execute ballard detection + ballard->detect(grayImage, positionBallard); +// execute guil detection + guil->detect(grayImage, positionGuil); + //! [generalized-hough-transform-run] + + + //! [generalized-hough-transform-draw-results] +// draw ballard + for (vector::iterator iter = positionBallard.begin(); iter != positionBallard.end(); ++iter) { + RotatedRect rRect = RotatedRect(Point2f((*iter)[0], (*iter)[1]), + Size2f(w * (*iter)[2], h * (*iter)[2]), + (*iter)[3]); + Point2f vertices[4]; + rRect.points(vertices); + for (int i = 0; i < 4; i++) + line(image, vertices[i], vertices[(i + 1) % 4], Scalar(255, 0, 0), 6); + } + +// draw guil + for (vector::iterator iter = positionGuil.begin(); iter != positionGuil.end(); ++iter) { + RotatedRect rRect = RotatedRect(Point2f((*iter)[0], (*iter)[1]), + Size2f(w * (*iter)[2], h * (*iter)[2]), + (*iter)[3]); + Point2f vertices[4]; + rRect.points(vertices); + for (int i = 0; i < 4; i++) + line(image, vertices[i], vertices[(i + 1) % 4], Scalar(0, 255, 0), 2); + } + + imshow("result_img", image); + waitKey(); + //! [generalized-hough-transform-draw-results] + + return EXIT_SUCCESS; +} \ No newline at end of file