openCV人脸识别,yuv420sp格式转BGR传入Mat矩阵

        继续安卓人脸识别,为了达到更好的效果,代码需要不断优化。

        前两篇分别实现了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;

}


 

猜你喜欢

转载自blog.csdn.net/u013547134/article/details/41009603