diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cb7570a02..b3ec5d754 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -31,6 +31,7 @@ set(ncnn_SRCS mat_pixel_drawing.cpp mat_pixel_resize.cpp mat_pixel_rotate.cpp + transform.cpp modelbin.cpp net.cpp option.cpp @@ -743,6 +744,7 @@ if(NCNN_INSTALL_SDK) layer_shader_type.h layer_type.h mat.h + transform.h modelbin.h net.h option.h diff --git a/src/transform.cpp b/src/transform.cpp new file mode 100644 index 000000000..368c5d3d7 --- /dev/null +++ b/src/transform.cpp @@ -0,0 +1,159 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#include + +#include "transform.h" + +namespace ncnn { + +namespace transform { + +Mat combine(const Mat& m1, const Mat& m2) +{ + Mat M(3, 2, sizeof(float)); + float row3[] = {0, 0, 1}; + float* p = M; + const float* p1 = m1; + const float* p2 = m2; + for (int row = 0; row < 2; ++row) + { + for (int col = 0; col < 3; ++col) + { + p[row * 3 + col] = p1[row * 3 + 0] * p2[0 * 3 + col] + p1[row * 3 + 1] * p2[1 * 3 + col] + p1[row * 3 + 2] * row3[col]; + } + } + return M; +} + +Mat rotation(const float degree, const float* center) +{ + int ndim = 2; + Mat M(3, 2, sizeof(float)); + float* mat = M; + float rad = degree * 3.14159265358979323846 / 180.0; + float c = cos(rad); + float s = sin(rad); + + M.fill(0); + mat[0] = c; + mat[1] = -s; + mat[3] = s; + mat[4] = c; + + if (center) + { + for (int d = 0; d < ndim; d++) + { + mat[d * 3 + ndim] = center[d] - center[0] * mat[d * 3 + 0] - center[1] * mat[d * 3 + 1]; + } + } + + return M; +} + +Mat shear(const float degree, float* center) +{ + int ndim = 2; + Mat M(3, 2, sizeof(float)); + float* mat = M; + float rad = degree * 3.14159265358979323846 / 180.0; + float s = tan(rad); + + M.fill(0); + mat[0] = 1; + mat[1] = s; + mat[3] = s; + mat[4] = 1; + + if (center) + { + for (int d = 0; d < ndim; d++) + { + mat[d * 3 + ndim] = center[d] - center[0] * mat[d * 3 + 0] - center[1] * mat[d * 3 + 1]; + } + } + + return M; +} + +Mat shear(const float* degrees, const float* center) +{ + int ndim = 2; + Mat M(3, 2, sizeof(float)); + float* mat = M; + float rad1 = degrees[0] * 3.14159265358979323846 / 180.0; + float s1 = tan(rad1); + float rad2 = degrees[1] * 3.14159265358979323846 / 180.0; + float s2 = tan(rad2); + + M.fill(0); + mat[0] = 1; + mat[1] = s1; + mat[3] = s2; + mat[4] = 1; + + if (center) + { + for (int d = 0; d < ndim; d++) + { + mat[d * 3 + ndim] = center[d] - center[0] * mat[d * 3 + 0] - center[1] * mat[d * 3 + 1]; + } + } + + return M; +} + +Mat scale(const float* scale, const float* center) +{ + int ndim = 2; + Mat M(3, 2, sizeof(float)); + M.fill(0); + float* mat = M; + + for (int d = 0; d < ndim; d++) + { + mat[d * 3 + d] = scale[d]; + } + if (center) + { + for (int d = 0; d < ndim; d++) + { + mat[d * 3 + ndim] = center[d] * (1 - scale[d]); + } + } + + return M; +} + +Mat translation(const float* offsets) +{ + int ndim = 2; + Mat M(3, 2, sizeof(float)); + float* mat = M; + + M.fill(0); + mat[0] = 1; + mat[4] = 1; + for (int d = 0; d < ndim; d++) + { + mat[d * 3 + ndim] = offsets[d]; + } + + return M; +} + +} // namespace transform + +} // namespace ncnn diff --git a/src/transform.h b/src/transform.h new file mode 100644 index 000000000..34ef819d5 --- /dev/null +++ b/src/transform.h @@ -0,0 +1,46 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef NCNN_TRANSFORM_H +#define NCNN_TRANSFORM_H + +#include "mat.h" + +namespace ncnn { + +namespace transform { + +Mat combine(const Mat& m1, const Mat& m2); + +template +Mat combine(const Mat& m1, const Mat& m2, const Args&... mats) +{ + return combine(combine(m1, m2), mats...); +} + +Mat rotation(const float degree, const float* center = NULL); + +Mat shear(const float degree, float* center = NULL); + +Mat shear(const float* degrees, const float* center = NULL); + +Mat scale(const float* scale, const float* center = NULL); + +Mat translation(const float* offsets); + +} // namespace transform + +} // namespace ncnn + +#endif // NCNN_TRANSFORM_H