Opencv detects straight lines, line segments, circles, and rectangles

Source: Internet
Author: User

From: http://blog.csdn.net/byxdaz/archive/2009/12/01/4912136.aspx

 

Detection Line: cvhoughlines, cvhoughlines2

Check circle: cvhoughcircles

Check rectangle: there is no corresponding function in opencv. The following code can detect the rectangle by first finding a straight line and then finding the four lines parallel to the vertical line.

 

Check line code:

/* This is a standalone program. Pass an image name as a first parameter of the program.

Switch between standard and probabilistic Hough transform by changing "# If 1" to "# If 0" and back */

# Include <cv. h>

# Include

# Include <math. h>

 

Int main (INT argc, char ** argv)

{

Const char * filename = argc> = 2? Argv [1]: "pic1.png ";

Iplimage * src = cvloadimage (filename, 0 );

Iplimage * DST;

Iplimage * color_dst;

Cvmemstorage * storage = cvcreatememstorage (0 );

Cvseq * lines = 0;

Int I;

 

If (! SRC)

Return-1;

DST = cvcreateimage (cvgetsize (SRC), 8, 1 );

Color_dst = cvcreateimage (cvgetsize (SRC), 8, 3 );

Cvkan (SRC, DST, 50,200, 3 );

Cvcvtcolor (DST, color_dst, cv_gray2bgr );

# If 0

Lines = cvhoughlines2 (DST, storage, cv_hough_standard, 1, cv_pi/180,100, 0, 0 );

 

For (I = 0; I <min (lines-> total, 100); I ++)

{

Float * line = (float *) cvgetseqelem (lines, I );

Float ROV = line [0];

Float Theta = line [1];

Cvpoint pt1, pt2;

Double A = cos (theta), B = sin (theta );

Double X0 = A * Records, Y0 = B * records;

Pt1.x = cvround (x0 + 1000 * (-B ));

Pt1.y = cvround (y0 + 1000 * ());

Pt2.x = cvround (x0-1000 * (-B ));

Pt2.y = cvround (y0-1000 * ());

Cvline (color_dst, pt1, pt2, cv_rgb (255, 0), 3, cv_aa, 0 );

}

# Else

Lines = cvhoughlines2 (DST, storage, cv_hough_probabilistic, 1, cv_pi/180, 50, 50, 10 );

For (I = 0; I <lines-> total; I ++)

{

Cvpoint * line = (cvpoint *) cvgetseqelem (lines, I );

Cvline (color_dst, line [0], line [1], cv_rgb (255, 0), 3, cv_aa, 0 );

}

# Endif

Cvnamedwindow ("Source", 1 );

Cvshowimage ("Source", Src );

 

Cvnamedwindow ("Hough", 1 );

Cvshowimage ("Hough", color_dst );

 

Cvwaitkey (0 );

 

Return 0;

}

 

 

Check circle code:

# Include <cv. h>

# Include

# Include <math. h>

 

Int main (INT argc, char ** argv)

{

Iplimage * IMG;

If (argc = 2 & (IMG = cvloadimage (argv [1], 1 ))! = 0)

{

Iplimage * gray = cvcreateimage (cvgetsize (IMG), 8, 1 );

Cvmemstorage * storage = cvcreatememstorage (0 );

Cvcvtcolor (IMG, gray, cv_bgr2gray );

Cvsmooth (Gray, gray, cv_gaussian, 9, 9); // smooth it, otherwise a of false circles may be detected

Cvseq * circles = cvhoughcircles (Gray, storage, cv_hough_gradient, 2, gray-> height/4,200,100 );

Int I;

For (I = 0; I <circles-> total; I ++)

{

Float * P = (float *) cvgetseqelem (circles, I );

Cvcircle (IMG, cvpoint (cvround (P [0]), cvround (P [1]), 3, cv_rgb (0,255, 0),-1, 8, 0 );

Cvcircle (IMG, cvpoint (cvround (P [0]), cvround (P [1]), cvround (P [2]), cv_rgb (255, 0, 0), 3, 8, 0 );

}

Cvnamedwindow ("Circles", 1 );

Cvshowimage ("Circles", IMG );

}

Return 0;

}

 

 

Check the rectangle code:

/* Find a rectangle in the Program */

# Ifdef _ CH _

# Pragma package <opencv>

# Endif

 

# Ifndef _ EIC

# Include "cv. H"

# Include "highgui. H"

# Include <stdio. h>

# Include <math. h>

# Include <string. h>

# Endif

 

Int thresh = 50;

Iplimage * IMG = 0;

Iplimage * img0 = 0;

Cvmemstorage * storage = 0;

Cvpoint PT [4];

Const char * wndname = "square detection Demo ";

 

// Helper function:

// Finds a cosine of angle between vectors

// From pt0-> pt1 and from pt0-> pt2

Double angle (cvpoint * pt1, cvpoint * pt2, cvpoint * pt0)

{

Double dx1 = pt1-> X-pt0-> X;

Double dy1 = pt1-> Y-pt0-> Y;

Double dx2 = pt2-> X-pt0-> X;

Double dy2 = pt2-> Y-pt0-> Y;

Return (dx1 * dx2 + dy1 * dy2)/SQRT (dx1 * dx1 + dy1 * dy1) * (dx2 * dx2 + dy2 * dy2) + 1e-10 );

}

 

// Returns sequence of squares detected on the image.

// The sequence is stored in the specified memory storage

Cvseq * findsquares4 (iplimage * IMG, cvmemstorage * storage)

{

Cvseq * contours;

Int I, C, L, n = 11;

Cvsize SZ = cvsize (IMG-> width &-2, IMG-> Height &-2 );

Iplimage * timg = cvcloneimage (IMG); // make a copy of input image

Iplimage * gray = cvcreateimage (SZ, 8, 1 );

Iplimage * Pyr = cvcreateimage (cvsize (SZ. width/2, Sz. Height/2), 8, 3 );

Iplimage * tgray;

Cvseq * result;

Double S, T;

// Create empty sequence that will contain points-

// 4 points per square (the square's vertices)

Cvseq * squares = cvcreateseq (0, sizeof (cvseq), sizeof (cvpoint), storage );

 

// Select the maximum ROI in the image

// With the width and height divisible by 2

Cvsetimageroi (timg, cvrect (0, 0, Sz. Width, Sz. Height ));

// Down-scale and upscale the image to filter out the noise

Cvpyrdown (timg, Pyr, 7 );

Cvpyrup (Pyr, timg, 7 );

Tgray = cvcreateimage (SZ, 8, 1 );

 

// Find squares in every color plane of the image

For (C = 0; C <3; C ++)

{

// Extract the C-th color plane

Cvsetimagecoi (timg, C + 1 );

Cvcopy (timg, tgray, 0 );

// Try several threshold levels

For (L = 0; L <n; l ++)

{

// Hack: Use canny instead of zero threshold level.

// Canny helps to catch squares with gradient shading

If (L = 0)

{

// Apply canny. Take the upper threshold from Slider

// And set the lower to 0 (which forces edges merging)

Cvcanny (tgray, gray, 0, thresh, 5 );

// Maid output to remove potential

// Holes between edge segments

Cvdilate (Gray, gray, 0, 1 );

}

Else

{

// Apply threshold if l! = 0:

// Tgray (x, y) = gray (x, y) <(L + 1) * 255/n? 255: 0

Cvthreshold (tgray, gray, (L + 1) * 255/N, 255, cv_thresh_binary );

}

 

// Find every S and store them all as a list

Cvfindcontours (Gray, storage, & contours, sizeof (cvcontour ),

Cv_retr_list, cv_chain_approx_simple, cvpoint (0, 0 ));

 

// Test each Contour

While (contours)

{

// Approximate contour with accuracy proportional

// To the contour perimeter

Result = cvapproxpoly (contours, sizeof (cvcontour), storage,

Cv_poly_approx_dp, cv1_perimeter (contours) * 0.02, 0 );

// Square contours shocould have 4 vertices after Approximation

// Relatively large area (to filter out noisy contours)

// And be convex.

// Note: absolute value of an area is used because

// Area may be positive or negative-in accordance with

// Contour Orientation

If (result-> total = 4 &&

FABS (cv1_area (result, cv_whole_seq)> 1000 &&

Cvcheck1_convexity (result ))

{

S = 0;

 

For (I = 0; I <5; I ++)

{

// Find minimum angle between joint

// Edges (maximum of cosine)

If (I> = 2)

{

T = FABS (angle (

(Cvpoint *) cvgetseqelem (result, I ),

(Cvpoint *) cvgetseqelem (result, I-2 ),

(Cvpoint *) cvgetseqelem (result, I-1 )));

S = s> T? S: T;

}

}

 

// If cosines of all angles are small

// (All angles are ~ 90 degree) then write quandrange

// Vertices to resultant Sequence

If (S <0.3)

For (I = 0; I <4; I ++)

Cvseqpush (squares,

(Cvpoint *) cvgetseqelem (result, I ));

}

// Take the next Contour

S = S-> h_next;

}

}

}

// Release all the temporary Images

Cvreleaseimage (& gray );

Cvreleaseimage (& Pyr );

Cvreleaseimage (& tgray );

Cvreleaseimage (& timg );

 

Return squares;

}

 

// The function draws all the squares in the image

Void drawsquares (iplimage * IMG, cvseq * squares)

{

Cvseqreader reader;

Iplimage * CPY = cvcloneimage (IMG );

Int I;

// Initialize reader of the sequence

Cvstartreadseq (squares, & reader, 0 );

// Read 4 sequence elements at a time (all vertices of a square)

For (I = 0; I <squares-> total; I + = 4)

{

Cvpoint * rect = pt;

Int COUNT = 4;

 

// Read 4 vertices

Memcpy (PT, reader. PTR, squares-> elem_size );

Cv_next_seq_elem (squares-> elem_size, Reader );

Memcpy (Pt + 1, reader. PTR, squares-> elem_size );

Cv_next_seq_elem (squares-> elem_size, Reader );

Memcpy (Pt + 2, reader. PTR, squares-> elem_size );

Cv_next_seq_elem (squares-> elem_size, Reader );

Memcpy (Pt + 3, reader. PTR, squares-> elem_size );

Cv_next_seq_elem (squares-> elem_size, Reader );

 

// Draw the square as a closed polyline

Cvpolyline (CPY, & rect, & count, 1, 1, cv_rgb (0,255, 0), 3, cv_aa, 0 );

}

 

// Show the resultant image

Cvshowimage (wndname, CPY );

Cvreleaseimage (& CPY );

}

 

Void on_trackbar (int)

{

If (IMG)

Drawsquares (IMG, findsquares4 (IMG, storage ));

}

Char * Names [] = {"pic1.png", "pic2.png", "pic3.png ",

"Pic4.png", "pic5.png", "pic6.png", 0 };

 

Int main (INT argc, char ** argv)

{

Int I, C;

// Create memory storage that will contain in all the dynamic data

Storage = cvcreatememstorage (0 );

For (I = 0; names [I]! = 0; I ++)

{

// Load I-th Image

Img0 = cvloadimage (Names [I], 1 );

If (! Img0)

{

Printf ("couldn't load % s/n", Names [I]);

Continue;

}

IMG = cvcloneimage (img0 );

 

// Create window and a trackbar (slider) with parent "image" and set callback

// (The slider regulates upper threshold, passed to Canny edge detector)

Cvnamedwindow (wndname, 1 );

Cvcreatetrackbar ("kan thresh", wndname, & Thresh, 1000, on_trackbar );

 

// Force the image processing

On_trackbar (0 );

// Wait for key.

// Also the function cvwaitkey takes care of Event Processing

C = cvwaitkey (0 );

// Release both images

Cvreleaseimage (& IMG );

Cvreleaseimage (& img0 );

// Clear memory storage-Reset free space position

Cvclearmemstorage (storage );

If (C = 27)

Break;

}

Cvdestroywindow (wndname );

Return 0;

}

# Ifdef _ EIC

Main (1, "squares. c ");

# Endif

Other reference blogs:

1. http://blog.csdn.net/superdont/article/details/6664254

2. http://hi.baidu.com/%CE%C4%BF%A1%B5%C4%CF%A3%CD%FB/blog/item/3a5cb2079158b304738b65f2.html

# Include <cv. h>
# Include # Include <math. h>

Int main ()
{
Iplimage * SRC;
If (src = cvloadimage ("5.bmp", 1 ))! = 0)
{
Iplimage * DST = cvcreateimage (cvgetsize (SRC), 8, 1 );
Iplimage * color_dst = cvcreateimage (cvgetsize (SRC), 8, 3 );
Cvmemstorage * storage = cvcreatememstorage (0); // The storage detects a line segment. Of course, it can be a matrix series of N * 1. If

The actual number of straight lines is N, so the maximum number of possible lines is returned.
Cvseq * lines = 0;
Int I;
Iplimage * src1 = cvcreateimage (cvsize (SRC-> width, Src-> height), ipl_depth_8u, 1 );

Cvcvtcolor (SRC, src1, cv_bgr2gray); // convert SRC to a grayscale image and save it in src1. Be sure to perform edge detection.

Change to grayscale
Cvcanny (src1, DST, 50,200, 3); // grayscale transformation with parameter 50,200

Cvcvtcolor (DST, color_dst, cv_gray2bgr );
# If 1
Lines = cvhoughlines2 (DST, storage, cv_hough_standard, 1, cv_pi/180,150, 0, 0); // standard Hoff change

The last two parameters are 0. Because line_storage is the memory space, a pointer to the cvseq sequence structure is returned.

For (I = 0; I <lines-> total; I ++)
{
Float * line = (float *) cvgetseqelem (lines, I); // use getseqelem to obtain a straight line
Float ROV = line [0];
Float Theta = line [1]; // For sht and msht (Standard transformation), line [0] Here, line [1] is the distance of rock (pixel-related units)

Precision) and theta (angle accuracy of radian measurement)
Cvpoint pt1, pt2;
Double A = cos (theta), B = sin (theta );
If (FABS (a) <1, 0.001)
{
Pt1.x = pt2.x = cvround (ROV );
Pt1.y = 0;
Pt2.y = color_dst-> height;
}
Else if (FABS (B) <1, 0.001)
{
Pt1.y = pt2.y = cvround (ROV );
Pt1.x = 0;
Pt2.x = color_dst-> width;
}
Else
{
Pt1.x = 0;
Pt1.y = cvround (ROV/B );
Pt2.x = cvround (ROV/);
Pt2.y = 0;
}
Cvline (color_dst, pt1, pt2, cv_rgb (255, 0), 3, 8 );
}
# Else
Lines = cvhoughlines2 (DST, storage, cv_hough_probabilistic, 1, cv_pi/180, 80, 30, 10 );
For (I = 0; I <lines-> total; I ++)
{
Cvpoint * line = (cvpoint *) cvgetseqelem (lines, I );
Cvline (color_dst, line [0], line [1], cv_rgb (255, 0), 3, 8 );
}
# Endif
Cvnamedwindow ("Source", 1 );
Cvshowimage ("Source", Src );

Cvnamedwindow ("Hough", 1 );
Cvshowimage ("Hough", color_dst );

Cvwaitkey (0 );
}
}

Line_storage
The detected Line Segment Storage warehouse. it can be a memory storage warehouse (in this case, a line segment sequence is created in the storage warehouse and returned by the function) or a special type that contains line segment parameters (see below) has a single row/single column matrix (cvmat *). The matrix header is modified by the function so that its Cols/rows contains a group of detected line segments. If line_storage is a matrix and the number of actual line segments exceeds the matrix size, the maximum number of line segments is returned (the line segments are not sorted by length, reliability, or other indicators ).

Method
One of the following variables is the Hough variable:
Cv_hough_standard-traditional or standard Hough transformation. each line segment is represented by two floating point numbers (p, θ), where p is the distance between the line and the origin (0, 0), and the angle between the θ line segment and the x-axis. Therefore, the matrix type must be cv_32fc2 type.

Cv_hough_probabilistic-probabilistic Hough Transformation (if the image contains long linear segmentation, it is more efficient). It returns the line segment instead of the entire line segment. Each split is expressed by the start and end points. Therefore, the matrix (or the sequence created) type is cv_32sc4.

Cv_hough_multi_scale-multi-scale variant of the traditional hough transformation. The line segment is encoded in the same way as cv_hough_standard.
Rock
Distance Precision of pixel-related units
Theta
Angle accuracy of radian Measurement
Threshold
Threshold parameter. If the cumulative value is greater than threshold, the line segment returned by the function.
Param1
Parameters related to the first method:
Do not use (0) for traditional Hough transformations ).
This is the minimum line segment length.
For the multi-scale hough transformation, it is the denominator of the Distance Precision, and the approximate distance precision is, and the precise precision should be ).
Param2
Parameters related to the second method:
Do not use (0) for traditional Hough transformations ).
This parameter indicates the maximum gap between broken line segments in the same line ), that is, when the interval between two broken lines in the same line is less than param2, combine them into one.

For multi-scale hough transformation, it is the denominator of angle precision theta (the approximate angle precision is Theta, and the precise angle should be Theta/param2 ).
The cvhoughlines2 function implements different methods for Line Segment Detection. Example.

3. http://www.opencv.org.cn/index.php/Hough%E7%BA%BF%E6% AE %B5%E6%A3%80%E6%B5%8B

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.