openCV的C++底层库用在android里面open()不了,遂换了种方式。用原生Camera的视频流封装成Mat再进行操作。
转发自:https://blog.csdn.net/Taily_Duan/article/details/52756166 我只能说是真的牛逼
这个单通道的,代码是jni的:
jbyte * pBuf = (jbyte*)env->GetByteArrayElements(yuv, 0);
int width = w;
int height = h + h / 2;
Mat imageSrc(height, width , CV_8UC1, (unsigned char*)pBuf );
Mat image;
cvtColor(imageSrc, image, CV_YUV2BGR_NV21);
Mat timage;
transpose(image, timage);
Mat ximage;
Mat yimage;
flip(timage, ximage, 0);
flip(ximage, yimage, 1);
Android的Bitmap图像格式转为BGRA,转为三通道的:
public void onPreviewFrame(byte[] data, Camera camera) {
if (data != null) {
int imageWidth = mCamera.getParameters().getPreviewSize().width;
int imageHeight = mCamera.getParameters().getPreviewSize().height;
int RGBData[] = new int[imageWidth * imageHeight];
decodeYUV420SP(RGBData, data, imageWidth, imageHeight);// 解码,yuv420sp转为RGB格式
Bitmap bm = Bitmap.createBitmap(RGBData, imageWidth,imageHeight, Config.ARGB_8888);//填到bitmap中
byte[] bgra = getPixelsBGRA(bm);//把bitmap中的ARGB_8888格式转为Mat矩阵中可用的BGRA格式数据bgra
}
}
public byte[] getPixelsBGRA(Bitmap image) {
// calculate how many bytes our image consists of
int bytes = image.getByteCount();
ByteBuffer buffer = ByteBuffer.allocate(bytes); // Create a new buffer
image.copyPixelsToBuffer(buffer); // Move the byte data to the buffer
byte[] temp = buffer.array(); // Get the underlying array containing the data.
byte[] pixels = new byte[temp.length]; // Allocate for BGRA
// Copy pixels into place
for (int i = 0; i < (temp.length / 4); i++) {
pixels[i * 4] = temp[i * 4 + 2]; //B
pixels[i * 4 + 1] = temp[i * 4 + 1];<span style="white-space:pre"> </span>//G
pixels[i * 4 + 2] = temp[i * 4 ]; //R
pixels[i * 4 + 3] = temp[i * 4 + 3]; //A
}
return pixels;
}
static public void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width,
int height) {
final int frameSize = width * height;
for (int j = 0, yp = 0; j < height; j++) {
int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
for (int i = 0; i < width; i++, yp++) {
int y = (0xff & ((int) yuv420sp[yp])) - 16;
if (y < 0)
y = 0;
if ((i & 1) == 0) {
v = (0xff & yuv420sp[uvp++]) - 128;
u = (0xff & yuv420sp[uvp++]) - 128;
}
int y1192 = 1192 * y;
int r = (y1192 + 1634 * v);
int g = (y1192 - 833 * v - 400 * u);
int b = (y1192 + 2066 * u);
if (r < 0)
r = 0;
else if (r > 262143)
r = 262143;
if (g < 0)
g = 0;
else if (g > 262143)
g = 262143;
if (b < 0)
b = 0;
else if (b > 262143)
b = 262143;
rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000)
| ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
}
}
}