9#ifndef COMMON_LINES_HPP
10#define COMMON_LINES_HPP
12#include <unordered_set>
23#include "opencv2/core.hpp"
42 Lines(
const std::vector<cv::Vec4i>& lines);
43 Lines(
const std::vector<std::vector<int>>& lines);
64 template <
typename FUNC = Line::CompareByLength>
66 template <
typename FUNC = Line::CompareByLength>
68 template <
typename FUNC = Line::CompareByLength>
70 template <
typename FUNC = Line::CompareByLength>
88 for (
auto&
line : lines)
106 for (
auto&
line : lines)
125 for (
auto&
line : lines)
146 for (
auto&
line : lines)
236 std::unordered_set<Line, Line::Hash>
lines_hash;
262 for (
auto&
line : *
this) {
295 return sum +
line.Length(is_rough);
302 throw Exception(
"The type(Statistic) of param \"type\" is incorrect!");
335 throw Exception(
"The \"line type\" only supports \"cm::HLINE\" or \"cm::VLINE\" types!");
414 return std::unordered_set<int>();
417 Cm_Assert(lines.Filter([lines](
const Line&
line) { return line.Type() == lines[0].Type(); }).size() == lines.size(),
"All lines must be of the same type!!!");
419 std::unordered_set<int>
indexes;
422 auto ge =
line.GECoefficients();
431 if (lines[
i].pt1.y <
line.pt1.
y || lines[
i].pt2.
y >
line.pt2.
y)
438 int x1 =
ge.GetX(lines[
i].pt1.y);
439 int x2 =
ge.GetX(lines[
i].pt2.y);
452 if (lines[
i].pt1.x <
line.pt1.
x || lines[
i].pt2.
x >
line.pt2.
x)
459 int y1 =
ge.GetY(lines[
i].pt1.x);
460 int y2 =
ge.GetY(lines[
i].pt2.x);
500 if (line_type ==
HLINE || line_type ==
VLINE) {
502 Cm_Assert(lines.Filter([line_type](
const cm::Line&
line) { return line.Type() == line_type; }).size() == lines.size(),
Sprintf(
"The line type in the line list must all be \"%s\"!!!", line_type ==
HLINE ?
"cm::HLINE" :
"cm::VLINE"));
553 }
else if (line_type ==
ULINE) {
569 throw Exception(
"The type(LineType) of param \"line_type\" is incorrect!");
607 Cm_Assert(lines.Filter([lines](
const Line&
line) { return line.Type() == lines[0].Type(); }).size() == lines.size(),
"All lines must be of the same type!!!");
686template <
typename FUNC>
700 if (line_type ==
HLINE || line_type ==
VLINE) {
702 Cm_Assert(lines.Filter([line_type](
const cm::Line&
line) { return line.Type() == line_type; }).size() == lines.size(),
Sprintf(
"The line type in the line list must all be \"%s\"!!!", line_type ==
HLINE ?
"cm::HLINE" :
"cm::VLINE"));
720 }
else if (line_type ==
ULINE) {
729 auto&
line = lines[
i];
751 throw Exception(
"The type(LineType) of param \"line_type\" is incorrect!");
779template <
typename FUNC>
794 Cm_Assert(lines.Filter([lines](
const Line&
line) { return line.Type() == lines[0].Type(); }).size() == lines.size(),
"All lines must be of the same type!!!");
827template <
typename FUNC>
859template <
typename FUNC>
static Interval All()
获取表示全范围的区间
Lines & RemoveLines(const std::unordered_set< size_t > &deleted_indexes)
移除指定索引的线段
double LineLength(Statistic type, const Interval &x_range=Interval::All(), const Interval &y_range=Interval::All(), bool is_rough=false)
计算线数组中有效线的长度
const Lines & ClassifyLines(Lines &hlines, Lines &vlines) const
对线段进行分类
std::unordered_set< size_t > GetDuplicateLines(LineType line_type=ULINE, double threshold=5, double min_overlap_ratio=0.5, Statistic near_method=cm::MAXIMUM, const FUNC &func=Line::CompareByLength(true)) const
获取重复线段对应的索引
std::unordered_set< int > GetLinesIndexInLine(const Line &line, int threshold=2, bool strict_inspect=true)
获取线在线列表中的索引
Lines(const Lines &lines)=default
线列表类的拷贝构造函数
Lines & ConnectAdjacentLines(int threshold=4, int max_distance=100, bool strict_inspect=true, const Interval &old_line_len_range=Interval::All(), bool oline_len_condition=true, const Interval &new_line_len_range=Interval::All())
连接线列表的相邻线段
Line MergeLines(LineType line_type) const
合并线列表
Lines()=default
线列表类的默认构造函数
Lines & RmDuplicateLines(LineType line_type=ULINE, double threshold=5, double min_overlap_ratio=0.5, Statistic near_method=cm::MAXIMUM, const FUNC &func=Line::CompareByLength(true))
删除重复线
Lines & operator=(const std::vector< cv::Vec4i > &lines)
线列表类的赋值拷贝构造函数
std::unordered_set< size_t > GetAdjacentDuplicateLines(double threshold, double min_overlap_ratio=0.5, Statistic near_method=cm::MAXIMUM, const FUNC &func=Line::CompareByLength(true)) const
获取相邻重复线段对应的索引
Lines & RmAdjacentDuplicateLines(double threshold, double min_overlap_ratio=0.5, Statistic near_method=cm::MAXIMUM, const FUNC &func=Line::CompareByLength(true))
删除相邻的重复线
Rect Boundary(int margin=0) const
获取线列表的边界
cm::size_t NumberInInterval(const Interval &x_range, const Interval &y_range)
计算区间内的线段数量
~Lines()=default
线列表类的析构函数
Lines & ConnectLines(LineType line_type=ULINE, int threshold=4, int max_distance=100, bool strict_inspect=true, const Interval &old_line_len_range=Interval::All(), bool oline_len_condition=true, const Interval &new_line_len_range=Interval::All())
连接线列表的线段
const_iterator Min() const
求列表中的最小值
List< Line > Filter(const FUNC &func) const
过滤列表项
size_t Count(const Line &value) const
统计列表中指定值的出现次数
const_iterator Max() const
求列表中的最大值
double DistanceTo(const Point< U > &pt) const
计算点到点之间的距离
#define Cm_Assert(expr, message)
断言宏
std::string Sprintf(const char *format,...)
格式化输出字符串
LineDistanceType
线与线的间距类型枚举
@ LDIS_VLINE_V
竖线与竖线之间的垂直距离(可能为负数,为负数时表示两竖线在y坐标上相交)
@ LDIS_HLINE_H
横线与横线之间的水平距离(可能为负数,为负数时表示两横线在x坐标上相交)
@ HLINE
横线 (horizontal line)
@ ULINE
未知线类型 (unknown line)
@ VLINE
竖线 (vertical line)