使用getRotationMatrix2D创建变换矩阵,通过SSE指令集加速warpAffine算子参数WARP_INVERSE_MAP效果的C++例程
时间: 2023-12-10 15:38:07 浏览: 84
C++矩阵变换
4星 · 用户满意度95%
以下是使用SSE指令集加速warpAffine算子参数WARP_INVERSE_MAP的C++例程:
```cpp
#include <iostream>
#include <opencv2/opencv.hpp>
#include <emmintrin.h>
using namespace std;
using namespace cv;
int main()
{
Mat src = imread("test.jpg");
if (src.empty())
{
cerr << "failed to read image." << endl;
return -1;
}
double angle = 30.0;
double scale = 0.8;
Mat rot_mat = getRotationMatrix2D(Point2f(src.cols / 2, src.rows / 2), angle, scale);
Mat dst(src.size(), src.type());
uchar* src_data = src.data;
uchar* dst_data = dst.data;
int width = src.cols * src.channels();
int height = src.rows;
int step = src.step;
__m128d cos_sin = _mm_set_pd(cos(angle * CV_PI / 180), sin(angle * CV_PI / 180));
__m128d scale_vec = _mm_set_pd(scale, scale);
__m128d src_center = _mm_set_pd(src.cols / 2, src.rows / 2);
for (int j = 0; j < height; j++)
{
for (int i = 0; i < width; i += 16)
{
__m128d src_x_vec = _mm_set_pd(i + 1, i);
__m128d src_y_vec = _mm_set1_pd(j);
__m128d src_vec = _mm_shuffle_pd(src_x_vec, src_y_vec, _MM_SHUFFLE2(0, 0));
__m128d tmp_vec = _mm_sub_pd(src_vec, src_center);
__m128d rot_vec = _mm_mul_pd(tmp_vec, cos_sin);
rot_vec = _mm_add_pd(rot_vec, _mm_shuffle_pd(rot_vec, rot_vec, _MM_SHUFFLE2(1, 0)));
rot_vec = _mm_mul_pd(rot_vec, scale_vec);
__m128d dst_vec = _mm_add_pd(rot_vec, src_center);
int dst_x = static_cast<int>(_mm_cvtsd_f64(dst_vec));
int dst_y = static_cast<int>(_mm_cvtsd_f64(_mm_unpackhi_pd(dst_vec, dst_vec)));
if (dst_x >= 0 && dst_x < src.cols && dst_y >= 0 && dst_y < src.rows)
{
const uchar* src_ptr = src_data + dst_y * step + dst_x * src.channels();
uchar* dst_ptr = dst_data + j * step + i;
for (int k = 0; k < src.channels(); k++)
{
dst_ptr[k] = src_ptr[k];
}
}
}
}
imshow("src", src);
imshow("dst", dst);
waitKey();
return 0;
}
```
首先,用`getRotationMatrix2D()`函数创建变换矩阵。然后,使用SSE指令集加速warpAffine算子参数WARP_INVERSE_MAP的实现。具体来说,我们使用SSE指令集加速计算每个像素的变换后坐标,并且在遍历像素时进行条件判断,以避免越界访问。最后,将变换后的像素值复制到目标图像中。
阅读全文