提交 50595239 编写于 作者: A Alexander Alekhin

core: fix processing of vector-rows

上级 e5d7f446
......@@ -199,6 +199,8 @@ static void binary_op( InputArray _src1, InputArray _src2, OutputArray _dst,
func = tab[depth1];
Mat src1 = psrc1->getMat(), src2 = psrc2->getMat(), dst = _dst.getMat();
if (_dst.isVector() && dst.size() != src1.size()) // https://github.com/opencv/opencv/pull/4159
dst = dst.reshape(0, (int)dst.total());
Size sz = getContinuousSize(src1, src2, dst);
size_t len = sz.width*(size_t)cn;
if( len == (size_t)(int)len )
......@@ -630,6 +632,8 @@ static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst,
usrdata, oclop, false))
Mat src1 = psrc1->getMat(), src2 = psrc2->getMat(), dst = _dst.getMat();
if (_dst.isVector() && dst.size() != src1.size()) // https://github.com/opencv/opencv/pull/4159
dst = dst.reshape(0, (int)dst.total());
Size sz = getContinuousSize(src1, src2, dst, src1.channels());
tab[depth1](src1.ptr(), src1.step, src2.ptr(), src2.step, dst.ptr(), dst.step, sz.width, sz.height, usrdata);
return;
......@@ -1279,6 +1283,8 @@ void cv::compare(InputArray _src1, InputArray _src2, OutputArray _dst, int op)
int cn = src1.channels();
_dst.create(src1.size(), CV_8UC(cn));
Mat dst = _dst.getMat();
if (_dst.isVector() && dst.size() != src1.size()) // https://github.com/opencv/opencv/pull/4159
dst = dst.reshape(0, (int)dst.total());
Size sz = getContinuousSize(src1, src2, dst, src1.channels());
getCmpFunc(src1.depth())(src1.ptr(), src1.step, src2.ptr(), src2.step, dst.ptr(), dst.step, sz.width, sz.height, &op);
return;
......
......@@ -443,7 +443,6 @@ void cv::Mat::convertTo(OutputArray _dst, int _type, double alpha, double beta)
_dst.create( dims, size, _type );
Mat dst = _dst.getMat();
BinaryFunc func = noScale ? getConvertFunc(sdepth, ddepth) : getConvertScaleFunc(sdepth, ddepth);
double scale[] = {alpha, beta};
int cn = channels();
......@@ -451,6 +450,8 @@ void cv::Mat::convertTo(OutputArray _dst, int _type, double alpha, double beta)
if( dims <= 2 )
{
if (_dst.isVector() && dst.size() != src.size()) // https://github.com/opencv/opencv/pull/4159
dst = dst.reshape(0, (int)dst.total());
Size sz = getContinuousSize(src, dst, cn);
func( src.data, src.step, 0, 0, dst.data, dst.step, sz, scale );
}
......@@ -512,6 +513,8 @@ void cv::convertFp16( InputArray _src, OutputArray _dst )
if( src.dims <= 2 )
{
if (_dst.isVector() && dst.size() != src.size()) // https://github.com/opencv/opencv/pull/4159
dst = dst.reshape(0, (int)dst.total());
Size sz = getContinuousSize(src, dst, cn);
func( src.data, src.step, 0, 0, dst.data, dst.step, sz, 0);
}
......
......@@ -427,6 +427,8 @@ void cv::convertScaleAbs( InputArray _src, OutputArray _dst, double alpha, doubl
if( src.dims <= 2 )
{
if (_dst.isVector() && dst.size() != src.size()) // https://github.com/opencv/opencv/pull/4159
dst = dst.reshape(0, (int)dst.total());
Size sz = getContinuousSize(src, dst, cn);
func( src.ptr(), src.step, 0, 0, dst.ptr(), dst.step, sz, scale );
}
......
......@@ -289,7 +289,7 @@ void Mat::copyTo( OutputArray _dst ) const
{
// For some cases (with vector) dst.size != src.size, so force to column-based form
// It prevents memory corruption in case of column-based src
if (_dst.isVector())
if (_dst.isVector() && dst.size() != size()) // https://github.com/opencv/opencv/pull/4159
dst = dst.reshape(0, (int)dst.total());
const uchar* sptr = data;
......@@ -403,6 +403,8 @@ void Mat::copyTo( OutputArray _dst, InputArray _mask ) const
if( dims <= 2 )
{
if (_dst.isVector() && dst.size() != size()) // https://github.com/opencv/opencv/pull/4159
dst = dst.reshape(0, (int)dst.total());
Size sz = getContinuousSize(*this, dst, mask, mcn);
copymask(data, step, mask.data, mask.step, dst.data, dst.step, sz, &esz);
return;
......
......@@ -168,6 +168,7 @@ inline Size getContinuousSize( const Mat& m1, int widthScale=1 )
inline Size getContinuousSize( const Mat& m1, const Mat& m2, int widthScale=1 )
{
CV_Assert(m1.size() == m2.size());
return getContinuousSize_(m1.flags & m2.flags,
m1.cols, m1.rows, widthScale);
}
......@@ -175,26 +176,12 @@ inline Size getContinuousSize( const Mat& m1, const Mat& m2, int widthScale=1 )
inline Size getContinuousSize( const Mat& m1, const Mat& m2,
const Mat& m3, int widthScale=1 )
{
CV_Assert(m1.size() == m2.size());
CV_Assert(m1.size() == m3.size());
return getContinuousSize_(m1.flags & m2.flags & m3.flags,
m1.cols, m1.rows, widthScale);
}
inline Size getContinuousSize( const Mat& m1, const Mat& m2,
const Mat& m3, const Mat& m4,
int widthScale=1 )
{
return getContinuousSize_(m1.flags & m2.flags & m3.flags & m4.flags,
m1.cols, m1.rows, widthScale);
}
inline Size getContinuousSize( const Mat& m1, const Mat& m2,
const Mat& m3, const Mat& m4,
const Mat& m5, int widthScale=1 )
{
return getContinuousSize_(m1.flags & m2.flags & m3.flags & m4.flags & m5.flags,
m1.cols, m1.rows, widthScale);
}
void setSize( Mat& m, int _dims, const int* _sz, const size_t* _steps, bool autoSteps=false );
void finalizeHdr(Mat& m);
int updateContinuityFlag(int flags, int dims, const int* size, const size_t* step);
......
......@@ -1940,5 +1940,36 @@ TEST(Core_InputArray, support_CustomType)
}
}
TEST(Core_Vectors, issue_13078)
{
float floats_[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
std::vector<float> floats(floats_, floats_ + 8);
std::vector<int> ints(4);
Mat m(4, 1, CV_32FC1, floats.data(), sizeof(floats[0]) * 2);
m.convertTo(ints, CV_32S);
ASSERT_EQ(1, ints[0]);
ASSERT_EQ(3, ints[1]);
ASSERT_EQ(5, ints[2]);
ASSERT_EQ(7, ints[3]);
}
TEST(Core_Vectors, issue_13078_workaround)
{
float floats_[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
std::vector<float> floats(floats_, floats_ + 8);
std::vector<int> ints(4);
Mat m(4, 1, CV_32FC1, floats.data(), sizeof(floats[0]) * 2);
m.convertTo(Mat(ints), CV_32S);
ASSERT_EQ(1, ints[0]);
ASSERT_EQ(3, ints[1]);
ASSERT_EQ(5, ints[2]);
ASSERT_EQ(7, ints[3]);
}
}} // namespace
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册