mirror of
https://github.com/opencv/opencv.git
synced 2026-07-31 00:03:03 +04:00
Merge branch 4.x
This commit is contained in:
@@ -162,26 +162,40 @@ approxPolyDP_( const Point_<T>* src_contour, int count0, Point_<T>* dst_contour,
|
||||
|
||||
if( pos != slice.end )
|
||||
{
|
||||
double dx, dy, dist, max_dist = 0;
|
||||
double dx, dy, max_dist_2_mul_segment_len_2 = 0;
|
||||
|
||||
dx = end_pt.x - start_pt.x;
|
||||
dy = end_pt.y - start_pt.y;
|
||||
double segment_len_2 = dx * dx + dy * dy;
|
||||
|
||||
CV_Assert( dx != 0 || dy != 0 );
|
||||
|
||||
while( pos != slice.end )
|
||||
{
|
||||
READ_PT(pt, pos);
|
||||
dist = fabs((pt.y - start_pt.y) * dx - (pt.x - start_pt.x) * dy);
|
||||
double projection = ((pt.x - start_pt.x) * dx + (pt.y - start_pt.y) * dy);
|
||||
|
||||
if( dist > max_dist )
|
||||
double dist_2_mul_segment_len_2;
|
||||
if ( projection < 0 )
|
||||
{
|
||||
max_dist = dist;
|
||||
dist_2_mul_segment_len_2 = ((pt.x - start_pt.x) * (pt.x - start_pt.x) + (pt.y - start_pt.y) * (pt.y - start_pt.y)) * segment_len_2;
|
||||
} else if ( projection > segment_len_2 )
|
||||
{
|
||||
dist_2_mul_segment_len_2 = ((pt.x - end_pt.x) * (pt.x - end_pt.x) + (pt.y - end_pt.y) * (pt.y - end_pt.y)) * segment_len_2;
|
||||
} else
|
||||
{
|
||||
double dist = ((pt.y - start_pt.y) * dx - (pt.x - start_pt.x) * dy);
|
||||
dist_2_mul_segment_len_2 = dist * dist;
|
||||
}
|
||||
|
||||
if( dist_2_mul_segment_len_2 > max_dist_2_mul_segment_len_2 )
|
||||
{
|
||||
max_dist_2_mul_segment_len_2 = dist_2_mul_segment_len_2;
|
||||
right_slice.start = (pos+count-1)%count;
|
||||
}
|
||||
}
|
||||
|
||||
le_eps = max_dist * max_dist <= eps * (dx * dx + dy * dy);
|
||||
le_eps = max_dist_2_mul_segment_len_2 <= eps * segment_len_2;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -321,7 +321,7 @@ bilateralFilter_32f( const Mat& src, Mat& dst, int d,
|
||||
}
|
||||
|
||||
// parallel_for usage
|
||||
CV_CPU_DISPATCH(bilateralFilterInvoker_32f, (cn, radius, maxk, space_ofs, temp, dst, scale_index, space_weight, expLUT),
|
||||
CV_CPU_DISPATCH(bilateralFilterInvoker_32f, (cn, radius, maxk, space_ofs, temp, dst, scale_index, space_weight, expLUT, kExpNumBins),
|
||||
CV_CPU_DISPATCH_MODES_ALL);
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ void bilateralFilterInvoker_8u(
|
||||
int* space_ofs, float *space_weight, float *color_weight);
|
||||
void bilateralFilterInvoker_32f(
|
||||
int cn, int radius, int maxk, int *space_ofs,
|
||||
const Mat& temp, Mat& dst, float scale_index, float *space_weight, float *expLUT);
|
||||
const Mat& temp, Mat& dst, float scale_index, float *space_weight, float *expLUT, int kExpNumBins);
|
||||
|
||||
#ifndef CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY
|
||||
|
||||
@@ -495,9 +495,9 @@ class BilateralFilter_32f_Invoker :
|
||||
public:
|
||||
|
||||
BilateralFilter_32f_Invoker(int _cn, int _radius, int _maxk, int *_space_ofs,
|
||||
const Mat& _temp, Mat& _dest, float _scale_index, float *_space_weight, float *_expLUT) :
|
||||
const Mat& _temp, Mat& _dest, float _scale_index, float *_space_weight, float *_expLUT, int _kExpNumBins) :
|
||||
cn(_cn), radius(_radius), maxk(_maxk), space_ofs(_space_ofs),
|
||||
temp(&_temp), dest(&_dest), scale_index(_scale_index), space_weight(_space_weight), expLUT(_expLUT)
|
||||
temp(&_temp), dest(&_dest), scale_index(_scale_index), space_weight(_space_weight), expLUT(_expLUT), kExpNumBins(_kExpNumBins)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -550,7 +550,7 @@ public:
|
||||
v_float32 val0 = vx_load(ksptr);
|
||||
v_float32 knan0 = v_not_nan(val0);
|
||||
v_float32 alpha0 = v_and(v_and(v_mul(v_absdiff(val0, rval0), sindex), v_not_nan(rval0)), knan0);
|
||||
v_int32 idx0 = v_trunc(alpha0);
|
||||
v_int32 idx0 = v_min(v_trunc(alpha0), vx_setall_s32(kExpNumBins));
|
||||
alpha0 = v_sub(alpha0, v_cvt_f32(idx0));
|
||||
v_float32 w0 = v_and(v_mul(kweight, v_muladd(v_lut(this->expLUT + 1, idx0), alpha0, v_mul(v_lut(this->expLUT, idx0), v_sub(v_one, alpha0)))), knan0);
|
||||
v_wsum0 = v_add(v_wsum0, w0);
|
||||
@@ -560,7 +560,7 @@ public:
|
||||
v_float32 val1 = vx_load(ksptr + nlanes);
|
||||
v_float32 knan1 = v_not_nan(val1);
|
||||
v_float32 alpha1 = v_and(v_and(v_mul(v_absdiff(val1, rval1), sindex), v_not_nan(rval1)), knan1);
|
||||
v_int32 idx1 = v_trunc(alpha1);
|
||||
v_int32 idx1 = v_min(v_trunc(alpha1), vx_setall_s32(kExpNumBins));
|
||||
alpha1 = v_sub(alpha1, v_cvt_f32(idx1));
|
||||
v_float32 w1 = v_and(v_mul(kweight, v_muladd(v_lut(this->expLUT + 1, idx1), alpha1, v_mul(v_lut(this->expLUT, idx1), v_sub(v_one, alpha1)))), knan1);
|
||||
v_wsum1 = v_add(v_wsum1, w1);
|
||||
@@ -570,7 +570,7 @@ public:
|
||||
v_float32 val2 = vx_load(ksptr + nlanes_2);
|
||||
v_float32 knan2 = v_not_nan(val2);
|
||||
v_float32 alpha2 = v_and(v_and(v_mul(v_absdiff(val2, rval2), sindex), v_not_nan(rval2)), knan2);
|
||||
v_int32 idx2 = v_trunc(alpha2);
|
||||
v_int32 idx2 = v_min(v_trunc(alpha2), vx_setall_s32(kExpNumBins));
|
||||
alpha2 = v_sub(alpha2, v_cvt_f32(idx2));
|
||||
v_float32 w2 = v_and(v_mul(kweight, v_muladd(v_lut(this->expLUT + 1, idx2), alpha2, v_mul(v_lut(this->expLUT, idx2), v_sub(v_one, alpha2)))), knan2);
|
||||
v_wsum2 = v_add(v_wsum2, w2);
|
||||
@@ -580,7 +580,7 @@ public:
|
||||
v_float32 val3 = vx_load(ksptr + nlanes_3);
|
||||
v_float32 knan3 = v_not_nan(val3);
|
||||
v_float32 alpha3 = v_and(v_and(v_mul(v_absdiff(val3, rval3), sindex), v_not_nan(rval3)), knan3);
|
||||
v_int32 idx3 = v_trunc(alpha3);
|
||||
v_int32 idx3 = v_min(v_trunc(alpha3), vx_setall_s32(kExpNumBins));
|
||||
alpha3 = v_sub(alpha3, v_cvt_f32(idx3));
|
||||
v_float32 w3 = v_and(v_mul(kweight, v_muladd(v_lut(this->expLUT + 1, idx3), alpha3, v_mul(v_lut(this->expLUT, idx3), v_sub(v_one, alpha3)))), knan3);
|
||||
v_wsum3 = v_add(v_wsum3, w3);
|
||||
@@ -611,7 +611,7 @@ public:
|
||||
v_float32 val0 = vx_load(ksptr);
|
||||
v_float32 knan0 = v_not_nan(val0);
|
||||
v_float32 alpha0 = v_and(v_and(v_mul(v_absdiff(val0, rval0), sindex), rval0_not_nan), knan0);
|
||||
v_int32 idx0 = v_trunc(alpha0);
|
||||
v_int32 idx0 = v_min(v_trunc(alpha0), vx_setall_s32(kExpNumBins));
|
||||
alpha0 = v_sub(alpha0, v_cvt_f32(idx0));
|
||||
v_float32 w0 = v_and(v_mul(kweight, v_muladd(v_lut(this->expLUT + 1, idx0), alpha0, v_mul(v_lut(this->expLUT, idx0), v_sub(v_one, alpha0)))), knan0);
|
||||
v_wsum0 = v_add(v_wsum0, w0);
|
||||
@@ -621,7 +621,7 @@ public:
|
||||
v_float32 val1 = vx_load(ksptr + nlanes);
|
||||
v_float32 knan1 = v_not_nan(val1);
|
||||
v_float32 alpha1 = v_and(v_and(v_mul(v_absdiff(val1, rval1), sindex), rval1_not_nan), knan1);
|
||||
v_int32 idx1 = v_trunc(alpha1);
|
||||
v_int32 idx1 = v_min(v_trunc(alpha1), vx_setall_s32(kExpNumBins));
|
||||
alpha1 = v_sub(alpha1, v_cvt_f32(idx1));
|
||||
v_float32 w1 = v_and(v_mul(kweight, v_muladd(v_lut(this->expLUT + 1, idx1), alpha1, v_mul(v_lut(this->expLUT, idx1), v_sub(v_one, alpha1)))), knan1);
|
||||
v_wsum1 = v_add(v_wsum1, w1);
|
||||
@@ -640,7 +640,7 @@ public:
|
||||
{
|
||||
const float* ksptr = sptr_j + space_ofs[k];
|
||||
float val = *ksptr;
|
||||
float alpha = std::abs(val - rval) * scale_index;
|
||||
float alpha = std::min(std::abs(val - rval) * scale_index, (float)kExpNumBins);
|
||||
int idx = cvFloor(alpha);
|
||||
alpha -= idx;
|
||||
if (!cvIsNaN(val))
|
||||
@@ -681,7 +681,7 @@ public:
|
||||
|
||||
v_float32 knan = v_and(v_and(v_not_nan(kb), v_not_nan(kg)), v_not_nan(kr));
|
||||
v_float32 alpha = v_and(v_and(v_and(v_and(v_mul(v_add(v_add(v_absdiff(kb, rb), v_absdiff(kg, rg)), v_absdiff(kr, rr)), sindex), v_not_nan(rb)), v_not_nan(rg)), v_not_nan(rr)), knan);
|
||||
v_int32 idx = v_trunc(alpha);
|
||||
v_int32 idx = v_min(v_trunc(alpha), vx_setall_s32(kExpNumBins));
|
||||
alpha = v_sub(alpha, v_cvt_f32(idx));
|
||||
|
||||
v_float32 w = v_and(v_mul(kweight, v_muladd(v_lut(this->expLUT + 1, idx), alpha, v_mul(v_lut(this->expLUT, idx), v_sub(v_one, alpha)))), knan);
|
||||
@@ -709,7 +709,7 @@ public:
|
||||
bool v_NAN = cvIsNaN(b) || cvIsNaN(g) || cvIsNaN(r);
|
||||
float rb = rsptr[0], rg = rsptr[1], rr = rsptr[2];
|
||||
bool r_NAN = cvIsNaN(rb) || cvIsNaN(rg) || cvIsNaN(rr);
|
||||
float alpha = (std::abs(b - rb) + std::abs(g - rg) + std::abs(r - rr)) * scale_index;
|
||||
float alpha = std::min((std::abs(b - rb) + std::abs(g - rg) + std::abs(r - rr)) * scale_index, (float)kExpNumBins);
|
||||
int idx = cvFloor(alpha);
|
||||
alpha -= idx;
|
||||
if (!v_NAN)
|
||||
@@ -753,17 +753,18 @@ private:
|
||||
const Mat* temp;
|
||||
Mat *dest;
|
||||
float scale_index, *space_weight, *expLUT;
|
||||
int kExpNumBins;
|
||||
};
|
||||
|
||||
} // namespace anon
|
||||
|
||||
void bilateralFilterInvoker_32f(
|
||||
int cn, int radius, int maxk, int *space_ofs,
|
||||
const Mat& temp, Mat& dst, float scale_index, float *space_weight, float *expLUT)
|
||||
const Mat& temp, Mat& dst, float scale_index, float *space_weight, float *expLUT, int kExpNumBins)
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
BilateralFilter_32f_Invoker body(cn, radius, maxk, space_ofs, temp, dst, scale_index, space_weight, expLUT);
|
||||
BilateralFilter_32f_Invoker body(cn, radius, maxk, space_ofs, temp, dst, scale_index, space_weight, expLUT, kExpNumBins);
|
||||
parallel_for_(Range(0, dst.rows), body, dst.total()/(double)(1<<16));
|
||||
}
|
||||
|
||||
|
||||
@@ -219,9 +219,9 @@ void convexHull( InputArray _points, OutputArray _hull, bool clockwise, bool ret
|
||||
}
|
||||
|
||||
for( i = 0; i < tl_count-1; i++ )
|
||||
hullbuf[nout++] = int(pointer[tl_stack[i]] - data0);
|
||||
hullbuf[nout++] = tl_stack[i];
|
||||
for( i = tr_count - 1; i > 0; i-- )
|
||||
hullbuf[nout++] = int(pointer[tr_stack[i]] - data0);
|
||||
hullbuf[nout++] = tr_stack[i];
|
||||
int stop_idx = tr_count > 2 ? tr_stack[1] : tl_count > 2 ? tl_stack[tl_count - 2] : -1;
|
||||
|
||||
// lower half
|
||||
@@ -257,9 +257,43 @@ void convexHull( InputArray _points, OutputArray _hull, bool clockwise, bool ret
|
||||
}
|
||||
|
||||
for( i = 0; i < bl_count-1; i++ )
|
||||
hullbuf[nout++] = int(pointer[bl_stack[i]] - data0);
|
||||
hullbuf[nout++] = bl_stack[i];
|
||||
for( i = br_count-1; i > 0; i-- )
|
||||
hullbuf[nout++] = int(pointer[br_stack[i]] - data0);
|
||||
hullbuf[nout++] = br_stack[i];
|
||||
|
||||
if (!returnPoints)
|
||||
{
|
||||
// Try keep monotonous indices in case of self-intersection.
|
||||
for (i = 0; i < nout; ++i)
|
||||
{
|
||||
auto prev = pointer[hullbuf[(i == 0 ? nout : i) - 1]];
|
||||
auto next = pointer[hullbuf[(i + 1) % nout]];
|
||||
auto cur = pointer[hullbuf[i]];
|
||||
if ((prev < cur && cur < next) || (prev > cur && cur > next))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (int j = hullbuf[i] + 1; j < total; ++j)
|
||||
{
|
||||
cur = pointer[j];
|
||||
if (*pointer[hullbuf[i]] == *cur)
|
||||
{
|
||||
if ((prev < cur && cur < next) || (prev > cur && cur > next))
|
||||
{
|
||||
hullbuf[i] = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
for (i = 0; i < nout; ++i)
|
||||
{
|
||||
hullbuf[i] = int(pointer[hullbuf[i]] - data0);
|
||||
}
|
||||
|
||||
// try to make the convex hull indices form
|
||||
// an ascending or descending sequence by the cyclic
|
||||
|
||||
@@ -1668,7 +1668,7 @@ ThickLine( Mat& img, Point2l p0, Point2l p1, const void* color,
|
||||
{
|
||||
if( line_type < cv::LINE_AA )
|
||||
{
|
||||
if( line_type == 1 || line_type == 4 || shift == 0 )
|
||||
if( line_type == 1 || line_type == 8 || shift == 0 )
|
||||
{
|
||||
p0.x = (p0.x + (XY_ONE>>1)) >> XY_SHIFT;
|
||||
p0.y = (p0.y + (XY_ONE>>1)) >> XY_SHIFT;
|
||||
|
||||
@@ -1171,8 +1171,24 @@ static bool replacementFilter2D(int stype, int dtype, int kernel_type,
|
||||
int anchor_x, int anchor_y,
|
||||
double delta, int borderType, bool isSubmatrix)
|
||||
{
|
||||
// Prioritize stateless implementation
|
||||
int res = cv_hal_filter_stateless(src_data, src_step, stype,
|
||||
dst_data, dst_step, dtype, width, height,
|
||||
full_width, full_height, offset_x, offset_y,
|
||||
kernel_data, kernel_step, kernel_type,
|
||||
kernel_width, kernel_height, anchor_x, anchor_y,
|
||||
delta, borderType, isSubmatrix, src_data == dst_data);
|
||||
if (res == CV_HAL_ERROR_OK)
|
||||
{
|
||||
return true;
|
||||
} else if (res != CV_HAL_ERROR_NOT_IMPLEMENTED)
|
||||
{
|
||||
CV_Error_(cv::Error::StsInternal,
|
||||
("HAL implementation filter_stateless ==> " CVAUX_STR(cv_hal_filter_stateless) " returned %d (0x%08x)", res, res));
|
||||
}
|
||||
|
||||
cvhalFilter2D* ctx;
|
||||
int res = cv_hal_filterInit(&ctx, kernel_data, kernel_step, kernel_type, kernel_width, kernel_height, width, height,
|
||||
res = cv_hal_filterInit(&ctx, kernel_data, kernel_step, kernel_type, kernel_width, kernel_height, width, height,
|
||||
stype, dtype, borderType, delta, anchor_x, anchor_y, isSubmatrix, src_data == dst_data);
|
||||
if (res == CV_HAL_ERROR_NOT_IMPLEMENTED)
|
||||
{
|
||||
@@ -1385,8 +1401,23 @@ static bool replacementSepFilter(int stype, int dtype, int ktype,
|
||||
uchar * kernely_data, int kernely_len,
|
||||
int anchor_x, int anchor_y, double delta, int borderType)
|
||||
{
|
||||
// Prioritize stateless implementation
|
||||
int res = cv_hal_sepFilter_stateless(src_data, src_step, stype,
|
||||
dst_data, dst_step, dtype,
|
||||
width, height, full_width, full_height, offset_x, offset_y,
|
||||
kernelx_data, kernelx_len, kernely_data, kernely_len, ktype,
|
||||
anchor_x, anchor_y, delta, borderType);
|
||||
if (res == CV_HAL_ERROR_OK)
|
||||
{
|
||||
return true;
|
||||
} else if (res != CV_HAL_ERROR_NOT_IMPLEMENTED)
|
||||
{
|
||||
CV_Error_(cv::Error::StsInternal,
|
||||
("HAL implementation sepFilter_stateless ==> " CVAUX_STR(cv_hal_sepFilter_stateless) " returned %d (0x%08x)", res, res));
|
||||
}
|
||||
|
||||
cvhalFilter2D *ctx;
|
||||
int res = cv_hal_sepFilterInit(&ctx, stype, dtype, ktype,
|
||||
res = cv_hal_sepFilterInit(&ctx, stype, dtype, ktype,
|
||||
kernelx_data, kernelx_len,
|
||||
kernely_data, kernely_len,
|
||||
anchor_x, anchor_y, delta, borderType);
|
||||
|
||||
@@ -86,6 +86,40 @@ int my_hal_filterFree(cvhalFilter2D *context) {
|
||||
*/
|
||||
struct cvhalFilter2D {};
|
||||
|
||||
/**
|
||||
@brief 2D filtering in a stateless manner
|
||||
@param src_data source image data
|
||||
@param src_step source image step
|
||||
@param src_type source image type
|
||||
@param dst_data destination image data
|
||||
@param dst_step destination image step
|
||||
@param dst_type destination image type
|
||||
@param width images width
|
||||
@param height images height
|
||||
@param full_width full width of source image (outside the ROI)
|
||||
@param full_height full height of source image (outside the ROI)
|
||||
@param offset_x source image ROI offset X
|
||||
@param offset_y source image ROI offset Y
|
||||
@param kernel_data pointer to kernel data
|
||||
@param kernel_step kernel step
|
||||
@param kernel_type kernel type (CV_8U, ...)
|
||||
@param kernel_width kernel width
|
||||
@param kernel_height kernel height
|
||||
@param anchor_x relative X position of center point within the kernel
|
||||
@param anchor_y relative Y position of center point within the kernel
|
||||
@param delta added to pixel values
|
||||
@param borderType border processing mode (CV_HAL_BORDER_REFLECT, ...)
|
||||
@param isSubmatrix indicates whether the submatrices will be allowed as source image
|
||||
@param allowInplace indicates whether the inplace operation will be possible
|
||||
@sa cv::filter2D, cv::hal::Filter2D
|
||||
*/
|
||||
inline int hal_ni_filter_stateless(const uchar * src_data, size_t src_step, int src_type,
|
||||
uchar * dst_data, size_t dst_step, int dst_type,
|
||||
int width, int height, int full_width, int full_height, int offset_x, int offset_y,
|
||||
const uchar * kernel_data, size_t kernel_step, int kernel_type, int kernel_width, int kernel_height,
|
||||
int anchor_x, int anchor_y, double delta, int borderType, bool isSubmatrix, bool allowInplace)
|
||||
{ return CV_HAL_ERROR_NOT_IMPLEMENTED; }
|
||||
|
||||
/**
|
||||
@brief hal_filterInit
|
||||
@param context double pointer to user-defined context
|
||||
@@ -131,11 +165,45 @@ inline int hal_ni_filter(cvhalFilter2D *context, uchar *src_data, size_t src_ste
|
||||
inline int hal_ni_filterFree(cvhalFilter2D *context) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
|
||||
|
||||
//! @cond IGNORED
|
||||
#define cv_hal_filter_stateless hal_ni_filter_stateless
|
||||
#define cv_hal_filterInit hal_ni_filterInit
|
||||
#define cv_hal_filter hal_ni_filter
|
||||
#define cv_hal_filterFree hal_ni_filterFree
|
||||
//! @endcond
|
||||
|
||||
/**
|
||||
@brief separable filtering in a stateless manner
|
||||
@param src_data source image data
|
||||
@param src_step source image step
|
||||
@param src_type source image type
|
||||
@param dst_data destination image data
|
||||
@param dst_step destination image step
|
||||
@param dst_type destination image type
|
||||
@param width images width
|
||||
@param height images height
|
||||
@param full_width full width of source image (outside the ROI)
|
||||
@param full_height full height of source image (outside the ROI)
|
||||
@param offset_x source image ROI offset X
|
||||
@param offset_y source image ROI offset Y
|
||||
@param kernelx_data pointer to x-kernel data
|
||||
@param kernelx_len x-kernel vector length
|
||||
@param kernely_data pointer to y-kernel data
|
||||
@param kernely_len y-kernel vector length
|
||||
@param kernel_type kernel type (CV_8U, ...)
|
||||
@param anchor_x relative X position of center point within the kernel
|
||||
@param anchor_y relative Y position of center point within the kernel
|
||||
@param delta added to pixel values
|
||||
@param borderType border processing mode (CV_HAL_BORDER_REFLECT, ...)
|
||||
@sa cv::sepFilter2D, cv::hal::SepFilter2D
|
||||
*/
|
||||
inline int hal_ni_sepFilter_stateless(const uchar * src_data, size_t src_step, int src_type,
|
||||
uchar * dst_data, size_t dst_step, int dst_type,
|
||||
int width, int height, int full_width, int full_height, int offset_x, int offset_y,
|
||||
const uchar * kernelx_data, int kernelx_len,
|
||||
const uchar * kernely_data, int kernely_len,
|
||||
int kernel_type, int anchor_x, int anchor_y, double delta, int borderType)
|
||||
{ return CV_HAL_ERROR_NOT_IMPLEMENTED; }
|
||||
|
||||
/**
|
||||
@brief hal_sepFilterInit
|
||||
@param context double pointer to user-defined context
|
||||
@@ -177,11 +245,54 @@ inline int hal_ni_sepFilter(cvhalFilter2D *context, uchar *src_data, size_t src_
|
||||
inline int hal_ni_sepFilterFree(cvhalFilter2D *context) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
|
||||
|
||||
//! @cond IGNORED
|
||||
#define cv_hal_sepFilter_stateless hal_ni_sepFilter_stateless
|
||||
#define cv_hal_sepFilterInit hal_ni_sepFilterInit
|
||||
#define cv_hal_sepFilter hal_ni_sepFilter
|
||||
#define cv_hal_sepFilterFree hal_ni_sepFilterFree
|
||||
//! @endcond
|
||||
|
||||
/**
|
||||
@brief morphology in a stateless manner
|
||||
@param operation morphology operation CV_HAL_MORPH_ERODE or CV_HAL_MORPH_DILATE
|
||||
@param src_data source image data
|
||||
@param src_step source image step
|
||||
@param src_type source image type
|
||||
@param dst_data destination image data
|
||||
@param dst_step destination image step
|
||||
@param dst_type destination image type
|
||||
@param width images width
|
||||
@param height images height
|
||||
@param src_full_width full width of source image (outside the ROI)
|
||||
@param src_full_height full height of source image (outside the ROI)
|
||||
@param src_roi_x source image ROI X offset
|
||||
@param src_roi_y source image ROI Y offset
|
||||
@param dst_full_width full width of destination image
|
||||
@param dst_full_height full height of destination image
|
||||
@param dst_roi_x destination image ROI X offset
|
||||
@param dst_roi_y destination image ROI Y offset
|
||||
@param kernel_data pointer to kernel data
|
||||
@param kernel_step kernel step
|
||||
@param kernel_type kernel type (CV_8U, ...)
|
||||
@param kernel_width kernel width
|
||||
@param kernel_height kernel height
|
||||
@param anchor_x relative X position of center point within the kernel
|
||||
@param anchor_y relative Y position of center point within the kernel
|
||||
@param borderType border processing mode (CV_HAL_BORDER_REFLECT, ...)
|
||||
@param borderValue values to use for CV_HAL_BORDER_CONSTANT mode
|
||||
@param iterations number of iterations
|
||||
@param allowSubmatrix indicates whether the submatrices will be allowed as source image
|
||||
@param allowInplace indicates whether the inplace operation will be possible
|
||||
@sa cv::erode, cv::dilate, cv::morphologyEx, cv::hal::Morph
|
||||
*/
|
||||
inline int hal_ni_morph_stateless(int operation, const uchar * src_data, size_t src_step, int src_type,
|
||||
uchar * dst_data, size_t dst_step, int dst_type,
|
||||
int width, int height, int src_full_width, int src_full_height, int src_roi_x, int src_roi_y,
|
||||
int dst_full_width, int dst_full_height, int dst_roi_x, int dst_roi_y,
|
||||
const uchar * kernel_data, size_t kernel_step, int kernel_type, int kernel_width, int kernel_height,
|
||||
int anchor_x, int anchor_y, int borderType, const double borderValue[4],
|
||||
int iterations, bool allowSubmatrix, bool allowInplace)
|
||||
{ return CV_HAL_ERROR_NOT_IMPLEMENTED; }
|
||||
|
||||
/**
|
||||
@brief hal_morphInit
|
||||
@param context double pointer to user-defined context
|
||||
@@ -233,6 +344,7 @@ inline int hal_ni_morph(cvhalFilter2D *context, uchar *src_data, size_t src_step
|
||||
inline int hal_ni_morphFree(cvhalFilter2D *context) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
|
||||
|
||||
//! @cond IGNORED
|
||||
#define cv_hal_morph_stateless hal_ni_morph_stateless
|
||||
#define cv_hal_morphInit hal_ni_morphInit
|
||||
#define cv_hal_morph hal_ni_morph
|
||||
#define cv_hal_morphFree hal_ni_morphFree
|
||||
|
||||
@@ -1024,7 +1024,7 @@ void HoughLinesPointSet( InputArray _point, OutputArray _lines, int lines_max, i
|
||||
int r = idx - (n+1)*(numrho+2) - 1;
|
||||
line.rho = static_cast<float>(min_rho) + r * (float)rho_step;
|
||||
line.angle = static_cast<float>(min_theta) + n * (float)theta_step;
|
||||
lines.push_back(Vec3d((double)accum[idx], (double)line.rho, (double)line.angle));
|
||||
lines.emplace_back((double)accum[idx], (double)line.rho, (double)line.angle);
|
||||
}
|
||||
|
||||
Mat(lines).copyTo(_lines);
|
||||
@@ -1125,7 +1125,7 @@ public:
|
||||
{
|
||||
if (ptr[x])
|
||||
{
|
||||
list.push_back(Point(x, y));
|
||||
list.emplace_back(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1489,7 +1489,7 @@ protected:
|
||||
// Check if the circle has enough support
|
||||
if(maxCount > accThreshold)
|
||||
{
|
||||
circlesLocal.push_back(EstimatedCircle(Vec3f(curCenter.x, curCenter.y, rBest), maxCount));
|
||||
circlesLocal.emplace_back(Vec3f(curCenter.x, curCenter.y, rBest), maxCount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1847,7 +1847,7 @@ static void HoughCirclesAlt( const Mat& img, std::vector<EstimatedCircle>& circl
|
||||
continue;
|
||||
|
||||
mdata[y*mstep + x] = (uchar)1;
|
||||
stack.push_back(Point(x, y));
|
||||
stack.emplace_back(x, y);
|
||||
bool backtrace_mode = false;
|
||||
|
||||
do
|
||||
@@ -1858,7 +1858,7 @@ static void HoughCirclesAlt( const Mat& img, std::vector<EstimatedCircle>& circl
|
||||
int vy = dyData[p.y*dxystep + p.x];
|
||||
|
||||
float mag = std::sqrt((float)vx*vx+(float)vy*vy);
|
||||
nz.push_back(Vec4f((float)p.x, (float)p.y, (float)vx, (float)vy));
|
||||
nz.emplace_back((float)p.x, (float)p.y, (float)vx, (float)vy);
|
||||
CV_Assert(mdata[p.y*mstep + p.x] == 1);
|
||||
|
||||
int sx = cvRound(vx * RAY_FP_SCALE / mag);
|
||||
@@ -1903,7 +1903,7 @@ static void HoughCirclesAlt( const Mat& img, std::vector<EstimatedCircle>& circl
|
||||
if( mdata[y_*mstep + x_] || !edgeData[y_*estep + x_])
|
||||
continue;
|
||||
mdata[y_*mstep + x_] = (uchar)1;
|
||||
stack.push_back(Point(x_, y_));
|
||||
stack.emplace_back(x_, y_);
|
||||
neighbors++;
|
||||
}
|
||||
|
||||
@@ -1919,7 +1919,7 @@ static void HoughCirclesAlt( const Mat& img, std::vector<EstimatedCircle>& circl
|
||||
// insert a special "stop marker" in the end of each
|
||||
// connected component to make sure we
|
||||
// finalize and analyze the arc segment
|
||||
nz.push_back(Vec4f(0.f, 0.f, 0.f, 0.f));
|
||||
nz.emplace_back(0.f, 0.f, 0.f, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1951,7 +1951,7 @@ static void HoughCirclesAlt( const Mat& img, std::vector<EstimatedCircle>& circl
|
||||
{
|
||||
float cx = (float)((left + x - 1)*dp*0.5f);
|
||||
float cy = (float)(y*dp);
|
||||
centers.push_back(Point2f(cx, cy));
|
||||
centers.emplace_back(cx, cy);
|
||||
left = -1;
|
||||
}
|
||||
}
|
||||
@@ -2223,7 +2223,7 @@ static void HoughCirclesAlt( const Mat& img, std::vector<EstimatedCircle>& circl
|
||||
// (accepted ? '+' : '-'), cx, cy, rk, cjk.weight, count, max_runlen, cjk.mask);
|
||||
|
||||
if( accepted )
|
||||
local_circles.push_back(EstimatedCircle(Vec3f(cx, cy, (float)rk), cjk.weight));
|
||||
local_circles.emplace_back(Vec3f(cx, cy, (float)rk), cjk.weight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,8 +212,22 @@ static bool halMorph(int op, int src_type, int dst_type,
|
||||
int kernel_width, int kernel_height, int anchor_x, int anchor_y,
|
||||
int borderType, const double borderValue[4], int iterations, bool isSubmatrix)
|
||||
{
|
||||
// Prioritize stateless implementation
|
||||
int res = cv_hal_morph_stateless(op, src_data, src_step, src_type, dst_data, dst_step, dst_type, width, height,
|
||||
roi_width, roi_height, roi_x, roi_y, roi_width2, roi_height2, roi_x2, roi_y2,
|
||||
kernel_data, kernel_step, kernel_type, kernel_width, kernel_height, anchor_x, anchor_y,
|
||||
borderType, borderValue, iterations, isSubmatrix, src_data == dst_data);
|
||||
if (res == CV_HAL_ERROR_OK)
|
||||
{
|
||||
return true;
|
||||
} else if (res != CV_HAL_ERROR_NOT_IMPLEMENTED)
|
||||
{
|
||||
CV_Error_(cv::Error::StsInternal,
|
||||
("HAL implementation morph_stateless ==> " CVAUX_STR(cv_hal_morph_stateless) " returned %d (0x%08x)", res, res));
|
||||
}
|
||||
|
||||
cvhalFilter2D * ctx;
|
||||
int res = cv_hal_morphInit(&ctx, op, src_type, dst_type, width, height,
|
||||
res = cv_hal_morphInit(&ctx, op, src_type, dst_type, width, height,
|
||||
kernel_type, kernel_data, kernel_step, kernel_width, kernel_height,
|
||||
anchor_x, anchor_y,
|
||||
borderType, borderValue,
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
#include "precomp.hpp"
|
||||
#include <cmath>
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename T>
|
||||
void calculateCrossPowerSpectrum(const cv::Mat& dft1, const cv::Mat& dft2, cv::Mat& cps)
|
||||
{
|
||||
for (int row = 0; row < dft1.rows; ++row)
|
||||
{
|
||||
auto* cpsp = cps.ptr<cv::Vec<T, 2>>(row);
|
||||
const auto* dft1p = dft1.ptr<cv::Vec<T, 2>>(row);
|
||||
const auto* dft2p = dft2.ptr<cv::Vec<T, 2>>(row);
|
||||
for (int col = 0; col < dft1.cols; ++col)
|
||||
{
|
||||
const T re = dft1p[col][0] * dft2p[col][0] + dft1p[col][1] * dft2p[col][1];
|
||||
const T im = dft1p[col][0] * dft2p[col][1] - dft1p[col][1] * dft2p[col][0];
|
||||
const T mag = std::sqrt(re * re + im * im);
|
||||
cpsp[col][0] = re / mag;
|
||||
cpsp[col][1] = im / mag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cv::Mat calculateCrossPowerSpectrum(const cv::Mat& dft1, const cv::Mat& dft2)
|
||||
{
|
||||
cv::Mat cps(dft1.rows, dft1.cols, dft1.type());
|
||||
if (dft1.type() == CV_32FC2)
|
||||
calculateCrossPowerSpectrum<float>(dft1, dft2, cps);
|
||||
else if (dft1.type() == CV_64FC2)
|
||||
calculateCrossPowerSpectrum<double>(dft1, dft2, cps);
|
||||
else
|
||||
CV_Error(cv::Error::StsNotImplemented, "Only CV_32FC2 and CV_64FC2 types are supported");
|
||||
return cps;
|
||||
}
|
||||
|
||||
void fftshift(cv::Mat& out)
|
||||
{
|
||||
int cx = out.cols / 2;
|
||||
int cy = out.rows / 2;
|
||||
cv::Mat q0(out, cv::Rect(0, 0, cx, cy));
|
||||
cv::Mat q1(out, cv::Rect(cx, 0, cx, cy));
|
||||
cv::Mat q2(out, cv::Rect(0, cy, cx, cy));
|
||||
cv::Mat q3(out, cv::Rect(cx, cy, cx, cy));
|
||||
|
||||
cv::Mat tmp;
|
||||
q0.copyTo(tmp);
|
||||
q3.copyTo(q0);
|
||||
tmp.copyTo(q3);
|
||||
q1.copyTo(tmp);
|
||||
q2.copyTo(q1);
|
||||
tmp.copyTo(q2);
|
||||
}
|
||||
|
||||
bool isOutOfBounds(const cv::Point2i& peak, const cv::Mat& mat, int size)
|
||||
{
|
||||
return peak.x - size / 2 < 0 || peak.y - size / 2 < 0 || peak.x + size / 2 >= mat.cols ||
|
||||
peak.y + size / 2 >= mat.rows;
|
||||
}
|
||||
|
||||
bool reduceL2size(int& L2size)
|
||||
{
|
||||
L2size -= 2;
|
||||
return L2size >= 3;
|
||||
}
|
||||
|
||||
int getL1size(int L2Usize, double L1ratio)
|
||||
{
|
||||
int L1size = static_cast<int>(std::floor(L1ratio * L2Usize));
|
||||
return (L1size % 2) ? L1size : L1size + 1;
|
||||
}
|
||||
|
||||
cv::Point2d getPeakSubpixel(const cv::Mat& mat)
|
||||
{
|
||||
const auto m = moments(mat);
|
||||
return cv::Point2d(m.m10 / m.m00, m.m01 / m.m00);
|
||||
}
|
||||
|
||||
bool accuracyReached(const cv::Point2d& L1peak, const cv::Point2d& L1mid)
|
||||
{
|
||||
return std::abs(L1peak.x - L1mid.x) < 0.5 && std::abs(L1peak.y - L1mid.y) < 0.5;
|
||||
}
|
||||
|
||||
cv::Point2d getSubpixelShift(const cv::Mat& L3,
|
||||
const cv::Point2d& L3peak,
|
||||
const cv::Point2d& L3mid,
|
||||
int L2size)
|
||||
{
|
||||
while (isOutOfBounds(L3peak, L3, L2size))
|
||||
if (!reduceL2size(L2size))
|
||||
return L3peak - L3mid;
|
||||
|
||||
cv::Mat L2 = L3(cv::Rect(static_cast<int>(L3peak.x - L2size / 2),
|
||||
static_cast<int>(L3peak.y - L2size / 2),
|
||||
L2size,
|
||||
L2size));
|
||||
cv::Point2d L2peak = getPeakSubpixel(L2);
|
||||
cv::Point2d L2mid(L2.cols / 2, L2.rows / 2);
|
||||
return L3peak - L3mid + L2peak - L2mid;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
cv::Point2d
|
||||
cv::phaseCorrelateIterative(InputArray _src1, InputArray _src2, int L2size, int maxIters)
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
Mat src1 = _src1.getMat();
|
||||
Mat src2 = _src2.getMat();
|
||||
|
||||
CV_Assert(src1.type() == src2.type());
|
||||
CV_Assert(src1.size() == src2.size());
|
||||
CV_Assert(src1.type() == CV_32FC1 || src1.type() == CV_64FC1);
|
||||
|
||||
// apply DFT window to input images
|
||||
Mat window;
|
||||
createHanningWindow(window, src1.size(), _src1.type());
|
||||
Mat image1, image2;
|
||||
multiply(_src1, window, image1);
|
||||
multiply(_src2, window, image2);
|
||||
|
||||
// compute the DFTs of input images
|
||||
dft(image1, image1, DFT_COMPLEX_OUTPUT);
|
||||
dft(image2, image2, DFT_COMPLEX_OUTPUT);
|
||||
|
||||
// compute the phase correlation landscape L3
|
||||
Mat L3 = calculateCrossPowerSpectrum(image1, image2);
|
||||
dft(L3, L3, DFT_INVERSE | DFT_SCALE | DFT_REAL_OUTPUT);
|
||||
fftshift(L3);
|
||||
Point2d L3mid(L3.cols / 2, L3.rows / 2);
|
||||
|
||||
// calculate the maximum correlation location
|
||||
Point2i L3peak;
|
||||
minMaxLoc(L3, nullptr, nullptr, nullptr, &L3peak);
|
||||
|
||||
// reduce the L2size as long as L2 is out of bounds of L3
|
||||
while (isOutOfBounds(L3peak, L3, L2size))
|
||||
if (!reduceL2size(L2size))
|
||||
return Point2d(L3peak) - L3mid;
|
||||
|
||||
// extract the L2 maximum correlation neighborhood from L3
|
||||
Mat L2 = L3(Rect(L3peak.x - L2size / 2, L3peak.y - L2size / 2, L2size, L2size));
|
||||
|
||||
// upsample L2 maximum correlation neighborhood to get L2U
|
||||
Mat L2U;
|
||||
const int L2Usize = 223; // empirically determined optimal constant
|
||||
resize(L2, L2U, {L2Usize, L2Usize}, 0, 0, INTER_LINEAR);
|
||||
const Point2d L2Umid(L2U.cols / 2, L2U.rows / 2);
|
||||
|
||||
// run the iterative refinement algorithm using the specified L1 ratio
|
||||
// gradually decrease L1 ratio if convergence is not achieved
|
||||
const double L1ratioBase = 0.45; // empirically determined optimal constant
|
||||
const double L1ratioStep = 0.025;
|
||||
for (double L1ratio = L1ratioBase; getL1size(L2U.cols, L1ratio) > 0; L1ratio -= L1ratioStep)
|
||||
{
|
||||
Point2d L2Upeak = L2Umid; // reset the accumulated L2U peak position
|
||||
const int L1size = getL1size(L2U.cols, L1ratio); // calculate the current L1 size
|
||||
const Point2d L1mid(L1size / 2, L1size / 2); // update the L1 mid position
|
||||
|
||||
// perform the iterative refinement algorithm
|
||||
for (int iter = 0; iter < maxIters; ++iter)
|
||||
{
|
||||
// verify that the L1 region is within the L2U region
|
||||
if (isOutOfBounds(L2Upeak, L2U, L1size))
|
||||
break;
|
||||
|
||||
// extract the L1 region from L2U
|
||||
const Mat L1 = L2U(Rect(static_cast<int>(L2Upeak.x - L1size / 2),
|
||||
static_cast<int>(L2Upeak.y - L1size / 2),
|
||||
L1size,
|
||||
L1size));
|
||||
|
||||
// calculate the centroid location
|
||||
const Point2d L1peak = getPeakSubpixel(L1);
|
||||
|
||||
// add the contribution of the current iteration to the accumulated L2U peak location
|
||||
L2Upeak += Point2d(std::round(L1peak.x - L1mid.x), std::round(L1peak.y - L1mid.y));
|
||||
|
||||
// check for convergence
|
||||
if (accuracyReached(L1peak, L1mid))
|
||||
// return the refined subpixel image shift
|
||||
return Point2d(L3peak) - L3mid +
|
||||
(L2Upeak - L2Umid + L1peak - L1mid) /
|
||||
(static_cast<double>(L2Usize) / L2size);
|
||||
}
|
||||
}
|
||||
|
||||
// iterative refinement failed to converge, return non-iterative subpixel shift
|
||||
return getSubpixelShift(L3, Point2d(L3peak), L3mid, L2size);
|
||||
}
|
||||
@@ -365,7 +365,7 @@ cv::RotatedRect cv::minAreaRect( InputArray _points )
|
||||
Mat hull;
|
||||
Point2f out[3];
|
||||
RotatedRect box;
|
||||
box.angle = -(float)CV_PI / 2; // default angle for box without rotation and single point
|
||||
double angle = -CV_PI / 2; // default angle for box without rotation and single point
|
||||
|
||||
static const bool clockwise = false;
|
||||
convexHull(_points, hull, clockwise, true);
|
||||
@@ -390,7 +390,7 @@ cv::RotatedRect cv::minAreaRect( InputArray _points )
|
||||
if (out[1].x == 0.f && out[1].y > 0.f)
|
||||
std::swap(box.size.width, box.size.height);
|
||||
else
|
||||
box.angle += (float)atan2( (double)out[1].y, (double)out[1].x );
|
||||
angle = -atan2( (double)out[1].x, (double)out[1].y );
|
||||
}
|
||||
else if( n == 2 )
|
||||
{
|
||||
@@ -406,12 +406,12 @@ cv::RotatedRect cv::minAreaRect( InputArray _points )
|
||||
}
|
||||
else if (dy < 0)
|
||||
{
|
||||
box.angle = (float)atan2( dy, dx );
|
||||
angle = atan2( dy, dx );
|
||||
std::swap(box.size.width, box.size.height);
|
||||
}
|
||||
else if (dy > 0)
|
||||
{
|
||||
box.angle += (float)atan2( dy, dx );
|
||||
angle = -atan2( dx, dy );
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -420,7 +420,7 @@ cv::RotatedRect cv::minAreaRect( InputArray _points )
|
||||
box.center = hpoints[0];
|
||||
}
|
||||
|
||||
box.angle = (float)(box.angle*180/CV_PI);
|
||||
box.angle = (float)(angle*180/CV_PI);
|
||||
CV_DbgCheckGE(box.angle, -90.0f, "");
|
||||
CV_DbgCheckLT(box.angle, 0.0f, "");
|
||||
return box;
|
||||
|
||||
@@ -41,6 +41,7 @@ OTHER DEALINGS IN THE SOFTWARE.
|
||||
#include "opencv2/core/hal/intrin.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -1199,12 +1200,17 @@ void stackBlur(InputArray _src, OutputArray _dst, Size ksize)
|
||||
CV_Assert( ksize.width > 0 && ksize.width % 2 == 1 &&
|
||||
ksize.height > 0 && ksize.height % 2 == 1 );
|
||||
|
||||
int radiusH = ksize.height / 2;
|
||||
int radiusW = ksize.width / 2;
|
||||
|
||||
int stype = _src.type(), sdepth = _src.depth();
|
||||
Mat src = _src.getMat();
|
||||
|
||||
if (ksize.width > src.cols)
|
||||
ksize.width = (src.cols % 2 == 0) ? std::max(1, src.cols - 1) : src.cols;
|
||||
if (ksize.height > src.rows)
|
||||
ksize.height = (src.rows % 2 == 0) ? std::max(1, src.rows - 1) : src.rows;
|
||||
|
||||
int radiusH = ksize.height / 2;
|
||||
int radiusW = ksize.width / 2;
|
||||
|
||||
if (ksize.width == 1)
|
||||
{
|
||||
_src.copyTo(_dst);
|
||||
|
||||
@@ -265,7 +265,7 @@ int Subdiv2D::newPoint(Point2f pt, bool isvirtual, int firstEdge)
|
||||
{
|
||||
if( freePoint == 0 )
|
||||
{
|
||||
vtx.push_back(Vertex());
|
||||
vtx.emplace_back();
|
||||
freePoint = (int)(vtx.size()-1);
|
||||
}
|
||||
int vidx = freePoint;
|
||||
@@ -520,8 +520,8 @@ void Subdiv2D::initDelaunay( Rect rect )
|
||||
Point2f ppB( rx, ry + big_coord );
|
||||
Point2f ppC( rx - big_coord, ry - big_coord );
|
||||
|
||||
vtx.push_back(Vertex());
|
||||
qedges.push_back(QuadEdge());
|
||||
vtx.emplace_back();
|
||||
qedges.emplace_back();
|
||||
|
||||
freeQEdge = 0;
|
||||
freePoint = 0;
|
||||
@@ -566,8 +566,8 @@ void Subdiv2D::initDelaunay( Rect2f rect )
|
||||
Point2f ppB( rx, ry + big_coord );
|
||||
Point2f ppC( rx - big_coord, ry - big_coord );
|
||||
|
||||
vtx.push_back(Vertex());
|
||||
qedges.push_back(QuadEdge());
|
||||
vtx.emplace_back();
|
||||
qedges.emplace_back();
|
||||
|
||||
freeQEdge = 0;
|
||||
freePoint = 0;
|
||||
@@ -784,7 +784,7 @@ void Subdiv2D::getEdgeList(std::vector<Vec4f>& edgeList) const
|
||||
{
|
||||
Point2f org = vtx[qedges[i].pt[0]].pt;
|
||||
Point2f dst = vtx[qedges[i].pt[2]].pt;
|
||||
edgeList.push_back(Vec4f(org.x, org.y, dst.x, dst.y));
|
||||
edgeList.emplace_back(org.x, org.y, dst.x, dst.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -836,7 +836,7 @@ void Subdiv2D::getTriangleList(std::vector<Vec6f>& triangleList) const
|
||||
edgemask[edge_a] = true;
|
||||
edgemask[edge_b] = true;
|
||||
edgemask[edge_c] = true;
|
||||
triangleList.push_back(Vec6f(a.x, a.y, b.x, b.y, c.x, c.y));
|
||||
triangleList.emplace_back(a.x, a.y, b.x, b.y, c.x, c.y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user