Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
944588e7
Commit
944588e7
authored
Feb 12, 2013
by
Vadim Pisarevsky
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
converted houghlines to C++
parent
7f8c9253
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
203 additions
and
648 deletions
+203
-648
perf_houghLines.cpp
modules/imgproc/perf/perf_houghLines.cpp
+1
-0
_list.h
modules/imgproc/src/_list.h
+0
-374
hough.cpp
modules/imgproc/src/hough.cpp
+199
-274
test_houghLines.cpp
modules/imgproc/test/test_houghLines.cpp
+3
-0
No files found.
modules/imgproc/perf/perf_houghLines.cpp
View file @
944588e7
...
...
@@ -36,5 +36,6 @@ PERF_TEST_P(Image_RhoStep_ThetaStep_Threshold, HoughLines,
TEST_CYCLE
()
HoughLines
(
image
,
lines
,
rhoStep
,
thetaStep
,
threshold
);
transpose
(
lines
,
lines
);
SANITY_CHECK
(
lines
);
}
modules/imgproc/src/_list.h
deleted
100644 → 0
View file @
7f8c9253
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef _CV_LIST_H_
#define _CV_LIST_H_
#include <stdlib.h>
#include <assert.h>
#define CV_FORCE_INLINE CV_INLINE
#if !defined(_LIST_INLINE)
#define _LIST_INLINE CV_FORCE_INLINE
#endif
/*_LIST_INLINE*/
#if defined DECLARE_LIST
#if defined _MSC_VER && _MSC_VER >= 1200
#pragma warning("DECLARE_LIST macro is already defined!")
#endif
#endif
/*DECLARE_LIST*/
static
const
long
default_size
=
10
;
static
const
long
default_inc_size
=
10
;
struct
_pos
{
void
*
m_pos
;
#ifdef _DEBUG
struct
_list
*
m_list
;
#endif
/*_DEBUG*/
};
typedef
struct
_pos
CVPOS
;
struct
_list
{
void
*
m_buffer
;
void
*
m_first_buffer
;
long
m_buf_size
;
/* The size of the buffer */
long
m_size
;
/* The number of elements */
CVPOS
m_head
;
CVPOS
m_tail
;
CVPOS
m_head_free
;
};
typedef
struct
_list
_CVLIST
;
#define DECLARE_LIST(type, prefix)\
/* Basic element of a list*/
\
struct prefix##element_##type\
{\
struct prefix##element_##type* m_prev;\
struct prefix##element_##type* m_next;\
type m_data;\
};\
typedef struct prefix##element_##type ELEMENT_##type;\
/* Initialization and destruction*/
\
_LIST_INLINE _CVLIST* prefix##create_list_##type(long);\
_LIST_INLINE void prefix##destroy_list_##type(_CVLIST*);\
/* Access functions*/
\
_LIST_INLINE CVPOS prefix##get_head_pos_##type(_CVLIST*);\
_LIST_INLINE CVPOS prefix##get_tail_pos_##type(_CVLIST*);\
_LIST_INLINE type* prefix##get_next_##type(CVPOS*);\
_LIST_INLINE type* prefix##get_prev_##type(CVPOS*);\
_LIST_INLINE int prefix##is_pos_##type(CVPOS pos);\
/* Modification functions*/
\
_LIST_INLINE void prefix##clear_list_##type(_CVLIST*);\
_LIST_INLINE CVPOS prefix##add_head_##type(_CVLIST*, type*);\
_LIST_INLINE CVPOS prefix##add_tail_##type(_CVLIST*, type*);\
_LIST_INLINE void prefix##remove_head_##type(_CVLIST*);\
_LIST_INLINE void prefix##remove_tail_##type(_CVLIST*);\
_LIST_INLINE CVPOS prefix##insert_before_##type(_CVLIST*, CVPOS, type*);\
_LIST_INLINE CVPOS prefix##insert_after_##type(_CVLIST*, CVPOS, type*);\
_LIST_INLINE void prefix##remove_at_##type(_CVLIST*, CVPOS);\
_LIST_INLINE void prefix##set_##type(CVPOS, type*);\
_LIST_INLINE type* prefix##get_##type(CVPOS);\
/* Statistics functions*/
\
_LIST_INLINE int prefix##get_count_##type(_CVLIST*);
/* This macro finds a space for a new element and puts in into 'element' pointer */
#define INSERT_NEW(element_type, l, element)\
l->m_size++;\
if(l->m_head_free.m_pos != NULL)\
{\
element = (element_type*)(l->m_head_free.m_pos);\
if(element->m_next != NULL)\
{\
element->m_next->m_prev = NULL;\
l->m_head_free.m_pos = element->m_next;\
}\
else\
{\
l->m_head_free.m_pos = NULL;\
}\
}\
else\
{\
if(l->m_buf_size < l->m_size && l->m_head_free.m_pos == NULL)\
{\
*(void**)l->m_buffer = cvAlloc(l->m_buf_size*sizeof(element_type) + sizeof(void*));\
l->m_buffer = *(void**)l->m_buffer;\
*(void**)l->m_buffer = NULL;\
element = (element_type*)((char*)l->m_buffer + sizeof(void*));\
}\
else\
{\
element = (element_type*)((char*)l->m_buffer + sizeof(void*)) + l->m_size - 1;\
}\
}
/* This macro adds 'element' to the list of free elements*/
#define INSERT_FREE(element_type, l, element)\
if(l->m_head_free.m_pos != NULL)\
{\
((element_type*)l->m_head_free.m_pos)->m_prev = element;\
}\
element->m_next = ((element_type*)l->m_head_free.m_pos);\
l->m_head_free.m_pos = element;
/*#define GET_FIRST_FREE(l) ((ELEMENT_##type*)(l->m_head_free.m_pos))*/
#define IMPLEMENT_LIST(type, prefix)\
_CVLIST* prefix##create_list_##type(long size)\
{\
_CVLIST* pl = (_CVLIST*)cvAlloc(sizeof(_CVLIST));\
pl->m_buf_size = size > 0 ? size : default_size;\
pl->m_first_buffer = cvAlloc(pl->m_buf_size*sizeof(ELEMENT_##type) + sizeof(void*));\
pl->m_buffer = pl->m_first_buffer;\
*(void**)pl->m_buffer = NULL;\
pl->m_size = 0;\
pl->m_head.m_pos = NULL;\
pl->m_tail.m_pos = NULL;\
pl->m_head_free.m_pos = NULL;\
return pl;\
}\
void prefix##destroy_list_##type(_CVLIST* l)\
{\
void* cur = l->m_first_buffer;\
void* next;\
while(cur)\
{\
next = *(void**)cur;\
cvFree(&cur);\
cur = next;\
}\
cvFree(&l);\
}\
CVPOS prefix##get_head_pos_##type(_CVLIST* l)\
{\
return l->m_head;\
}\
CVPOS prefix##get_tail_pos_##type(_CVLIST* l)\
{\
return l->m_tail;\
}\
type* prefix##get_next_##type(CVPOS* pos)\
{\
if(pos->m_pos)\
{\
ELEMENT_##type* element = (ELEMENT_##type*)(pos->m_pos);\
pos->m_pos = element->m_next;\
return &element->m_data;\
}\
else\
{\
return NULL;\
}\
}\
type* prefix##get_prev_##type(CVPOS* pos)\
{\
if(pos->m_pos)\
{\
ELEMENT_##type* element = (ELEMENT_##type*)(pos->m_pos);\
pos->m_pos = element->m_prev;\
return &element->m_data;\
}\
else\
{\
return NULL;\
}\
}\
int prefix##is_pos_##type(CVPOS pos)\
{\
return !!pos.m_pos;\
}\
void prefix##clear_list_##type(_CVLIST* l)\
{\
l->m_head.m_pos = NULL;\
l->m_tail.m_pos = NULL;\
l->m_size = 0;\
l->m_head_free.m_pos = NULL;\
}\
CVPOS prefix##add_head_##type(_CVLIST* l, type* data)\
{\
ELEMENT_##type* element;\
INSERT_NEW(ELEMENT_##type, l, element);\
element->m_prev = NULL;\
element->m_next = (ELEMENT_##type*)(l->m_head.m_pos);\
memcpy(&(element->m_data), data, sizeof(*data));\
if(element->m_next)\
{\
element->m_next->m_prev = element;\
}\
else\
{\
l->m_tail.m_pos = element;\
}\
l->m_head.m_pos = element;\
return l->m_head;\
}\
CVPOS prefix##add_tail_##type(_CVLIST* l, type* data)\
{\
ELEMENT_##type* element;\
INSERT_NEW(ELEMENT_##type, l, element);\
element->m_next = NULL;\
element->m_prev = (ELEMENT_##type*)(l->m_tail.m_pos);\
memcpy(&(element->m_data), data, sizeof(*data));\
if(element->m_prev)\
{\
element->m_prev->m_next = element;\
}\
else\
{\
l->m_head.m_pos = element;\
}\
l->m_tail.m_pos = element;\
return l->m_tail;\
}\
void prefix##remove_head_##type(_CVLIST* l)\
{\
ELEMENT_##type* element = ((ELEMENT_##type*)(l->m_head.m_pos));\
if(element->m_next != NULL)\
{\
element->m_next->m_prev = NULL;\
}\
l->m_head.m_pos = element->m_next;\
INSERT_FREE(ELEMENT_##type, l, element);\
l->m_size--;\
}\
void prefix##remove_tail_##type(_CVLIST* l)\
{\
ELEMENT_##type* element = ((ELEMENT_##type*)(l->m_tail.m_pos));\
if(element->m_prev != NULL)\
{\
element->m_prev->m_next = NULL;\
}\
l->m_tail.m_pos = element->m_prev;\
INSERT_FREE(ELEMENT_##type, l, element);\
l->m_size--;\
}\
CVPOS prefix##insert_after_##type(_CVLIST* l, CVPOS pos, type* data)\
{\
ELEMENT_##type* element;\
ELEMENT_##type* before;\
CVPOS newpos;\
INSERT_NEW(ELEMENT_##type, l, element);\
memcpy(&(element->m_data), data, sizeof(*data));\
before = (ELEMENT_##type*)pos.m_pos;\
element->m_prev = before;\
element->m_next = before->m_next;\
before->m_next = element;\
if(element->m_next != NULL)\
element->m_next->m_prev = element;\
else\
l->m_tail.m_pos = element;\
newpos.m_pos = element;\
return newpos;\
}\
CVPOS prefix##insert_before_##type(_CVLIST* l, CVPOS pos, type* data)\
{\
ELEMENT_##type* element;\
ELEMENT_##type* after;\
CVPOS newpos;\
INSERT_NEW(ELEMENT_##type, l, element);\
memcpy(&(element->m_data), data, sizeof(*data));\
after = (ELEMENT_##type*)pos.m_pos;\
element->m_prev = after->m_prev;\
element->m_next = after;\
after->m_prev = element;\
if(element->m_prev != NULL)\
element->m_prev->m_next = element;\
else\
l->m_head.m_pos = element;\
newpos.m_pos = element;\
return newpos;\
}\
void prefix##remove_at_##type(_CVLIST* l, CVPOS pos)\
{\
ELEMENT_##type* element = ((ELEMENT_##type*)pos.m_pos);\
if(element->m_prev != NULL)\
{\
element->m_prev->m_next = element->m_next;\
}\
else\
{\
l->m_head.m_pos = element->m_next;\
}\
if(element->m_next != NULL)\
{\
element->m_next->m_prev = element->m_prev;\
}\
else\
{\
l->m_tail.m_pos = element->m_prev;\
}\
INSERT_FREE(ELEMENT_##type, l, element);\
l->m_size--;\
}\
void prefix##set_##type(CVPOS pos, type* data)\
{\
ELEMENT_##type* element = ((ELEMENT_##type*)(pos.m_pos));\
memcpy(&(element->m_data), data, sizeof(*data));\
}\
type* prefix##get_##type(CVPOS pos)\
{\
ELEMENT_##type* element = ((ELEMENT_##type*)(pos.m_pos));\
return &(element->m_data);\
}\
int prefix##get_count_##type(_CVLIST* list)\
{\
return list->m_size;\
}
#define DECLARE_AND_IMPLEMENT_LIST(type, prefix)\
DECLARE_LIST(type, prefix)\
IMPLEMENT_LIST(type, prefix)
typedef
struct
__index
{
int
value
;
float
rho
,
theta
;
}
_index
;
DECLARE_LIST
(
_index
,
h_
)
#endif
/*_CV_LIST_H_*/
modules/imgproc/src/hough.cpp
View file @
944588e7
...
...
@@ -40,37 +40,25 @@
//M*/
#include "precomp.hpp"
#include "_list.h"
#define halfPi ((float)(CV_PI*0.5))
#define Pi ((float)CV_PI)
#define a0 0
/*-4.172325e-7f*/
/*(-(float)0x7)/((float)0x1000000); */
#define a1 1.000025f
/*((float)0x1922253)/((float)0x1000000)*2/Pi; */
#define a2 -2.652905e-4f
/*(-(float)0x2ae6)/((float)0x1000000)*4/(Pi*Pi); */
#define a3 -0.165624f
/*(-(float)0xa45511)/((float)0x1000000)*8/(Pi*Pi*Pi); */
#define a4 -1.964532e-3f
/*(-(float)0x30fd3)/((float)0x1000000)*16/(Pi*Pi*Pi*Pi); */
#define a5 1.02575e-2f
/*((float)0x191cac)/((float)0x1000000)*32/(Pi*Pi*Pi*Pi*Pi); */
#define a6 -9.580378e-4f
/*(-(float)0x3af27)/((float)0x1000000)*64/(Pi*Pi*Pi*Pi*Pi*Pi); */
#define _sin(x) ((((((a6*(x) + a5)*(x) + a4)*(x) + a3)*(x) + a2)*(x) + a1)*(x) + a0)
#define _cos(x) _sin(halfPi - (x))
/****************************************************************************************\
* Classical Hough Transform *
\****************************************************************************************/
namespace
cv
{
typedef
struct
CvLinePolar
// Classical Hough Transform
struct
LinePolar
{
float
rho
;
float
angle
;
}
CvLinePolar
;
};
/*=====================================================================================*/
#define hough_cmp_gt(l1,l2) (aux[l1] > aux[l2])
struct
hough_cmp_gt
{
hough_cmp_gt
(
const
int
*
_aux
)
:
aux
(
_aux
)
{}
bool
operator
()(
int
l1
,
int
l2
)
const
{
return
aux
[
l1
]
>
aux
[
l2
];
}
const
int
*
aux
;
};
static
CV_IMPLEMENT_QSORT_EX
(
icvHoughSortDescent32s
,
int
,
hough_cmp_gt
,
const
int
*
)
/*
Here image is an input raster;
...
...
@@ -82,34 +70,27 @@ array of (rho, theta) pairs. linesMax is the buffer size (number of pairs).
Functions return the actual number of found lines.
*/
static
void
icvHoughLinesStandard
(
const
CvMat
*
img
,
float
rho
,
float
theta
,
int
threshold
,
CvSeq
*
lines
,
int
linesMax
)
HoughLinesStandard
(
const
Mat
&
img
,
float
rho
,
float
theta
,
int
threshold
,
vector
<
Vec2f
>&
lines
,
int
linesMax
)
{
cv
::
AutoBuffer
<
int
>
_accum
,
_sort_buf
;
cv
::
AutoBuffer
<
float
>
_tabSin
,
_tabCos
;
const
uchar
*
image
;
int
step
,
width
,
height
;
int
numangle
,
numrho
;
int
total
=
0
;
int
i
,
j
;
float
irho
=
1
/
rho
;
double
scale
;
CV_Assert
(
CV_IS_MAT
(
img
)
&&
CV_MAT_TYPE
(
img
->
type
)
==
CV_8UC1
);
CV_Assert
(
img
.
type
(
)
==
CV_8UC1
);
image
=
img
->
data
.
ptr
;
step
=
img
->
step
;
width
=
img
->
cols
;
height
=
img
->
rows
;
const
uchar
*
image
=
img
.
data
;
int
step
=
(
int
)
img
.
step
;
int
width
=
img
.
cols
;
int
height
=
img
.
rows
;
numangle
=
cvRound
(
CV_PI
/
theta
);
numrho
=
cvRound
(((
width
+
height
)
*
2
+
1
)
/
rho
);
int
numangle
=
cvRound
(
CV_PI
/
theta
);
int
numrho
=
cvRound
(((
width
+
height
)
*
2
+
1
)
/
rho
);
_accum
.
allocate
((
numangle
+
2
)
*
(
numrho
+
2
));
_sort_buf
.
allocate
(
numangle
*
numrho
);
_tabSin
.
allocate
(
numangle
);
_tabCos
.
allocate
(
numangle
);
AutoBuffer
<
int
>
_accum
((
numangle
+
2
)
*
(
numrho
+
2
));
AutoBuffer
<
int
>
_sort_buf
(
numangle
*
numrho
);
AutoBuffer
<
float
>
_tabSin
(
numangle
);
AutoBuffer
<
float
>
_tabCos
(
numangle
);
int
*
accum
=
_accum
,
*
sort_buf
=
_sort_buf
;
float
*
tabSin
=
_tabSin
,
*
tabCos
=
_tabCos
;
...
...
@@ -147,122 +128,104 @@ icvHoughLinesStandard( const CvMat* img, float rho, float theta,
}
// stage 3. sort the detected lines by accumulator value
icvHoughSortDescent32s
(
sort_buf
,
total
,
accum
);
std
::
sort
(
sort_buf
,
sort_buf
+
total
,
hough_cmp_gt
(
accum
)
);
// stage 4. store the first min(total,linesMax) lines to the output buffer
linesMax
=
MIN
(
linesMax
,
total
);
scale
=
1.
/
(
numrho
+
2
);
double
scale
=
1.
/
(
numrho
+
2
);
for
(
i
=
0
;
i
<
linesMax
;
i
++
)
{
Cv
LinePolar
line
;
LinePolar
line
;
int
idx
=
sort_buf
[
i
];
int
n
=
cvFloor
(
idx
*
scale
)
-
1
;
int
r
=
idx
-
(
n
+
1
)
*
(
numrho
+
2
)
-
1
;
line
.
rho
=
(
r
-
(
numrho
-
1
)
*
0.5
f
)
*
rho
;
line
.
angle
=
n
*
theta
;
cvSeqPush
(
lines
,
&
line
);
lines
.
push_back
(
Vec2f
(
line
.
rho
,
line
.
angle
)
);
}
}
/****************************************************************************************\
* Multi-Scale variant of Classical Hough Transform *
\****************************************************************************************/
// Multi-Scale variant of Classical Hough Transform
struct
hough_index
{
hough_index
()
:
value
(
0
),
rho
(
0.
f
),
theta
(
0.
f
)
{}
hough_index
(
int
_val
,
float
_rho
,
float
_theta
)
:
value
(
_val
),
rho
(
_rho
),
theta
(
_theta
)
{}
int
value
;
float
rho
,
theta
;
};
//DECLARE_AND_IMPLEMENT_LIST( _index, h_ );
IMPLEMENT_LIST
(
_index
,
h_
)
static
void
icvHoughLinesSDiv
(
const
CvMat
*
img
,
HoughLinesSDiv
(
const
Mat
&
img
,
float
rho
,
float
theta
,
int
threshold
,
int
srn
,
int
stn
,
CvSeq
*
lines
,
int
linesMax
)
vector
<
Vec2f
>&
lines
,
int
linesMax
)
{
std
::
vector
<
uchar
>
_caccum
,
_buffer
;
std
::
vector
<
float
>
_sinTable
;
std
::
vector
<
int
>
_x
,
_y
;
float
*
sinTable
;
int
*
x
,
*
y
;
uchar
*
caccum
,
*
buffer
;
_CVLIST
*
list
=
0
;
#define _POINT(row, column)\
#define _POINT(row, column)\
(image_src[(row)*step+(column)])
uchar
*
mcaccum
=
0
;
int
rn
,
tn
;
/* number of rho and theta discrete values */
int
index
,
i
;
int
ri
,
ti
,
ti1
,
ti0
;
int
row
,
col
;
float
r
,
t
;
/* Current rho and theta */
float
rv
;
/* Some temporary rho value */
float
irho
;
float
itheta
;
float
srho
,
stheta
;
float
isrho
,
istheta
;
const
uchar
*
image_src
;
int
w
,
h
,
step
;
int
fn
=
0
;
float
xc
,
yc
;
const
float
d2r
=
(
float
)(
Pi
/
180
);
const
float
d2r
=
(
float
)(
CV_PI
/
180
);
int
sfn
=
srn
*
stn
;
int
fi
;
int
count
;
int
cmax
=
0
;
CVPOS
pos
;
_index
*
pindex
;
_index
vi
;
vector
<
hough_index
>
lst
;
CV_Assert
(
CV_IS_MAT
(
img
)
&&
CV_MAT_TYPE
(
img
->
type
)
==
CV_8UC1
);
CV_Assert
(
img
.
type
(
)
==
CV_8UC1
);
CV_Assert
(
linesMax
>
0
&&
rho
>
0
&&
theta
>
0
);
threshold
=
MIN
(
threshold
,
255
);
image_src
=
img
->
data
.
ptr
;
step
=
img
->
step
;
w
=
img
->
cols
;
h
=
img
->
rows
;
const
uchar
*
image_src
=
img
.
data
;
int
step
=
(
int
)
img
.
step
;
int
w
=
img
.
cols
;
int
h
=
img
.
rows
;
irho
=
1
/
rho
;
itheta
=
1
/
theta
;
srho
=
rho
/
srn
;
stheta
=
theta
/
stn
;
isrho
=
1
/
srho
;
istheta
=
1
/
stheta
;
float
irho
=
1
/
rho
;
float
itheta
=
1
/
theta
;
float
srho
=
rho
/
srn
;
float
stheta
=
theta
/
stn
;
float
isrho
=
1
/
srho
;
float
istheta
=
1
/
stheta
;
rn
=
cvFloor
(
sqrt
(
(
double
)
w
*
w
+
(
double
)
h
*
h
)
*
irho
);
tn
=
cvFloor
(
2
*
Pi
*
itheta
);
int
rn
=
cvFloor
(
sqrt
(
(
double
)
w
*
w
+
(
double
)
h
*
h
)
*
irho
);
int
tn
=
cvFloor
(
2
*
CV_PI
*
itheta
);
list
=
h_create_list__index
(
linesMax
<
1000
?
linesMax
:
1000
);
vi
.
value
=
threshold
;
vi
.
rho
=
-
1
;
h_add_head__index
(
list
,
&
vi
);
lst
.
push_back
(
hough_index
(
threshold
,
-
1.
f
,
0.
f
));
/
* Precalculating sin */
_sinTable
.
resiz
e
(
5
*
tn
*
stn
);
sinTable
=
&
_sinTable
[
0
];
/
/ Precalculate sin table
vector
<
float
>
_sinTabl
e
(
5
*
tn
*
stn
);
float
*
sinTable
=
&
_sinTable
[
0
];
for
(
index
=
0
;
index
<
5
*
tn
*
stn
;
index
++
)
sinTable
[
index
]
=
(
float
)
cos
(
stheta
*
index
*
0.2
f
);
_caccum
.
resize
(
rn
*
tn
);
caccum
=
&
_caccum
[
0
];
memset
(
caccum
,
0
,
rn
*
tn
*
sizeof
(
caccum
[
0
]
));
vector
<
uchar
>
_caccum
(
rn
*
tn
,
(
uchar
)
0
);
uchar
*
caccum
=
&
_caccum
[
0
];
/
* Counting all feature pixels */
/
/ Counting all feature pixels
for
(
row
=
0
;
row
<
h
;
row
++
)
for
(
col
=
0
;
col
<
w
;
col
++
)
fn
+=
_POINT
(
row
,
col
)
!=
0
;
_x
.
resize
(
fn
);
_y
.
resize
(
fn
);
x
=
&
_x
[
0
];
y
=
&
_y
[
0
];
vector
<
int
>
_x
(
fn
),
_y
(
fn
);
int
*
x
=
&
_x
[
0
],
*
y
=
&
_y
[
0
];
/
* Full Hough Transform (it's accumulator update part) */
/
/ Full Hough Transform (it's accumulator update part)
fi
=
0
;
for
(
row
=
0
;
row
<
h
;
row
++
)
{
...
...
@@ -275,9 +238,9 @@ icvHoughLinesSDiv( const CvMat* img,
float
scale_factor
;
int
iprev
=
-
1
;
float
phi
,
phi1
;
float
theta_it
;
/
* Value of theta for iterating */
float
theta_it
;
/
/ Value of theta for iterating
/
* Remember the feature point */
/
/ Remember the feature point
x
[
fi
]
=
col
;
y
[
fi
]
=
row
;
fi
++
;
...
...
@@ -289,18 +252,18 @@ icvHoughLinesSDiv( const CvMat* img,
t
=
(
float
)
fabs
(
cvFastArctan
(
yc
,
xc
)
*
d2r
);
r
=
(
float
)
sqrt
(
(
double
)
xc
*
xc
+
(
double
)
yc
*
yc
);
r0
=
r
*
irho
;
ti0
=
cvFloor
(
(
t
+
Pi
/
2
)
*
itheta
);
ti0
=
cvFloor
(
(
t
+
CV_PI
*
0.5
)
*
itheta
);
caccum
[
ti0
]
++
;
theta_it
=
rho
/
r
;
theta_it
=
theta_it
<
theta
?
theta_it
:
theta
;
scale_factor
=
theta_it
*
itheta
;
halftn
=
cvFloor
(
Pi
/
theta_it
);
for
(
ti1
=
1
,
phi
=
theta_it
-
halfPi
,
phi1
=
(
theta_it
+
t
)
*
itheta
;
halftn
=
cvFloor
(
CV_PI
/
theta_it
);
for
(
ti1
=
1
,
phi
=
theta_it
-
(
float
)(
CV_PI
*
0.5
)
,
phi1
=
(
theta_it
+
t
)
*
itheta
;
ti1
<
halftn
;
ti1
++
,
phi
+=
theta_it
,
phi1
+=
scale_factor
)
{
rv
=
r0
*
_
cos
(
phi
);
rv
=
r0
*
std
::
cos
(
phi
);
i
=
cvFloor
(
rv
)
*
tn
;
i
+=
cvFloor
(
phi1
);
assert
(
i
>=
0
);
...
...
@@ -314,28 +277,26 @@ icvHoughLinesSDiv( const CvMat* img,
}
}
/
* Starting additional analysis */
/
/ Starting additional analysis
count
=
0
;
for
(
ri
=
0
;
ri
<
rn
;
ri
++
)
{
for
(
ti
=
0
;
ti
<
tn
;
ti
++
)
{
if
(
caccum
[
ri
*
tn
+
ti
]
>
threshold
)
{
count
++
;
}
}
}
if
(
count
*
100
>
rn
*
tn
)
{
icv
HoughLinesStandard
(
img
,
rho
,
theta
,
threshold
,
lines
,
linesMax
);
HoughLinesStandard
(
img
,
rho
,
theta
,
threshold
,
lines
,
linesMax
);
return
;
}
_buffer
.
resize
(
srn
*
stn
+
2
);
buffer
=
&
_buffer
[
0
];
mcaccum
=
buffer
+
1
;
vector
<
uchar
>
_buffer
(
srn
*
stn
+
2
);
uchar
*
buffer
=
&
_buffer
[
0
];
uchar
*
mcaccum
=
buffer
+
1
;
count
=
0
;
for
(
ri
=
0
;
ri
<
rn
;
ri
++
)
...
...
@@ -355,18 +316,16 @@ icvHoughLinesSDiv( const CvMat* img,
yc
=
(
float
)
y
[
index
]
+
0.5
f
;
xc
=
(
float
)
x
[
index
]
+
0.5
f
;
/
* Update the accumulator */
/
/ Update the accumulator
t
=
(
float
)
fabs
(
cvFastArctan
(
yc
,
xc
)
*
d2r
);
r
=
(
float
)
sqrt
(
(
double
)
xc
*
xc
+
(
double
)
yc
*
yc
)
*
isrho
;
ti0
=
cvFloor
(
(
t
+
Pi
*
0.5
f
)
*
istheta
);
ti0
=
cvFloor
(
(
t
+
CV_PI
*
0.5
)
*
istheta
);
ti2
=
(
ti
*
stn
-
ti0
)
*
5
;
r0
=
(
float
)
ri
*
srn
;
for
(
ti1
=
0
/*, phi = ti*theta - Pi/2 - t */
;
ti1
<
stn
;
ti1
++
,
ti2
+=
5
/*phi += stheta */
)
for
(
ti1
=
0
;
ti1
<
stn
;
ti1
++
,
ti2
+=
5
)
{
/*rv = r*_cos(phi) - r0; */
rv
=
r
*
sinTable
[(
int
)
(
abs
(
ti2
))]
-
r0
;
rv
=
r
*
sinTable
[(
int
)
(
std
::
abs
(
ti2
))]
-
r0
;
i
=
cvFloor
(
rv
)
*
stn
+
ti1
;
i
=
CV_IMAX
(
i
,
-
1
);
...
...
@@ -377,75 +336,38 @@ icvHoughLinesSDiv( const CvMat* img,
}
}
/
* Find peaks in maccum... */
/
/ Find peaks in maccum...
for
(
index
=
0
;
index
<
sfn
;
index
++
)
{
i
=
0
;
pos
=
h_get_tail_pos__index
(
list
);
if
(
h_get_prev__index
(
&
pos
)
->
value
<
mcaccum
[
index
]
)
{
vi
.
value
=
mcaccum
[
index
];
vi
.
rho
=
index
/
stn
*
srho
+
ri
*
rho
;
vi
.
theta
=
index
%
stn
*
stheta
+
ti
*
theta
-
halfPi
;
while
(
h_is_pos__index
(
pos
))
int
pos
=
(
int
)(
lst
.
size
()
-
1
);
if
(
pos
<
0
||
lst
[
pos
].
value
<
mcaccum
[
index
]
)
{
if
(
h_get__index
(
pos
)
->
value
>
mcaccum
[
index
]
)
hough_index
vi
(
mcaccum
[
index
],
index
/
stn
*
srho
+
ri
*
rho
,
index
%
stn
*
stheta
+
ti
*
theta
-
(
float
)(
CV_PI
*
0.5
));
lst
.
push_back
(
vi
);
for
(
;
pos
>=
0
;
pos
--
)
{
h_insert_after__index
(
list
,
pos
,
&
vi
);
if
(
h_get_count__index
(
list
)
>
linesMax
)
{
h_remove_tail__index
(
list
);
}
if
(
lst
[
pos
].
value
>
vi
.
value
)
break
;
lst
[
pos
+
1
]
=
lst
[
pos
];
}
h_get_prev__index
(
&
pos
);
}
if
(
!
h_is_pos__index
(
pos
))
{
h_add_head__index
(
list
,
&
vi
);
if
(
h_get_count__index
(
list
)
>
linesMax
)
{
h_remove_tail__index
(
list
);
}
}
lst
[
pos
+
1
]
=
vi
;
if
(
(
int
)
lst
.
size
()
>
linesMax
)
lst
.
pop_back
();
}
}
}
}
}
pos
=
h_get_head_pos__index
(
list
);
if
(
h_get_count__index
(
list
)
==
1
)
{
if
(
h_get__index
(
pos
)
->
rho
<
0
)
{
h_clear_list__index
(
list
);
}
}
else
{
while
(
h_is_pos__index
(
pos
))
for
(
size_t
i
=
0
;
i
<
lst
.
size
();
i
++
)
{
CvLinePolar
line
;
pindex
=
h_get__index
(
pos
);
if
(
pindex
->
rho
<
0
)
{
/* This should be the last element... */
h_get_next__index
(
&
pos
);
assert
(
!
h_is_pos__index
(
pos
));
break
;
}
line
.
rho
=
pindex
->
rho
;
line
.
angle
=
pindex
->
theta
;
cvSeqPush
(
lines
,
&
line
);
if
(
lines
->
total
>=
linesMax
)
break
;
h_get_next__index
(
&
pos
);
}
if
(
lst
[
i
].
rho
<
0
)
continue
;
lines
.
push_back
(
Vec2f
(
lst
[
i
].
rho
,
lst
[
i
].
theta
));
}
h_destroy_list__index
(
list
);
}
...
...
@@ -454,98 +376,80 @@ icvHoughLinesSDiv( const CvMat* img,
\****************************************************************************************/
static
void
icvHoughLinesProbabilistic
(
CvMat
*
image
,
HoughLinesProbabilistic
(
Mat
&
image
,
float
rho
,
float
theta
,
int
threshold
,
int
lineLength
,
int
lineGap
,
CvSeq
*
lines
,
int
linesMax
)
vector
<
Vec4i
>&
lines
,
int
linesMax
)
{
cv
::
Mat
accum
,
mask
;
cv
::
vector
<
float
>
trigtab
;
cv
::
MemStorage
storage
(
cvCreateMemStorage
(
0
));
CvSeq
*
seq
;
CvSeqWriter
writer
;
int
width
,
height
;
int
numangle
,
numrho
;
float
ang
;
int
r
,
n
,
count
;
CvPoint
pt
;
Point
pt
;
float
irho
=
1
/
rho
;
CvRNG
rng
=
cvRNG
(
-
1
);
const
float
*
ttab
;
uchar
*
mdata0
;
RNG
rng
((
uint64
)
-
1
);
CV_Assert
(
CV_IS_MAT
(
image
)
&&
CV_MAT_TYPE
(
image
->
type
)
==
CV_8UC1
);
CV_Assert
(
image
.
type
(
)
==
CV_8UC1
);
width
=
image
->
cols
;
height
=
image
->
rows
;
int
width
=
image
.
cols
;
int
height
=
image
.
rows
;
numangle
=
cvRound
(
CV_PI
/
theta
);
numrho
=
cvRound
(((
width
+
height
)
*
2
+
1
)
/
rho
);
int
numangle
=
cvRound
(
CV_PI
/
theta
);
int
numrho
=
cvRound
(((
width
+
height
)
*
2
+
1
)
/
rho
);
accum
.
create
(
numangle
,
numrho
,
CV_32SC1
);
mask
.
create
(
height
,
width
,
CV_8UC1
);
trigtab
.
resize
(
numangle
*
2
);
accum
=
cv
::
Scalar
(
0
);
Mat
accum
=
Mat
::
zeros
(
numangle
,
numrho
,
CV_32SC1
);
Mat
mask
(
height
,
width
,
CV_8UC1
);
vector
<
float
>
trigtab
(
numangle
*
2
);
for
(
ang
=
0
,
n
=
0
;
n
<
numangle
;
ang
+=
theta
,
n
++
)
for
(
int
n
=
0
;
n
<
numangle
;
n
++
)
{
trigtab
[
n
*
2
]
=
(
float
)(
cos
(
ang
)
*
irho
);
trigtab
[
n
*
2
+
1
]
=
(
float
)(
sin
(
ang
)
*
irho
);
trigtab
[
n
*
2
]
=
(
float
)(
cos
(
n
*
theta
)
*
irho
);
trigtab
[
n
*
2
+
1
]
=
(
float
)(
sin
(
n
*
theta
)
*
irho
);
}
ttab
=
&
trigtab
[
0
];
mdata0
=
mask
.
data
;
cvStartWriteSeq
(
CV_32SC2
,
sizeof
(
CvSeq
),
sizeof
(
CvPoint
),
storage
,
&
writer
);
const
float
*
ttab
=
&
trigtab
[
0
];
uchar
*
mdata0
=
mask
.
data
;
vector
<
Point
>
nzloc
;
// stage 1. collect non-zero image points
for
(
pt
.
y
=
0
,
count
=
0
;
pt
.
y
<
height
;
pt
.
y
++
)
for
(
pt
.
y
=
0
;
pt
.
y
<
height
;
pt
.
y
++
)
{
const
uchar
*
data
=
image
->
data
.
ptr
+
pt
.
y
*
image
->
step
;
uchar
*
mdata
=
m
data0
+
pt
.
y
*
width
;
const
uchar
*
data
=
image
.
ptr
(
pt
.
y
)
;
uchar
*
mdata
=
m
ask
.
ptr
(
pt
.
y
)
;
for
(
pt
.
x
=
0
;
pt
.
x
<
width
;
pt
.
x
++
)
{
if
(
data
[
pt
.
x
]
)
{
mdata
[
pt
.
x
]
=
(
uchar
)
1
;
CV_WRITE_SEQ_ELEM
(
pt
,
writer
);
nzloc
.
push_back
(
pt
);
}
else
mdata
[
pt
.
x
]
=
0
;
}
}
seq
=
cvEndWriteSeq
(
&
writer
);
count
=
seq
->
total
;
int
count
=
(
int
)
nzloc
.
size
();
// stage 2. process all the points in random order
for
(
;
count
>
0
;
count
--
)
{
// choose random point out of the remaining ones
int
idx
=
cvRandInt
(
&
rng
)
%
count
;
int
idx
=
rng
.
uniform
(
0
,
count
)
;
int
max_val
=
threshold
-
1
,
max_n
=
0
;
CvPoint
*
point
=
(
CvPoint
*
)
cvGetSeqElem
(
seq
,
idx
)
;
CvPoint
line_end
[
2
]
=
{{
0
,
0
},
{
0
,
0
}}
;
Point
point
=
nzloc
[
idx
]
;
Point
line_end
[
2
]
;
float
a
,
b
;
int
*
adata
=
(
int
*
)
accum
.
data
;
int
i
,
j
,
k
,
x0
,
y0
,
dx0
,
dy0
,
xflag
;
int
i
=
point
.
y
,
j
=
point
.
x
,
k
,
x0
,
y0
,
dx0
,
dy0
,
xflag
;
int
good_line
;
const
int
shift
=
16
;
i
=
point
->
y
;
j
=
point
->
x
;
// "remove" it by overriding it with the last element
*
point
=
*
(
CvPoint
*
)
cvGetSeqElem
(
seq
,
count
-
1
)
;
nzloc
[
idx
]
=
nzloc
[
count
-
1
]
;
// check if it has been excluded already (i.e. belongs to some other line)
if
(
!
mdata0
[
i
*
width
+
j
]
)
continue
;
// update accumulator, find the most probable line
for
(
n
=
0
;
n
<
numangle
;
n
++
,
adata
+=
numrho
)
for
(
int
n
=
0
;
n
<
numangle
;
n
++
,
adata
+=
numrho
)
{
r
=
cvRound
(
j
*
ttab
[
n
*
2
]
+
i
*
ttab
[
n
*
2
+
1
]
);
int
r
=
cvRound
(
j
*
ttab
[
n
*
2
]
+
i
*
ttab
[
n
*
2
+
1
]
);
r
+=
(
numrho
-
1
)
/
2
;
int
val
=
++
adata
[
r
];
if
(
max_val
<
val
)
...
...
@@ -625,8 +529,8 @@ icvHoughLinesProbabilistic( CvMat* image,
}
}
good_line
=
abs
(
line_end
[
1
].
x
-
line_end
[
0
].
x
)
>=
lineLength
||
abs
(
line_end
[
1
].
y
-
line_end
[
0
].
y
)
>=
lineLength
;
good_line
=
std
::
abs
(
line_end
[
1
].
x
-
line_end
[
0
].
x
)
>=
lineLength
||
std
::
abs
(
line_end
[
1
].
y
-
line_end
[
0
].
y
)
>=
lineLength
;
for
(
k
=
0
;
k
<
2
;
k
++
)
{
...
...
@@ -664,9 +568,9 @@ icvHoughLinesProbabilistic( CvMat* image,
if
(
good_line
)
{
adata
=
(
int
*
)
accum
.
data
;
for
(
n
=
0
;
n
<
numangle
;
n
++
,
adata
+=
numrho
)
for
(
int
n
=
0
;
n
<
numangle
;
n
++
,
adata
+=
numrho
)
{
r
=
cvRound
(
j1
*
ttab
[
n
*
2
]
+
i1
*
ttab
[
n
*
2
+
1
]
);
int
r
=
cvRound
(
j1
*
ttab
[
n
*
2
]
+
i1
*
ttab
[
n
*
2
+
1
]
);
r
+=
(
numrho
-
1
)
/
2
;
adata
[
r
]
--
;
}
...
...
@@ -681,23 +585,56 @@ icvHoughLinesProbabilistic( CvMat* image,
if
(
good_line
)
{
CvRect
lr
=
{
line_end
[
0
].
x
,
line_end
[
0
].
y
,
line_end
[
1
].
x
,
line_end
[
1
].
y
}
;
cvSeqPush
(
lines
,
&
lr
);
if
(
lines
->
total
>=
linesMax
)
Vec4i
lr
(
line_end
[
0
].
x
,
line_end
[
0
].
y
,
line_end
[
1
].
x
,
line_end
[
1
].
y
)
;
lines
.
push_back
(
lr
);
if
(
(
int
)
lines
.
size
()
>=
linesMax
)
return
;
}
}
}
}
void
cv
::
HoughLines
(
InputArray
_image
,
OutputArray
_lines
,
double
rho
,
double
theta
,
int
threshold
,
double
srn
,
double
stn
)
{
Mat
image
=
_image
.
getMat
();
vector
<
Vec2f
>
lines
;
if
(
srn
==
0
&&
stn
==
0
)
HoughLinesStandard
(
image
,
rho
,
theta
,
threshold
,
lines
,
INT_MAX
);
else
HoughLinesSDiv
(
image
,
rho
,
theta
,
threshold
,
srn
,
stn
,
lines
,
INT_MAX
);
Mat
(
lines
).
copyTo
(
_lines
);
}
void
cv
::
HoughLinesP
(
InputArray
_image
,
OutputArray
_lines
,
double
rho
,
double
theta
,
int
threshold
,
double
minLineLength
,
double
maxGap
)
{
Mat
image
=
_image
.
getMat
();
vector
<
Vec4i
>
lines
;
HoughLinesProbabilistic
(
image
,
rho
,
theta
,
threshold
,
minLineLength
,
maxGap
,
lines
,
INT_MAX
);
Mat
(
lines
).
copyTo
(
_lines
);
}
/* Wrapper function for standard hough transform */
CV_IMPL
CvSeq
*
cvHoughLines2
(
CvArr
*
src_image
,
void
*
lineStorage
,
int
method
,
double
rho
,
double
theta
,
int
threshold
,
double
param1
,
double
param2
)
{
cv
::
Mat
image
=
cv
::
cvarrToMat
(
src_image
);
std
::
vector
<
cv
::
Vec2f
>
l2
;
std
::
vector
<
cv
::
Vec4i
>
l4
;
CvSeq
*
result
=
0
;
CvMat
stub
,
*
img
=
(
CvMat
*
)
src_image
;
CvMat
*
mat
=
0
;
CvSeq
*
lines
=
0
;
CvSeq
lines_header
;
...
...
@@ -706,11 +643,6 @@ cvHoughLines2( CvArr* src_image, void* lineStorage, int method,
int
linesMax
=
INT_MAX
;
int
iparam1
,
iparam2
;
img
=
cvGetMat
(
img
,
&
stub
);
if
(
!
CV_IS_MASK_ARR
(
img
))
CV_Error
(
CV_StsBadArg
,
"The source image must be 8-bit, single-channel"
);
if
(
!
lineStorage
)
CV_Error
(
CV_StsNullPtr
,
"NULL destination"
);
...
...
@@ -758,31 +690,49 @@ cvHoughLines2( CvArr* src_image, void* lineStorage, int method,
switch
(
method
)
{
case
CV_HOUGH_STANDARD
:
icvHoughLinesStandard
(
img
,
(
float
)
rho
,
(
float
)
theta
,
threshold
,
l
ines
,
linesMax
);
HoughLinesStandard
(
image
,
(
float
)
rho
,
(
float
)
theta
,
threshold
,
l
2
,
linesMax
);
break
;
case
CV_HOUGH_MULTI_SCALE
:
icvHoughLinesSDiv
(
img
,
(
float
)
rho
,
(
float
)
theta
,
threshold
,
iparam1
,
iparam2
,
l
ines
,
linesMax
);
HoughLinesSDiv
(
image
,
(
float
)
rho
,
(
float
)
theta
,
threshold
,
iparam1
,
iparam2
,
l
2
,
linesMax
);
break
;
case
CV_HOUGH_PROBABILISTIC
:
icvHoughLinesProbabilistic
(
img
,
(
float
)
rho
,
(
float
)
theta
,
threshold
,
iparam1
,
iparam2
,
l
ines
,
linesMax
);
HoughLinesProbabilistic
(
image
,
(
float
)
rho
,
(
float
)
theta
,
threshold
,
iparam1
,
iparam2
,
l
4
,
linesMax
);
break
;
default
:
CV_Error
(
CV_StsBadArg
,
"Unrecognized method id"
);
}
int
nlines
=
(
int
)(
l2
.
size
()
+
l4
.
size
());
if
(
mat
)
{
if
(
mat
->
cols
>
mat
->
rows
)
mat
->
cols
=
lines
->
total
;
mat
->
cols
=
nlines
;
else
mat
->
rows
=
lines
->
total
;
mat
->
rows
=
nlines
;
}
if
(
nlines
)
{
cv
::
Mat
lx
=
method
==
CV_HOUGH_STANDARD
||
method
==
CV_HOUGH_MULTI_SCALE
?
cv
::
Mat
(
nlines
,
1
,
CV_32FC2
,
&
l2
[
0
])
:
cv
::
Mat
(
nlines
,
1
,
CV_32SC4
,
&
l4
[
0
]);
if
(
mat
)
{
cv
::
Mat
dst
(
nlines
,
1
,
lx
.
type
(),
mat
->
data
.
ptr
);
lx
.
copyTo
(
dst
);
}
else
result
=
lines
;
{
cvSeqPushMulti
(
lines
,
lx
.
data
,
nlines
);
}
}
if
(
!
mat
)
result
=
lines
;
return
result
;
}
...
...
@@ -909,7 +859,7 @@ icvHoughCirclesGradient( CvMat* img, float dp, float min_dist,
sort_buf
.
resize
(
MAX
(
center_count
,
nz_count
)
);
cvCvtSeqToArray
(
centers
,
&
sort_buf
[
0
]
);
icvHoughSortDescent32s
(
&
sort_buf
[
0
],
center_count
,
adata
);
std
::
sort
(
sort_buf
.
begin
(),
sort_buf
.
begin
()
+
center_count
,
cv
::
hough_cmp_gt
(
adata
)
);
cvClearSeq
(
centers
);
cvSeqPushMulti
(
centers
,
&
sort_buf
[
0
],
center_count
);
...
...
@@ -963,7 +913,7 @@ icvHoughCirclesGradient( CvMat* img, float dp, float min_dist,
continue
;
dist_buf
->
cols
=
nz_count1
;
cvPow
(
dist_buf
,
dist_buf
,
0.5
);
icvHoughSortDescent32s
(
&
sort_buf
[
0
],
nz_count1
,
(
int
*
)
ddata
);
std
::
sort
(
sort_buf
.
begin
(),
sort_buf
.
begin
()
+
nz_count1
,
cv
::
hough_cmp_gt
((
int
*
)
ddata
)
);
dist_sum
=
start_dist
=
ddata
[
sort_buf
[
nz_count1
-
1
]];
for
(
j
=
nz_count1
-
2
;
j
>=
0
;
j
--
)
...
...
@@ -1102,31 +1052,6 @@ static void seqToMat(const CvSeq* seq, OutputArray _arr)
}
void
cv
::
HoughLines
(
InputArray
_image
,
OutputArray
_lines
,
double
rho
,
double
theta
,
int
threshold
,
double
srn
,
double
stn
)
{
Ptr
<
CvMemStorage
>
storage
=
cvCreateMemStorage
(
STORAGE_SIZE
);
Mat
image
=
_image
.
getMat
();
CvMat
c_image
=
image
;
CvSeq
*
seq
=
cvHoughLines2
(
&
c_image
,
storage
,
srn
==
0
&&
stn
==
0
?
CV_HOUGH_STANDARD
:
CV_HOUGH_MULTI_SCALE
,
rho
,
theta
,
threshold
,
srn
,
stn
);
seqToMat
(
seq
,
_lines
);
}
void
cv
::
HoughLinesP
(
InputArray
_image
,
OutputArray
_lines
,
double
rho
,
double
theta
,
int
threshold
,
double
minLineLength
,
double
maxGap
)
{
Ptr
<
CvMemStorage
>
storage
=
cvCreateMemStorage
(
STORAGE_SIZE
);
Mat
image
=
_image
.
getMat
();
CvMat
c_image
=
image
;
CvSeq
*
seq
=
cvHoughLines2
(
&
c_image
,
storage
,
CV_HOUGH_PROBABILISTIC
,
rho
,
theta
,
threshold
,
minLineLength
,
maxGap
);
seqToMat
(
seq
,
_lines
);
}
void
cv
::
HoughCircles
(
InputArray
_image
,
OutputArray
_circles
,
int
method
,
double
dp
,
double
min_dist
,
double
param1
,
double
param2
,
...
...
modules/imgproc/test/test_houghLines.cpp
View file @
944588e7
...
...
@@ -134,6 +134,9 @@ void CV_HoughLinesTest::run_test(int type)
read
(
fs
[
"exp_lines"
],
exp_lines
,
Mat
()
);
fs
.
release
();
if
(
exp_lines
.
size
!=
lines
.
size
)
transpose
(
lines
,
lines
);
if
(
exp_lines
.
size
!=
lines
.
size
||
norm
(
exp_lines
,
lines
,
NORM_INF
)
>
1e-4
)
{
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_MISMATCH
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment