OpenCV:15.图片的几何变换

具体代码请看:NDKPractice项目的opencv63

1. 图片旋转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Java_com_east_opencv63_OpenCvUtils_rotation(JNIEnv *env, jclass clazz, jobject bitmap) {
Mat src;
cv_helper::bitmap2mat(env, bitmap, src);

int res_w = src.rows; // 图片的宽
int res_h = src.cols; // 图片的高

Mat res(res_h, res_w, src.type());

// 处理输出图像的下半部分
for (int row = 0; row < res_h; ++row) {
for (int col = 0; col < res_w; ++col) {
if (src.type() == CV_8UC4)
res.at<Vec4b>(row, col) = src.at<Vec4b>(src.rows - col, row);
else if (src.type() == CV_8UC2)
res.at<Vec3b>(row, col) = src.at<Vec3b>(src.rows - col, row);
else if (src.type() == CV_8UC1)
res.at<uchar>(row, col) = src.at<uchar>(src.rows - col, row);
}
}

// 创建一个新的bitmap 宽是原来的高,高是原来的宽
jobject newBitmap = bitmap_util::create_bitmap(env, res_w, res_h, res.type());
cv_helper::mat2bitmap(env, res, newBitmap);
return newBitmap;
}

2. 矩阵仿射变换

使用到的 api

1
2
3
4
5
6
7
8
9
10
// center 旋转中心点  angle 逆时针 scale 缩放比例
Mat getRotationMatrix2D(Point2f center, double angle, double scale)


// 图像仿射变换的 用到的 api
CV_EXPORTS_W void warpAffine( InputArray src, OutputArray dst,
InputArray M, Size dsize,
int flags = INTER_LINEAR,
int borderMode = BORDER_CONSTANT,
const Scalar& borderValue = Scalar());

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 图片仿射变换
extern "C"
JNIEXPORT jobject JNICALL
Java_com_east_opencv63_OpenCvUtils_warpAffine(JNIEnv *env, jclass clazz, jobject bitmap) {
Mat src;
cv_helper::bitmap2mat(env, bitmap, src);

Mat res(src.size(), src.type());
/*Mat M(2,3,CV_32FC1);
// 这几个值应该怎么确定?
// [a0,a1,a2] 两个矩阵 [a0,a1] [a2] = [ x ] * [a0,a1] + [a2] = a0*x+b0*x + a2
// [b0,b1,b2] [b0,b1] [b2] [ y ] [b0,b1] [b2] = b1*y+b1*y + b2
M.at<float>(0,0) = 1;// a0
M.at<float>(0,1) = 0;// a1
M.at<float>(0,2) = 0;// a2
M.at<float>(1,0) = 0; // b1
M.at<float>(1,1) = 1; // b2
M.at<float>(1,2) = 0;*/ //b3

Point2f center(src.cols / 2, src.rows / 2);
Mat M = getRotationMatrix2D(center, 45, 1);

warpAffine(src, res, M, src.size());

cv_helper::mat2bitmap(env, res, bitmap);
return bitmap;
}

3. reSize() 图片缩放

  • INTER_NEAREST - 最近邻插值
  • INTER_LINEAR - 线性插值(默认值)
  • INTER_AREA - 区域插值(利用像素区域关系的重采样插值)
  • INTER_CUBIC –三次样条插值(超过4×4像素邻域内的双三次插值)
  • INTER_LANCZOS4 -Lanczos插值(超过8×8像素邻域的Lanczos插值)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// 图片缩放
extern "C"
JNIEXPORT jobject JNICALL
Java_com_east_opencv63_OpenCvUtils_resize(JNIEnv *env, jclass clazz, jobject bitmap, jint width,
jint height) {
Mat src;
cv_helper::bitmap2mat(env, bitmap, src);
Mat res(height, width, src.type());

float src_w = src.cols;
float src_h = src.rows;

for (int row = 0; row < height; ++row) {
for (int col = 0; col < width; ++col) {

int src_row = row * (src_h / height);
int src_col = col * (src_w / width);

if (src.type() == CV_8UC4)
res.at<Vec4b>(row, col) = src.at<Vec4b>(src_row, src_col);
else if (src.type() == CV_8UC2)
res.at<Vec3b>(row, col) = src.at<Vec3b>(src_row, src_col);
else if (src.type() == CV_8UC1)
res.at<uchar>(row, col) = src.at<uchar>(src_row, src_col);
}
}


jobject newBitmap = bitmap_util::create_bitmap(env, width, height, res.type());
cv_helper::mat2bitmap(env, res, newBitmap);
return newBitmap;
}

4.remap 重映射 (自己实现)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
void remap(Mat &src,Mat &res,Mat &matX,Mat &matY){
res.create(src.size(),src.type());
int res_w = res.cols;
int res_h = res.rows;
for (int row = 0; row < res_h; ++row) {
for (int col = 0; col < res_w; ++col) {
int x = matX.at<float>(row,col);
int y = matY.at<float>(row,col);
res.at<Vec4b>(row,col) = src.at<Vec4b>(y,x);
}
}
}

// 手写 Remap 重映射
extern "C"
JNIEXPORT jobject JNICALL
Java_com_east_opencv63_OpenCvUtils_reMap(JNIEnv *env, jclass clazz, jobject bitmap) {
Mat src;
cv_helper::bitmap2mat(env, bitmap, src);
Mat res;

Mat matX(src.size(), CV_32F);
Mat matY(src.size(), CV_32F);

for (int row = 0; row < src.rows; ++row) {
for (int col = 0; col < src.cols; ++col) {
matX.at<float>(row, col) = src.cols - col;
matY.at<float>(row, col) = src.rows - row;
}
}

remap(src, res, matX, matY);
cv_helper::mat2bitmap(env,res,bitmap);
return bitmap;
}
-------------本文结束感谢您的阅读-------------
坚持原创技术分享,您的支持将鼓励我继续创作!
0%