相机获取图像的格式问题

android中承认的格式的参考网址为 :http://developer.android.com/reference/android/graphics/ImageFormat.html);

并不是所有的android摄像机都支持这种格式,其中最为常用(android系统默认)的格式为:NV21格式;(所有相机都支持)。但是往往我们需要将这种格式转化为其它的类型,以便于进行相关处理,最常见的就是rgb和jpeg类型,还有android中的BitMap 格式的图像类型。NV21格式其实是一种YUV格式,相关格式的说明可参考网络资料~,下面帖一下相关算法:

public void decodeToBitMap(byte[] data, Camera _camera) {
Size size = mCamera.getParameters().getPreviewSize();
try {
YuvImage image = new YuvImage(data, ImageFormat.NV21, size.width,
size.height, null);
if (image != null) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
image.compressToJpeg(new Rect(0, 0, size.width, size.height),
80, stream);
Bitmap bmp = BitmapFactory.decodeByteArray(
stream.toByteArray(), 0, stream.size());
stream.close();
}
} catch (Exception ex) {
Log.e("Sys", "Error:" + ex.getMessage());
}
}

注意:该算法只适用于android2.2以后的版本~

——————————————————————————————————————

 

 

另外帖出一篇网文,仅供参考者图像格式详解网址:http://ticktick.blog.51cto.com/823160/555791

算法网址:http://www.cnblogs.com/lyout/archive/2012/03/16/2400370.html

本次摘录网址 :

上次讲的是摄像头的初始化,如果觉得这么就万事OK的话,那就大错特错了。接下来的东西让人感到更加头痛。

在我的这个应用里,不需要把拍下来的图片存储,只需要把预览的图片数据处理一下就好,很自然的我只是用了onPreviewFrame 

调用,考虑处理传递进来的data数据流就是了。

网上很多帖子都说,然后用BitmapFactory的decodeByteArray()函数来解析图片就行了,我试了一下,发现这真是彻头彻尾 的谎 

言,data字节流默认是YCbCr_420_SP(虽然可以改,但其他的格式未必兼容),decodeByteArray()压根儿不 认!SDK2.2之后, 

似乎提供了一个YuvImage的类来转一下(那Google一开始提供这个借口是做什么的?),难道就要把老机给抛弃了么??万 万不 

能啊(穷人最理解穷人们了)!

好在这个世界总是不缺少好人和牛人的,有人提供了这么一段转换的代码:

上次讲的是摄像头的初始化,如果觉得这么就万事OK的话,那就大错特错了。接下来的东西让人感到更加头痛。

在我的这个应用里,不需要把拍下来的图片存储,只需要把预览的图片数据处理一下就好,很自然的我只是用了onPreviewFrame 

调用,考虑处理传递进来的data数据流就是了。

网上很多帖子都说,然后用BitmapFactory的decodeByteArray()函数来解析图片就行了,我试了一下,发现这真是彻头彻尾 的谎 

言,data字节流默认是YCbCr_420_SP(虽然可以改,但其他的格式未必兼容),decodeByteArray()压根儿不 认!SDK2.2之后, 

似乎提供了一个YuvImage的类来转一下(那Google一开始提供这个借口是做什么的?),难道就要把老机给抛弃了么??万 万不 

能啊(穷人最理解穷人们了)!

好在这个世界总是不缺少好人和牛人的,有人提供了这么一段转换的代码:

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);
}
}
}

我不是很清楚这里面的原理,但是它能在我这里工作,暂时可以了……然后你才可以吧处理完的rgb[]传给decodeByteArray()。

顺便好心的把使用SDK2.2之后的也贴上吧,万一有用呢……

public void onPreviewFrame(byte[] data, Camera arg1) {
FileOutputStream outStream = null;
try {
YuvImage yuvimage = new YuvImage(data,ImageFormat.NV21,arg1.getParameters().getPreviewSize
().width,arg1.getParameters().getPreviewSize().height,null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
yuvimage.compressToJpeg(new Rect(0,0,arg1.getParameters().getPreviewSize().width,arg1.getParameters
().getPreviewSize().height), 80, baos); outStream = new FileOutputStream(String.format("/sdcard/%d.jpg", System.currentTimeMillis()));
outStream.write(baos.toByteArray());
outStream.close(); Log.d(TAG, "onPreviewFrame - wrote bytes: " + data.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
Preview.this.invalidate();
}

哦,得到的图像旋转了90°(似乎有的机型设置一下setRotation(90)可以搞定,但还是那句话,不通用啊,况且这个是2.1之后 的API)。手动转一下吧……

——————注:经本人验证,并没有出现旋转90°的问题。。。

Matrix matrix = new Matrix();

matrix.postRotate(90);

// 这里的rgb就是刚刚转换处理的东东

Bitmap bmp = Bitmap.createBitmap(rgb, 0, w, w, h, Bitmap.Config.ARGB_4444);

Bitmap nbmp = Bitmap.createBitmap(bmp,

0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true);

终于正常了~~~

考虑到需要做识别,自然得先把它转成灰度图像,经典心理公式Gray = R*0.299 + G*0.587 + B*0.114出场了,但是手机的计算 

速度不那么快,这样的浮点运算还是尽量避免吧~ 于是考虑Gray = (R*299 + G*587 + B*114 + 500) / 1000或者Gray = (R*30 + 

G*59 + B*11 + 50) /

android摄像头获取图像——第三弹的更多相关文章

  1. android摄像头获取图像——第二弹

    使用android内的Camera对象 (1)Camera是控制着摄像头的api,拥有一系列控制摄像头的上层方法:camera类能够调用底层的摄像头接口,完成启动摄像头.预 览摄像头图像.拍照等功能: ...

  2. android摄像头获取图像——第一弹

    http://www.cnblogs.com/mengyan/archive/2012/09/01/2666636.html 安卓读取视频的几种方式: 详细讲述请参考网址:http://www.cnb ...

  3. Android Camera2 拍照(三)——切换摄像头,延时拍摄和闪光模式

    原文:Android Camera2 拍照(三)--切换摄像头,延时拍摄和闪光模式 一.切换摄像头 在前后摄像头之间切换,首先需要关闭之前打开的摄像头,关闭preview,之后重新打开新的摄像头,重新 ...

  4. ROS 教程之 vision : 用各种摄像头获取图像

    可能有很多人想在ROS下学习视觉,先用摄像头获取图像,再用opencv做相应算法处理,可是ROS下图像的采集可不像平常的read一下那么简单,需要借助外部package的使用.而摄像头即可以用笔记本自 ...

  5. 如何使用 OpenCV 打开摄像头获取图像数据?

    OpenCV 如何打开摄像头获取图像数据? 代码运行环境:Qt 5.9.1 msvc2015 32bit OpenCV 3.3.0 #include "include/opencv2/ope ...

  6. Android内存优化(三)详解内存分析工具MAT

    前言 在这个系列的前四篇文章中,我分别介绍了DVM.ART.内存泄漏和内存检测工具的相关知识点,这一篇我们通过一个小例子,来学习如何使用内存分析工具MAT. 1.概述 在进行内存分析时,我们可以使用M ...

  7. Android测试基础题(三)

    今天接着给大家带来的是Android测试基础题(三).    需求:定义一个排序的方法,根据用户传入的double类型数组进行排序,并返回排序后的数组 俗话说的好:温故而知新,可以为师矣 packag ...

  8. Android APP压力测试(三)之Monkey日志自动分析脚本

    Android APP压力测试(三) 之Monkey日志自动分析脚本 前言 上次说要分享Monkey日志的分析脚本,这次贴出来分享一下,废话不多说,请看正文. [目录] 1.Monkey日志分析脚本 ...

  9. 前端学习 第三弹: JavaScript语言的特性与发展

    前端学习 第三弹: JavaScript语言的特性与发展 javascript的缺点 1.没有命名空间,没有多文件的规范,同名函数相互覆盖 导致js的模块化很差 2.标准库很小 3.null和unde ...

随机推荐

  1. 用 ERD 盘解决 Win8 自己主动更新后不能启动的问题

    用 ERD 盘解决 Win8 自己主动更新后不能启动的问题 有安装了 Win8 x64 系统的台式机,在自己主动更新后无法启动了.在黑屏的情况下.没有反应了. 安全模式也无法进入系统. 几经周折,发现 ...

  2. 怎么样获得泛型T的Class对象?

    public class GenClass<T> { private Class<T> entityClass; } public class Test { public st ...

  3. 获取iOS系统版本号,慎重使用[[[UIDevice currentDevice] systemVersion] floatValue]——【sdk缺陷】

    iOS 最常见的获取系统版本的方法是: [[[UIDevice currentDevice] systemVersion] floatValue] 可是.这个floatValue是不靠谱的,这也算是i ...

  4. 2014年辛星解读css第五节

    本小节我们解说css中的"盒模型".即"box model",它通经常使用于在布局的时候使用,这个"盒模型"也有人成为"框模型&q ...

  5. EasyDarwin EasyCamera支持海康摄像机接入了

    本文转自EasyDarwin开源团队成员Alex的博客:http://blog.csdn.net/cai6811376/article/details/52709816 EasyCamera默认使用海 ...

  6. 九度OJ 1130:日志排序 (排序)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1265 解决:303 题目描述: 有一个网络日志,记录了网络中计算任务的执行情况,每个计算任务对应一条如下形式的日志记录: "hs ...

  7. Android笔记之平移View

    方法有多种,只讲一种 使用View.setLeft和View.setRight 对于wrap_content的View,要横向平移,setRight是必要的,否则View的宽度会被改变(right应设 ...

  8. Java版TicTacToe

    MainFrame.java package com.bu_ish; import java.awt.BorderLayout; import java.awt.Color; import java. ...

  9. Jquery跨域调用

    今天在项目中须要做远程数据载入并渲染页面,直到开发阶段才意识到ajax跨域请求的问题,隐约记得Jquery有提过一个ajax跨域请求的解决方式,于是即刻翻出Jquery的API出来研究,发现JQuer ...

  10. 【C++基础学习】引用和指针、重载、函数、内存管理

    第一部分:引用VS指针 引用的含义:变量的别名 注意:变量不能只有别名,必须有一个真实的变量与之相对应 基本数据类型的引用 对别名本身的操作和它的实体的操作是一样的 1.基本数据类型的引用 类型 &a ...