mirror of
https://github.com/opencv/opencv.git
synced 2025-06-07 17:44:04 +08:00
Tutorial Hough Lines
This commit is contained in:
parent
d99ced6ec8
commit
9a2317e063
@ -1,12 +1,15 @@
|
||||
Hough Line Transform {#tutorial_hough_lines}
|
||||
====================
|
||||
|
||||
@prev_tutorial{tutorial_canny_detector}
|
||||
@next_tutorial{tutorial_hough_circle}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
In this tutorial you will learn how to:
|
||||
|
||||
- Use the OpenCV functions @ref cv::HoughLines and @ref cv::HoughLinesP to detect lines in an
|
||||
- Use the OpenCV functions **HoughLines()** and **HoughLinesP()** to detect lines in an
|
||||
image.
|
||||
|
||||
Theory
|
||||
@ -79,54 +82,93 @@ a. **The Standard Hough Transform**
|
||||
|
||||
- It consists in pretty much what we just explained in the previous section. It gives you as
|
||||
result a vector of couples \f$(\theta, r_{\theta})\f$
|
||||
- In OpenCV it is implemented with the function @ref cv::HoughLines
|
||||
- In OpenCV it is implemented with the function **HoughLines()**
|
||||
|
||||
b. **The Probabilistic Hough Line Transform**
|
||||
|
||||
- A more efficient implementation of the Hough Line Transform. It gives as output the extremes
|
||||
of the detected lines \f$(x_{0}, y_{0}, x_{1}, y_{1})\f$
|
||||
- In OpenCV it is implemented with the function @ref cv::HoughLinesP
|
||||
- In OpenCV it is implemented with the function **HoughLinesP()**
|
||||
|
||||
### What does this program do?
|
||||
- Loads an image
|
||||
- Applies a *Standard Hough Line Transform* and a *Probabilistic Line Transform*.
|
||||
- Display the original image and the detected line in three windows.
|
||||
|
||||
Code
|
||||
----
|
||||
|
||||
-# **What does this program do?**
|
||||
- Loads an image
|
||||
- Applies either a *Standard Hough Line Transform* or a *Probabilistic Line Transform*.
|
||||
- Display the original image and the detected line in two windows.
|
||||
@add_toggle_cpp
|
||||
The sample code that we will explain can be downloaded from
|
||||
[here](https://raw.githubusercontent.com/opencv/opencv/master/samples/cpp/tutorial_code/ImgTrans/houghlines.cpp).
|
||||
A slightly fancier version (which shows both Hough standard and probabilistic
|
||||
with trackbars for changing the threshold values) can be found
|
||||
[here](https://raw.githubusercontent.com/opencv/opencv/master/samples/cpp/tutorial_code/ImgTrans/HoughLines_Demo.cpp).
|
||||
@include samples/cpp/tutorial_code/ImgTrans/houghlines.cpp
|
||||
@end_toggle
|
||||
|
||||
-# The sample code that we will explain can be downloaded from [here](https://github.com/opencv/opencv/tree/master/samples/cpp/houghlines.cpp). A slightly fancier version
|
||||
(which shows both Hough standard and probabilistic with trackbars for changing the threshold
|
||||
values) can be found [here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ImgTrans/HoughLines_Demo.cpp).
|
||||
@include samples/cpp/houghlines.cpp
|
||||
@add_toggle_java
|
||||
The sample code that we will explain can be downloaded from
|
||||
[here](https://raw.githubusercontent.com/opencv/opencv/master/samples/java/tutorial_code/ImgTrans/HoughLine/HoughLines.java).
|
||||
@include samples/java/tutorial_code/ImgTrans/HoughLine/HoughLines.java
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
The sample code that we will explain can be downloaded from
|
||||
[here](https://raw.githubusercontent.com/opencv/opencv/master/samples/python/tutorial_code/ImgTrans/HoughLine/hough_lines.py).
|
||||
@include samples/python/tutorial_code/ImgTrans/HoughLine/hough_lines.py
|
||||
@end_toggle
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
|
||||
-# Load an image
|
||||
@code{.cpp}
|
||||
Mat src = imread(filename, 0);
|
||||
if(src.empty())
|
||||
{
|
||||
help();
|
||||
cout << "can not open " << filename << endl;
|
||||
return -1;
|
||||
}
|
||||
@endcode
|
||||
-# Detect the edges of the image by using a Canny detector
|
||||
@code{.cpp}
|
||||
Canny(src, dst, 50, 200, 3);
|
||||
@endcode
|
||||
Now we will apply the Hough Line Transform. We will explain how to use both OpenCV functions
|
||||
available for this purpose:
|
||||
#### Load an image:
|
||||
|
||||
-# **Standard Hough Line Transform**
|
||||
-# First, you apply the Transform:
|
||||
@code{.cpp}
|
||||
vector<Vec2f> lines;
|
||||
HoughLines(dst, lines, 1, CV_PI/180, 100, 0, 0 );
|
||||
@endcode
|
||||
with the following arguments:
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgTrans/houghlines.cpp load
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ImgTrans/HoughLine/HoughLines.java load
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ImgTrans/HoughLine/hough_lines.py load
|
||||
@end_toggle
|
||||
|
||||
#### Detect the edges of the image by using a Canny detector:
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgTrans/houghlines.cpp edge_detection
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ImgTrans/HoughLine/HoughLines.java edge_detection
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ImgTrans/HoughLine/hough_lines.py edge_detection
|
||||
@end_toggle
|
||||
|
||||
Now we will apply the Hough Line Transform. We will explain how to use both OpenCV functions
|
||||
available for this purpose.
|
||||
|
||||
#### Standard Hough Line Transform:
|
||||
First, you apply the Transform:
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgTrans/houghlines.cpp hough_lines
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ImgTrans/HoughLine/HoughLines.java hough_lines
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ImgTrans/HoughLine/hough_lines.py hough_lines
|
||||
@end_toggle
|
||||
|
||||
- with the following arguments:
|
||||
|
||||
- *dst*: Output of the edge detector. It should be a grayscale image (although in fact it
|
||||
is a binary one)
|
||||
@ -137,28 +179,35 @@ Explanation
|
||||
- *threshold*: The minimum number of intersections to "*detect*" a line
|
||||
- *srn* and *stn*: Default parameters to zero. Check OpenCV reference for more info.
|
||||
|
||||
-# And then you display the result by drawing the lines.
|
||||
@code{.cpp}
|
||||
for( size_t i = 0; i < lines.size(); i++ )
|
||||
{
|
||||
float rho = lines[i][0], theta = lines[i][1];
|
||||
Point pt1, pt2;
|
||||
double a = cos(theta), b = sin(theta);
|
||||
double x0 = a*rho, y0 = b*rho;
|
||||
pt1.x = cvRound(x0 + 1000*(-b));
|
||||
pt1.y = cvRound(y0 + 1000*(a));
|
||||
pt2.x = cvRound(x0 - 1000*(-b));
|
||||
pt2.y = cvRound(y0 - 1000*(a));
|
||||
line( cdst, pt1, pt2, Scalar(0,0,255), 3, LINE_AA);
|
||||
}
|
||||
@endcode
|
||||
-# **Probabilistic Hough Line Transform**
|
||||
-# First you apply the transform:
|
||||
@code{.cpp}
|
||||
vector<Vec4i> lines;
|
||||
HoughLinesP(dst, lines, 1, CV_PI/180, 50, 50, 10 );
|
||||
@endcode
|
||||
with the arguments:
|
||||
And then you display the result by drawing the lines.
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgTrans/houghlines.cpp draw_lines
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ImgTrans/HoughLine/HoughLines.java draw_lines
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ImgTrans/HoughLine/hough_lines.py draw_lines
|
||||
@end_toggle
|
||||
|
||||
#### Probabilistic Hough Line Transform
|
||||
First you apply the transform:
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgTrans/houghlines.cpp hough_lines_p
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ImgTrans/HoughLine/HoughLines.java hough_lines_p
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ImgTrans/HoughLine/hough_lines.py hough_lines_p
|
||||
@end_toggle
|
||||
|
||||
- with the arguments:
|
||||
|
||||
- *dst*: Output of the edge detector. It should be a grayscale image (although in fact it
|
||||
is a binary one)
|
||||
@ -172,23 +221,47 @@ Explanation
|
||||
this number of points are disregarded.
|
||||
- *maxLineGap*: The maximum gap between two points to be considered in the same line.
|
||||
|
||||
-# And then you display the result by drawing the lines.
|
||||
@code{.cpp}
|
||||
for( size_t i = 0; i < lines.size(); i++ )
|
||||
{
|
||||
Vec4i l = lines[i];
|
||||
line( cdst, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 3, LINE_AA);
|
||||
}
|
||||
@endcode
|
||||
-# Display the original image and the detected lines:
|
||||
@code{.cpp}
|
||||
imshow("source", src);
|
||||
imshow("detected lines", cdst);
|
||||
@endcode
|
||||
-# Wait until the user exits the program
|
||||
@code{.cpp}
|
||||
waitKey();
|
||||
@endcode
|
||||
And then you display the result by drawing the lines.
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgTrans/houghlines.cpp draw_lines_p
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ImgTrans/HoughLine/HoughLines.java draw_lines_p
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ImgTrans/HoughLine/hough_lines.py draw_lines_p
|
||||
@end_toggle
|
||||
|
||||
#### Display the original image and the detected lines:
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgTrans/houghlines.cpp imshow
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ImgTrans/HoughLine/HoughLines.java imshow
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ImgTrans/HoughLine/hough_lines.py imshow
|
||||
@end_toggle
|
||||
|
||||
#### Wait until the user exits the program
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgTrans/houghlines.cpp exit
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ImgTrans/HoughLine/HoughLines.java exit
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ImgTrans/HoughLine/hough_lines.py exit
|
||||
@end_toggle
|
||||
|
||||
Result
|
||||
------
|
||||
@ -198,13 +271,11 @@ Result
|
||||
section. It still implements the same stuff as above, only adding the Trackbar for the
|
||||
Threshold.
|
||||
|
||||
Using an input image such as:
|
||||
|
||||

|
||||
|
||||
We get the following result by using the Probabilistic Hough Line Transform:
|
||||
|
||||

|
||||
Using an input image such as a [sudoku image](https://raw.githubusercontent.com/opencv/opencv/master/samples/data/sudoku.png).
|
||||
We get the following result by using the Standard Hough Line Transform:
|
||||

|
||||
And by using the Probabilistic Hough Line Transform:
|
||||

|
||||
|
||||
You may observe that the number of lines detected vary while you change the *threshold*. The
|
||||
explanation is sort of evident: If you establish a higher threshold, fewer lines will be detected
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 66 KiB |
Binary file not shown.
After Width: | Height: | Size: 61 KiB |
@ -125,6 +125,8 @@ In this section you will learn about the image processing (manipulation) functio
|
||||
|
||||
- @subpage tutorial_hough_lines
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Ana Huamán
|
||||
|
@ -1,77 +0,0 @@
|
||||
#include "opencv2/imgcodecs.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
static void help()
|
||||
{
|
||||
cout << "\nThis program demonstrates line finding with the Hough transform.\n"
|
||||
"Usage:\n"
|
||||
"./houghlines <image_name>, Default is ../data/pic1.png\n" << endl;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
cv::CommandLineParser parser(argc, argv,
|
||||
"{help h||}{@image|../data/pic1.png|}"
|
||||
);
|
||||
if (parser.has("help"))
|
||||
{
|
||||
help();
|
||||
return 0;
|
||||
}
|
||||
string filename = parser.get<string>("@image");
|
||||
if (filename.empty())
|
||||
{
|
||||
help();
|
||||
cout << "no image_name provided" << endl;
|
||||
return -1;
|
||||
}
|
||||
Mat src = imread(filename, 0);
|
||||
if(src.empty())
|
||||
{
|
||||
help();
|
||||
cout << "can not open " << filename << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Mat dst, cdst;
|
||||
Canny(src, dst, 50, 200, 3);
|
||||
cvtColor(dst, cdst, COLOR_GRAY2BGR);
|
||||
|
||||
#if 0
|
||||
vector<Vec2f> lines;
|
||||
HoughLines(dst, lines, 1, CV_PI/180, 100, 0, 0 );
|
||||
|
||||
for( size_t i = 0; i < lines.size(); i++ )
|
||||
{
|
||||
float rho = lines[i][0], theta = lines[i][1];
|
||||
Point pt1, pt2;
|
||||
double a = cos(theta), b = sin(theta);
|
||||
double x0 = a*rho, y0 = b*rho;
|
||||
pt1.x = cvRound(x0 + 1000*(-b));
|
||||
pt1.y = cvRound(y0 + 1000*(a));
|
||||
pt2.x = cvRound(x0 - 1000*(-b));
|
||||
pt2.y = cvRound(y0 - 1000*(a));
|
||||
line( cdst, pt1, pt2, Scalar(0,0,255), 3, CV_AA);
|
||||
}
|
||||
#else
|
||||
vector<Vec4i> lines;
|
||||
HoughLinesP(dst, lines, 1, CV_PI/180, 50, 50, 10 );
|
||||
for( size_t i = 0; i < lines.size(); i++ )
|
||||
{
|
||||
Vec4i l = lines[i];
|
||||
line( cdst, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 3, LINE_AA);
|
||||
}
|
||||
#endif
|
||||
imshow("source", src);
|
||||
imshow("detected lines", cdst);
|
||||
|
||||
waitKey();
|
||||
|
||||
return 0;
|
||||
}
|
89
samples/cpp/tutorial_code/ImgTrans/houghlines.cpp
Normal file
89
samples/cpp/tutorial_code/ImgTrans/houghlines.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
/**
|
||||
* @file houghclines.cpp
|
||||
* @brief This program demonstrates line finding with the Hough transform
|
||||
*/
|
||||
|
||||
#include "opencv2/imgcodecs.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
// Declare the output variables
|
||||
Mat dst, cdst, cdstP;
|
||||
|
||||
//![load]
|
||||
const char* default_file = "../../../data/sudoku.png";
|
||||
const char* filename = argc >=2 ? argv[1] : default_file;
|
||||
|
||||
// Loads an image
|
||||
Mat src = imread( filename, IMREAD_GRAYSCALE );
|
||||
|
||||
// Check if image is loaded fine
|
||||
if(src.empty()){
|
||||
printf(" Error opening image\n");
|
||||
printf(" Program Arguments: [image_name -- default %s] \n", default_file);
|
||||
return -1;
|
||||
}
|
||||
//![load]
|
||||
|
||||
//![edge_detection]
|
||||
// Edge detection
|
||||
Canny(src, dst, 50, 200, 3);
|
||||
//![edge_detection]
|
||||
|
||||
// Copy edges to the images that will display the results in BGR
|
||||
cvtColor(dst, cdst, COLOR_GRAY2BGR);
|
||||
cdstP = cdst.clone();
|
||||
|
||||
//![hough_lines]
|
||||
// Standard Hough Line Transform
|
||||
vector<Vec2f> lines; // will hold the results of the detection
|
||||
HoughLines(dst, lines, 1, CV_PI/180, 150, 0, 0 ); // runs the actual detection
|
||||
//![hough_lines]
|
||||
//![draw_lines]
|
||||
// Draw the lines
|
||||
for( size_t i = 0; i < lines.size(); i++ )
|
||||
{
|
||||
float rho = lines[i][0], theta = lines[i][1];
|
||||
Point pt1, pt2;
|
||||
double a = cos(theta), b = sin(theta);
|
||||
double x0 = a*rho, y0 = b*rho;
|
||||
pt1.x = cvRound(x0 + 1000*(-b));
|
||||
pt1.y = cvRound(y0 + 1000*(a));
|
||||
pt2.x = cvRound(x0 - 1000*(-b));
|
||||
pt2.y = cvRound(y0 - 1000*(a));
|
||||
line( cdst, pt1, pt2, Scalar(0,0,255), 3, CV_AA);
|
||||
}
|
||||
//![draw_lines]
|
||||
|
||||
//![hough_lines_p]
|
||||
// Probabilistic Line Transform
|
||||
vector<Vec4i> linesP; // will hold the results of the detection
|
||||
HoughLinesP(dst, linesP, 1, CV_PI/180, 50, 50, 10 ); // runs the actual detection
|
||||
//![hough_lines_p]
|
||||
//![draw_lines_p]
|
||||
// Draw the lines
|
||||
for( size_t i = 0; i < linesP.size(); i++ )
|
||||
{
|
||||
Vec4i l = linesP[i];
|
||||
line( cdstP, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 3, LINE_AA);
|
||||
}
|
||||
//![draw_lines_p]
|
||||
|
||||
//![imshow]
|
||||
// Show results
|
||||
imshow("Source", src);
|
||||
imshow("Detected Lines (in red) - Standard Hough Line Transform", cdst);
|
||||
imshow("Detected Lines (in red) - Probabilistic Line Transform", cdstP);
|
||||
//![imshow]
|
||||
|
||||
//![exit]
|
||||
// Wait and Exit
|
||||
waitKey();
|
||||
return 0;
|
||||
//![exit]
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
/**
|
||||
* @file HoughLines.java
|
||||
* @brief This program demonstrates line finding with the Hough transform
|
||||
*/
|
||||
|
||||
import org.opencv.core.*;
|
||||
import org.opencv.core.Point;
|
||||
import org.opencv.highgui.HighGui;
|
||||
import org.opencv.imgcodecs.Imgcodecs;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
|
||||
class HoughLinesRun {
|
||||
|
||||
public void run(String[] args) {
|
||||
// Declare the output variables
|
||||
Mat dst = new Mat(), cdst = new Mat(), cdstP;
|
||||
|
||||
//! [load]
|
||||
String default_file = "../../../../data/sudoku.png";
|
||||
String filename = ((args.length > 0) ? args[0] : default_file);
|
||||
|
||||
// Load an image
|
||||
Mat src = Imgcodecs.imread(filename, Imgcodecs.IMREAD_GRAYSCALE);
|
||||
|
||||
// Check if image is loaded fine
|
||||
if( src.empty() ) {
|
||||
System.out.println("Error opening image!");
|
||||
System.out.println("Program Arguments: [image_name -- default "
|
||||
+ default_file +"] \n");
|
||||
System.exit(-1);
|
||||
}
|
||||
//! [load]
|
||||
|
||||
//! [edge_detection]
|
||||
// Edge detection
|
||||
Imgproc.Canny(src, dst, 50, 200, 3, false);
|
||||
//! [edge_detection]
|
||||
|
||||
// Copy edges to the images that will display the results in BGR
|
||||
Imgproc.cvtColor(dst, cdst, Imgproc.COLOR_GRAY2BGR);
|
||||
cdstP = cdst.clone();
|
||||
|
||||
//! [hough_lines]
|
||||
// Standard Hough Line Transform
|
||||
Mat lines = new Mat(); // will hold the results of the detection
|
||||
Imgproc.HoughLines(dst, lines, 1, Math.PI/180, 150); // runs the actual detection
|
||||
//! [hough_lines]
|
||||
//! [draw_lines]
|
||||
// Draw the lines
|
||||
for (int x = 0; x < lines.rows(); x++) {
|
||||
double rho = lines.get(x, 0)[0],
|
||||
theta = lines.get(x, 0)[1];
|
||||
|
||||
double a = Math.cos(theta), b = Math.sin(theta);
|
||||
double x0 = a*rho, y0 = b*rho;
|
||||
Point pt1 = new Point(Math.round(x0 + 1000*(-b)), Math.round(y0 + 1000*(a)));
|
||||
Point pt2 = new Point(Math.round(x0 - 1000*(-b)), Math.round(y0 - 1000*(a)));
|
||||
Imgproc.line(cdst, pt1, pt2, new Scalar(0, 0, 255), 3, Imgproc.LINE_AA, 0);
|
||||
}
|
||||
//! [draw_lines]
|
||||
|
||||
//! [hough_lines_p]
|
||||
// Probabilistic Line Transform
|
||||
Mat linesP = new Mat(); // will hold the results of the detection
|
||||
Imgproc.HoughLinesP(dst, linesP, 1, Math.PI/180, 50, 50, 10); // runs the actual detection
|
||||
//! [hough_lines_p]
|
||||
//! [draw_lines_p]
|
||||
// Draw the lines
|
||||
for (int x = 0; x < linesP.rows(); x++) {
|
||||
double[] l = linesP.get(x, 0);
|
||||
Imgproc.line(cdstP, new Point(l[0], l[1]), new Point(l[2], l[3]), new Scalar(0, 0, 255), 3, Imgproc.LINE_AA, 0);
|
||||
}
|
||||
//! [draw_lines_p]
|
||||
|
||||
//! [imshow]
|
||||
// Show results
|
||||
HighGui.imshow("Source", src);
|
||||
HighGui.imshow("Detected Lines (in red) - Standard Hough Line Transform", cdst);
|
||||
HighGui.imshow("Detected Lines (in red) - Probabilistic Line Transform", cdstP);
|
||||
//! [imshow]
|
||||
|
||||
//! [exit]
|
||||
// Wait and Exit
|
||||
HighGui.waitKey();
|
||||
System.exit(0);
|
||||
//! [exit]
|
||||
}
|
||||
}
|
||||
|
||||
public class HoughLines {
|
||||
public static void main(String[] args) {
|
||||
// Load the native library.
|
||||
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
|
||||
new HoughLinesRun().run(args);
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
"""
|
||||
@file hough_lines.py
|
||||
@brief This program demonstrates line finding with the Hough transform
|
||||
"""
|
||||
import sys
|
||||
import math
|
||||
import cv2
|
||||
import numpy as np
|
||||
|
||||
|
||||
def main(argv):
|
||||
## [load]
|
||||
default_file = "../../../../data/sudoku.png"
|
||||
filename = argv[0] if len(argv) > 0 else default_file
|
||||
|
||||
# Loads an image
|
||||
src = cv2.imread(filename, cv2.IMREAD_GRAYSCALE)
|
||||
|
||||
# Check if image is loaded fine
|
||||
if src is None:
|
||||
print ('Error opening image!')
|
||||
print ('Usage: hough_lines.py [image_name -- default ' + default_file + '] \n')
|
||||
return -1
|
||||
## [load]
|
||||
|
||||
## [edge_detection]
|
||||
# Edge detection
|
||||
dst = cv2.Canny(src, 50, 200, None, 3)
|
||||
## [edge_detection]
|
||||
|
||||
# Copy edges to the images that will display the results in BGR
|
||||
cdst = cv2.cvtColor(dst, cv2.COLOR_GRAY2BGR)
|
||||
cdstP = np.copy(cdst)
|
||||
|
||||
## [hough_lines]
|
||||
# Standard Hough Line Transform
|
||||
lines = cv2.HoughLines(dst, 1, np.pi / 180, 150, None, 0, 0)
|
||||
## [hough_lines]
|
||||
## [draw_lines]
|
||||
# Draw the lines
|
||||
if lines is not None:
|
||||
for i in range(0, len(lines)):
|
||||
rho = lines[i][0][0]
|
||||
theta = lines[i][0][1]
|
||||
a = math.cos(theta)
|
||||
b = math.sin(theta)
|
||||
x0 = a * rho
|
||||
y0 = b * rho
|
||||
pt1 = (int(x0 + 1000*(-b)), int(y0 + 1000*(a)))
|
||||
pt2 = (int(x0 - 1000*(-b)), int(y0 - 1000*(a)))
|
||||
|
||||
cv2.line(cdst, pt1, pt2, (0,0,255), 3, cv2.LINE_AA)
|
||||
## [draw_lines]
|
||||
|
||||
## [hough_lines_p]
|
||||
# Probabilistic Line Transform
|
||||
linesP = cv2.HoughLinesP(dst, 1, np.pi / 180, 50, None, 50, 10)
|
||||
## [hough_lines_p]
|
||||
## [draw_lines_p]
|
||||
# Draw the lines
|
||||
if linesP is not None:
|
||||
for i in range(0, len(linesP)):
|
||||
l = linesP[i][0]
|
||||
cv2.line(cdstP, (l[0], l[1]), (l[2], l[3]), (0,0,255), 3, cv2.LINE_AA)
|
||||
## [draw_lines_p]
|
||||
## [imshow]
|
||||
# Show results
|
||||
cv2.imshow("Source", src)
|
||||
cv2.imshow("Detected Lines (in red) - Standard Hough Line Transform", cdst)
|
||||
cv2.imshow("Detected Lines (in red) - Probabilistic Line Transform", cdstP)
|
||||
## [imshow]
|
||||
## [exit]
|
||||
# Wait and Exit
|
||||
cv2.waitKey()
|
||||
return 0
|
||||
## [exit]
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv[1:])
|
Loading…
Reference in New Issue
Block a user