概述
继续安卓人脸识别,为了达到更好的效果,代码需要不断优化。
前两篇分别实现了jpg格式和bitmap格式的图片数据传入Mat矩阵中,省去了把图片数据保存成图片文件再用imread读取的过程,提高了程序运行效率。但是安卓摄像头采集的图像数据是yuv420sp(NV21)格式的,需要转换成jpg或bitmap格式的数据传到jni中,传给Mat矩阵。
看opencv源码的时候,偶然发现直接可以用yuv420sp转化成BGR格式。这样又可以减少在上层转换格式的过程。代码如下:
//YUV420SP转BGR
JNIEXPORT int JNICALL Java_com_facedetect_nativecaller_FaceNative_readYUV420SP(JNIEnv *env, jclass clz, jbyteArray yuv,jint len,jint height,jint width)
{
jbyte * pBuf = (jbyte*)env->GetByteArrayElements(yuv, 0);
Mat image(height + height/2,width,CV_8UC1,(unsigned char *)pBuf);
Mat mBgr;
cvtColor(image, mBgr, CV_YUV2BGR_NV21);
imwrite("/mnt/sdcard/readYuv.jpg",mBgr);
env->ReleaseByteArrayElements(yuv, pBuf, 0);
return 0;
}
//上篇中,Bitmap转BGR
JNIEXPORT int JNICALL Java_com_facedetect_nativecaller_FaceNative_readBitmap(JNIEnv *env, jclass clz, jobject bitmapcolor,jint len,jint height,jint width)
{
AndroidBitmapInfo infocolor;
void* pixelscolor;
int ret;
if ((ret = AndroidBitmap_getInfo(env, bitmapcolor, &infocolor)) < 0) {
LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
return -1;
}
LOGI("color image :: width is %d; height is %d; stride is %d; format is %d;flags is %d",
infocolor.width,infocolor.height,infocolor.stride,infocolor.format,infocolor.flags);
if (infocolor.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
LOGE("Bitmap format is not RGBA_8888 !");
return -1;
}
if ((ret = AndroidBitmap_lockPixels(env, bitmapcolor, &pixelscolor)) < 0) {
LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
}
Mat image(infocolor.height,infocolor.width,CV_8UC4,(char*)pixelscolor);
Mat bgr;
//转换成BGR
cvtColor(image,bgr,CV_RGBA2BGR);
imwrite("/mnt/sdcard/readBitmap.jpg",bgr);
//转换成GRAY
// cvtColor(bgr,gray,CV_BGR2GRAY);
// imwrite("/mnt/sdcard/gray.jpg",gray);
AndroidBitmap_unlockPixels(env, bitmapcolor);
return 0;
}
最后
以上就是彩色康乃馨为你收集整理的openCV人脸识别,yuv420sp格式转BGR传入Mat矩阵的全部内容,希望文章能够帮你解决openCV人脸识别,yuv420sp格式转BGR传入Mat矩阵所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复