我是靠谱客的博主 沉默诺言,这篇文章主要介绍利用OPENCV为android开发畸变校正的JNI库方法,现在分享给大家,希望可以做个参考。

需要为项目提供一套畸变校正的算法,由于需要大量的矩阵运算,考虑到效率和适时性,使用JNI开发,希望把有关数组短阵的处理的变换全部放入C语言中处理。

主要用于android移动端,大致的数据来源一是从camera直接读取YUV数据,一种是从第三方接读取RGB数据,另一种是直接对BITMAP进行处理。

1.考虑到硬件设备接口,第三方软件接口,图像接口,OPENCV接口,希望能够开发出通用的算法库,一劳永逸的解决各种复杂的使用场景,因此数据要支持YUV,支持ARGB,支持MAT

2android对BITMAP有获取像素点的操作,也有通过象素点生成BITMAP的操作,而且有很多图像处理接口和第三方可以处理RGB矩阵,如

复制代码
1
2
3
bm.getPixels(pixs, 0, w, 0, 0, w, h); int[] pixs1 = new int[w*h]; final Bitmap bm2 = Bitmap.createBitmap(pixs1, w, h, Bitmap.Config.ARGB_8888);

因此设计如下接口,入口为ARGB的整型,输出也是整型

复制代码
1
public static native boolean RgbaUndistort(int[] argb, int width, int height, int[] pixels);

3考虑到有些情况需要二维数组,

复制代码
1
public static native boolean RgbaUndistort2(int[][] rgb, int width, int height, int[] pixels);

4考虑到OPENCV的MAT结构,由于MAT有matToBitmap可以直接转化为BITMAP,应用MAT 提供

复制代码
1
public static native boolean RgbaUndistortMat(int[] argb, int width, int height, long pArgbOutMatAddr);

5考虑到第三方使用MAT的情况,因此输入也可以支持MAT因此设计接口

复制代码
1
public static native boolean RgbMatUndistortMat(long pArgbMatAddr, int width, int height, long pArgbOutMatAddr);

6考虑到摄像头输出YUV,提供YUV数据处理, 一个输出RGB, 一个输出MAT

复制代码
1
2
public static native boolean YuvNv21UndistortRgba(byte[] YuvNv21, int width, int height, int[] pixels); public static native boolean YuvNv21UndistortRgbaMat(byte[] YuvNv21, int width, int height, long pMatAddr);

7考虑到可能有不需要畸变的场合,为YUV设计一个灰度,一个RGB接口

复制代码
1
2
public static native boolean YuvNv21ToGray(byte[] YuvNv21,int width, int height, int[] pixels); public static native boolean YuvNv21ToRGBA(byte[] YuvNv21, int width, int height, int[] pixels);

8于是编写简单的JAVA头源生类

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class ImageProc3 { static { System.loadLibrary("ImgProc3"); } public static native boolean YuvNv21ToGray(byte[] YuvNv21,int width, int height, int[] pixels); public static native boolean YuvNv21ToRGBA(byte[] YuvNv21, int width, int height, int[] pixels); public static native boolean RgbaUndistort(int[] argb, int width, int height, int[] pixels); public static native boolean RgbaUndistort2(int[][] rgb, int width, int height, int[] pixels); public static native boolean RgbaUndistortMat(int[] argb, int width, int height, long pArgbOutMatAddr); public static native boolean RgbMatUndistortMat(long pArgbMatAddr, int width, int height, long pArgbOutMatAddr); public static native boolean YuvNv21UndistortRgba(byte[] YuvNv21, int width, int height, int[] pixels); public static native boolean YuvNv21UndistortRgbaMat(byte[] YuvNv21, int width, int height, long pMatAddr); }

进入BIN目录的classes文件夹使用java -classpath . -jni 生成C头文件

根据头文件编写实现的C代码

复制代码
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
#include <stdio.h> #include <jni.h> #include<Android/log.h> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> using namespace std; using namespace cv; #define TAG "Camera XXXXX" // 锟斤拷锟斤拷锟斤拷远锟斤拷锟斤拷LOG锟侥憋拷识 #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG,__VA_ARGS__) // 锟斤拷锟斤拷LOGD锟斤拷锟斤拷 #ifdef __cplusplus extern "C" { #endif /* * Class: ImgProc_ImageProc3 * Method: YuvNv21ToGray * Signature: ([BII[I)Z */ JNIEXPORT jboolean JNICALL Java_ImgProc_ImageProc3_YuvNv21ToGray (JNIEnv *jenv, jclass jclassz, jbyteArray YuvNv21, jint width, jint height, jintArray pixels){ jbyte * pNV21FrameData = jenv->GetByteArrayElements(YuvNv21, 0); jint * poutPixels = jenv->GetIntArrayElements(pixels, 0); Mat mNV(height, width, CV_8UC1, (unsigned char*) pNV21FrameData); Mat mBgra(height, width, CV_8UC4, (unsigned char*) poutPixels); cvtColor(mNV, mBgra, CV_YUV420sp2RGBA); jenv->ReleaseByteArrayElements(YuvNv21, pNV21FrameData, 0); jenv->ReleaseIntArrayElements(pixels, poutPixels, 0); return true; } /* * Class: ImgProc_ImageProc3 * Method: YuvNv21ToRGBA * Signature: ([BII[I)Z */ JNIEXPORT jboolean JNICALL Java_ImgProc_ImageProc3_YuvNv21ToRGBA (JNIEnv *jenv, jclass jclassz, jbyteArray YuvNv21, jint width, jint height, jintArray pixels){ jbyte * pBuf = (jbyte*) jenv->GetByteArrayElements(YuvNv21, 0); jint * poutPixels = jenv->GetIntArrayElements(pixels, 0); Mat image(height + height / 2, width, CV_8UC1, (unsigned char *) pBuf); Mat rgba(height, width, CV_8UC4, (unsigned char*) poutPixels); Mat tmp(height, width, CV_8UC4); cvtColor(image, tmp, CV_YUV420sp2RGBA); vector <Mat> channels; split(tmp, channels); Mat r = channels.at(0); Mat g = channels.at(1); Mat b = channels.at(2); Mat a = channels.at(3); vector <Mat> mbgr(4); mbgr[0] = b; mbgr[1] = g; mbgr[2] = r; mbgr[3] = a; merge(mbgr, rgba); jenv->ReleaseByteArrayElements(YuvNv21, pBuf, 0); jenv->ReleaseIntArrayElements(pixels, poutPixels, 0); return true; } /* * Class: ImgProc_ImageProc3 * Method: RgbaUndistort * Signature: ([III[I)Z */ JNIEXPORT jboolean JNICALL Java_ImgProc_ImageProc3_RgbaUndistort (JNIEnv *jenv, jclass jclassz, jintArray argb, jint width, jint height, jintArray pixels){ jint * poutPixels = jenv->GetIntArrayElements(pixels, 0); jint * pinPixels = jenv->GetIntArrayElements(argb, 0); Mat out(height, width, CV_8UC4, (unsigned char*) poutPixels); Mat in(height, width, CV_8UC4, (unsigned char*) pinPixels); double cam[] = {width, 0, width / 2, 0, height, height / 2, 0, 0, 1 }; double distort[] = { 0.1, 0.35, 0.0, 0.0, 0.01 }; Mat camMat = Mat(3, 3, CV_64FC1, cam); Mat disMat = Mat(5, 1, CV_64FC1, distort); undistort(in, out, camMat, disMat); jenv->ReleaseIntArrayElements(argb, pinPixels, 0); jenv->ReleaseIntArrayElements(pixels, poutPixels, 0); return true; } /* * Class: ImgProc_ImageProc3 * Method: RgbaUndistort2 * Signature: ([[III[I)Z */ JNIEXPORT jboolean JNICALL Java_ImgProc_ImageProc3_RgbaUndistort2(JNIEnv *jenv, jclass jclassz, jobjectArray argb, jint width, jint height, jintArray pixels) { jint i, j; int row = jenv->GetArrayLength(argb); jintArray myarray = (jintArray)(jenv->GetObjectArrayElement(argb, 0)); int col = jenv->GetArrayLength(myarray); jint jniData[row][col]; LOGD("jiaXXX %s", "Java_ImgProc_ImageProc_convertRGB3"); for (i = 0; i < row; i++) { myarray = (jintArray)(jenv->GetObjectArrayElement(argb, i)); jint *coldata = jenv->GetIntArrayElements(myarray, 0); for (j = 0; j < col; j++) { jniData[i][j] = coldata[j]; LOGD("jiaXXX %d", jniData[i][j]); } jenv->ReleaseIntArrayElements(myarray, coldata, 0); } Mat img = Mat(row, col, CV_8UC4, jniData); LOGD("jiaXXX %x", img.at<unsigned int>(1, 1)); double cam[] = {width, 0, width / 2, 0, height, height / 2, 0, 0, 1 }; double distort[] = { 0.1, 0.35, 0.0, 0.0, 0.01 }; Mat camMat = Mat(3, 3, CV_64FC1, cam); Mat disMat = Mat(5, 1, CV_64FC1, distort); jint * poutPixels = jenv->GetIntArrayElements(pixels, 0); Mat out(height, width, CV_8UC4, (unsigned char*) poutPixels); undistort(img, out, camMat, disMat); jenv->ReleaseIntArrayElements(pixels, poutPixels, 0); return true; } /* * Class: ImgProc_ImageProc3 * Method: RgbaUndistortMat * Signature: ([IIIJ)Z */ JNIEXPORT jboolean JNICALL Java_ImgProc_ImageProc3_RgbaUndistortMat (JNIEnv *jenv, jclass jclassz, jintArray argb, jint width, jint height, jlong pArgbOutMatAddr){ //jint * poutPixels = jenv->GetIntArrayElements(pixels, 0); jint * pinPixels = jenv->GetIntArrayElements(argb, 0); //Mat out(height, width, CV_8UC4, (unsigned char*) poutPixels); Mat in(height, width, CV_8UC4, (unsigned char*) pinPixels); Mat out = *((Mat*)pArgbOutMatAddr); double cam[] = {width, 0, width / 2, 0, height, height / 2, 0, 0, 1 }; double distort[] = { 0.1, 0.35, 0.0, 0.0, 0.01 }; Mat camMat = Mat(3, 3, CV_64FC1, cam); Mat disMat = Mat(5, 1, CV_64FC1, distort); undistort(in, out, camMat, disMat); jenv->ReleaseIntArrayElements(argb, pinPixels, 0); //jenv->ReleaseIntArrayElements(pixels, poutPixels, 0); return true; } /* * Class: ImgProc_ImageProc3 * Method: RgbMatUndistortMat * Signature: (JIIJ)Z */ JNIEXPORT jboolean JNICALL Java_ImgProc_ImageProc3_RgbMatUndistortMat (JNIEnv *jenv, jclass jclassz, jlong pArgbMatAddr, jint width, jint height, jlong pArgbOutMatAddr){ Mat in=*((Mat*)pArgbMatAddr); Mat out = *((Mat*)pArgbOutMatAddr); double cam[] = {width, 0, width / 2, 0, height, height / 2, 0, 0, 1 }; double distort[] = { 0.1, 0.35, 0.0, 0.0, 0.01 }; Mat camMat = Mat(3, 3, CV_64FC1, cam); Mat disMat = Mat(5, 1, CV_64FC1, distort); undistort(in, out, camMat, disMat); return true; } /* * Class: ImgProc_ImageProc3 * Method: YuvNv21UndistortRgba * Signature: ([BII[I)Z */ JNIEXPORT jboolean JNICALL Java_ImgProc_ImageProc3_YuvNv21UndistortRgba (JNIEnv *jenv, jclass jclassz, jbyteArray YuvNv21, jint width, jint height, jintArray pixels){ jbyte * pBuf = (jbyte*) jenv->GetByteArrayElements(YuvNv21, 0); jint * poutPixels = jenv->GetIntArrayElements(pixels, 0); Mat image(height + height / 2, width, CV_8UC1, (unsigned char *) pBuf); Mat rgba(height, width, CV_8UC4, (unsigned char*) poutPixels); Mat tmp(height, width, CV_8UC4); cvtColor(image, tmp, CV_YUV420sp2RGBA); double cam[] = { width, 0, width / 2, 0, height, height / 2, 0, 0, 1 }; double distort[] = { 0.1, 0.35, 0.0, 0.0, 0.01 }; Mat camMat = Mat(3, 3, CV_64FC1, cam); Mat disMat = Mat(5, 1, CV_64FC1, distort); undistort(tmp, tmp, camMat, disMat); vector < Mat > channels; split(tmp, channels); Mat r = channels.at(0); Mat g = channels.at(1); Mat b = channels.at(2); Mat a = channels.at(3); vector < Mat > mbgr(4); mbgr[0] = b; mbgr[1] = g; mbgr[2] = r; mbgr[3] = a; merge(mbgr, rgba); jenv->ReleaseByteArrayElements(YuvNv21, pBuf, 0); jenv->ReleaseIntArrayElements(pixels, poutPixels, 0); return true; } /* * Class: ImgProc_ImageProc3 * Method: YuvNv21UndistortRgbaMat * Signature: ([BIIJ)Z */ JNIEXPORT jboolean JNICALL Java_ImgProc_ImageProc3_YuvNv21UndistortRgbaMat (JNIEnv *jenv, jclass jclassz, jbyteArray YuvNv21, jint width, jint height, jlong pMatAddr){ jbyte * pBuf = (jbyte*) jenv->GetByteArrayElements(YuvNv21, 0); //jint * poutPixels = jenv->GetIntArrayElements(pixels, 0); Mat image(height + height / 2, width, CV_8UC1, (unsigned char *) pBuf); //Mat rgba(height, width, CV_8UC4, (unsigned char*) poutPixels); Mat rgba = *((Mat*) pMatAddr); Mat tmp(height, width, CV_8UC4); cvtColor(image, tmp, CV_YUV420sp2RGBA); double cam[] = { width, 0, width / 2, 0, height, height / 2, 0, 0, 1 }; double distort[] = { 0.1, 0.35, 0.0, 0.0, 0.01 }; Mat camMat = Mat(3, 3, CV_64FC1, cam); Mat disMat = Mat(5, 1, CV_64FC1, distort); undistort(tmp, tmp, camMat, disMat); vector < Mat > channels; split(tmp, channels); Mat r = channels.at(0); Mat g = channels.at(1); Mat b = channels.at(2); Mat a = channels.at(3); vector < Mat > mbgr(4); mbgr[0] = b; mbgr[1] = g; mbgr[2] = r; mbgr[3] = a; merge(mbgr, rgba); jenv->ReleaseByteArrayElements(YuvNv21, pBuf, 0); //jenv->ReleaseIntArrayElements(pixels, poutPixels, 0); return true; } #ifdef __cplusplus } #endif

以上这篇利用OPENCV为android开发畸变校正的JNI库方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持靠谱客。

最后

以上就是沉默诺言最近收集整理的关于利用OPENCV为android开发畸变校正的JNI库方法的全部内容,更多相关利用OPENCV为android开发畸变校正内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(201)

评论列表共有 0 条评论

立即
投稿
返回
顶部