利用OPENCV為android開發(fā)畸變校正的JNI庫方法
需要為項目提供一套畸變校正的算法,由于需要大量的矩陣運算,考慮到效率和適時性,使用JNI開發(fā),希望把有關(guān)數(shù)組短陣的處理的變換全部放入C語言中處理。
主要用于android移動端,大致的數(shù)據(jù)來源一是從camera直接讀取YUV數(shù)據(jù),一種是從第三方接讀取RGB數(shù)據(jù),另一種是直接對BITMAP進行處理。
1.考慮到硬件設(shè)備接口,第三方軟件接口,圖像接口,OPENCV接口,希望能夠開發(fā)出通用的算法庫,一勞永逸的解決各種復(fù)雜的使用場景,因此數(shù)據(jù)要支持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);
因此設(shè)計如下接口,入口為ARGB的整型,輸出也是整型
public static native boolean RgbaUndistort(int[] argb, int width, int height, int[] pixels);
3考慮到有些情況需要二維數(shù)組,
public static native boolean RgbaUndistort2(int[][] rgb, int width, int height, int[] pixels);
4考慮到OPENCV的MAT結(jié)構(gòu),由于MAT有matToBitmap可以直接轉(zhuǎn)化為BITMAP,應(yīng)用MAT 提供
public static native boolean RgbaUndistortMat(int[] argb, int width, int height, long pArgbOutMatAddr);
5考慮到第三方使用MAT的情況,因此輸入也可以支持MAT因此設(shè)計接口
public static native boolean RgbMatUndistortMat(long pArgbMatAddr, int width, int height, long pArgbOutMatAddr);
6考慮到攝像頭輸出YUV,提供YUV數(shù)據(jù)處理, 一個輸出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設(shè)計一個灰度,一個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頭文件
根據(jù)頭文件編寫實現(xiàn)的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開發(fā)畸變校正的JNI庫方法就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
- Android OpenCv4 繪制多邊形的方法
- Android+OpenCv4實現(xiàn)邊緣檢測及輪廓繪制出圖像最大邊緣
- 如何在Android上使用opencv
- Android Studio4.0導(dǎo)入OpenCv4.3.0的方法步驟
- 使用Android Studio創(chuàng)建OpenCV4.1.0 項目的步驟
- Android+OpenCV4.2.0環(huán)境配置詳解(Android studio)
- OpenCV在Android上的應(yīng)用示例
- Android 通過cmake的方式接入opencv的方法步驟
- Android通過Java sdk的方式接入OpenCv的方法
- android端使用openCV實現(xiàn)車牌檢測
- Android 中使用 dlib+opencv 實現(xiàn)動態(tài)人臉檢測功能
- Android基于OpenCV實現(xiàn)圖像修復(fù)
相關(guān)文章
Android LinearLayout實現(xiàn)自動換行
這篇文章主要為大家詳細介紹了Android LinearLayout實現(xiàn)自動換行,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-08-08Android使用ViewFlipper實現(xiàn)圖片切換功能
這篇文章主要為大家詳細介紹了Android使用ViewFlipper實現(xiàn)圖片切換功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07Android開發(fā) 旋轉(zhuǎn)屏幕導(dǎo)致Activity重建解決方法
Android開發(fā)文檔上專門有一小節(jié)解釋這個問題。簡單來說,Activity是負責(zé)與用戶交互的最主要機制,接下來為您詳細介紹2012-11-11Android實現(xiàn)下拉刷新的視圖和圖標(biāo)的旋轉(zhuǎn)
本篇文章主要介紹了Android實現(xiàn)下拉刷新的視圖和圖標(biāo)的旋轉(zhuǎn)的實例,具有很好的參考價值。下面跟著小編一起來看下吧2017-03-03