您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關如何利用OPENCV為android開發畸變校正的JNI庫,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
需要為項目提供一套畸變校正的算法,由于需要大量的矩陣運算,考慮到效率和適時性,使用JNI開發,希望把有關數組短陣的處理的變換全部放入C語言中處理。
主要用于android移動端,大致的數據來源一是從camera直接讀取YUV數據,一種是從第三方接讀取RGB數據,另一種是直接對BITMAP進行處理。
1.考慮到硬件設備接口,第三方軟件接口,圖像接口,OPENCV接口,希望能夠開發出通用的算法庫,一勞永逸的解決各種復雜的使用場景,因此數據要支持YUV,支持ARGB,支持MAT
2android對BITMAP有獲取像素點的操作,也有通過象素點生成BITMAP的操作,而且有很多圖像處理接口和第三方可以處理RGB矩陣,如
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的整型,輸出也是整型
public static native boolean RgbaUndistort(int[] argb, int width, int height, int[] pixels);
3考慮到有些情況需要二維數組,
public static native boolean RgbaUndistort2(int[][] rgb, int width, int height, int[] pixels);
4考慮到OPENCV的MAT結構,由于MAT有matToBitmap可以直接轉化為BITMAP,應用MAT 提供
public static native boolean RgbaUndistortMat(int[] argb, int width, int height, long pArgbOutMatAddr);
5考慮到第三方使用MAT的情況,因此輸入也可以支持MAT因此設計接口
public static native boolean RgbMatUndistortMat(long pArgbMatAddr, int width, int height, long pArgbOutMatAddr);
6考慮到攝像頭輸出YUV,提供YUV數據處理, 一個輸出RGB, 一個輸出MAT
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接口
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頭源生類
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代碼
#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庫”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。