版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Android = 人+计算 普适环境,授课教师:李治军,lizhijun_ 综合楼417室,第4章 视觉感知与Android实践,Chapter 4: Vision Sensing camera = Camera.open(); . camera.takePicture(shutterCallback,null,jpegCallback); . camera.release();/释放资源 camera = null;,Android图像采集的细节,关键:camera.takePicture,核心是三个参数,第一个参数:在图像被捕获时回调,通常通过音效表明拍摄成功,第二个参数:图像捕获时被调
2、用,图片的原始数据通过byte传入回调方法,可忽略,第三个参数:生成JPEG格式图片数据时被调用,JPEG数据通过byte传入回调方法,camera.takePicture(shutterCallback,null,jpegCallback); private ShutterCallback shutterCallback = new ShutterCallback(). private PictureCallback jpegCallback = new PictureCallback().,Android图像采集的细节,第一个回调:shutterCallback,private Shutt
3、erCallback shutterCallback = new ShutterCallback() public void onShutter() if(tone = null) /发出提示用户的声音 tone=new ToneGenerator(AudioManager.STREAM_MUSIC, ToneGenerator.MAX_VOLUME); tone.startTone(ToneGenerator.TONE_PROP_BEEP2); ;,快门按下的时候onShutter()被回调,private ToneGenerator tone;,Android让手机应用开发变得很容易,An
4、droid已经封装好ToneGenerator产生铃声,Android图像采集的细节,第二个回调:rawCallback,private PictureCallback rawCallback = new PictureCallback() public void onPictureTaken(byte data, Camera cam) String path = save(data); ;,得到图像数据时调用,private String save(byte data) String path = /sdcard/+System.currentTimeMillis()+.raw; File
5、 file = new File(path); if(!file.exists() file.createNewFile(); FileOutputStream fos = new FileOutputStream(file); fos.write(data); fos.close();,Android图像采集的细节,第三个回调:jpegCallback,private PictureCallback jpegCallback = new PictureCallback() public void onPictureTaken(byte data, Camera camera) String
6、path = save(data); ;,保存成xx.jpg文件,没有经过压缩,一个标准,压缩率极高,Android图像采集的细节,现在运行不好使!,class CameraPreview extends SurfaceView SurfaceHolder mHolder; public CameraPreview(Context context) super(context); mHolder = getHolder(); public void surfaceCreated(SurfaceHolder holder) camera = Camera.open(); try camera.s
7、etPreviewDisplay(holder); public void surfaceChanged(.) camera.setParameters(parameters); camera.startPreview(); ,Takepicture以preview为基础,Android图像采集的细节,类CameraPreview的使用!,public class CameraActivity extends Activity private CameraPreview preview; private Camera camera; public void onCreate(Bundle sa
8、vedInstanceState) preview = new CameraPreview(this); setContentView(preview); ,需要定义拍照按钮!,public boolean onCreateOptionsMenu(Menu menu) menu.add(0, OPTION_SNAPSHOT, 0, R.string.snapshot); return super.onCreateOptionsMenu(menu);,增加系统菜单项,Android运行实例,照一个图片试一试(捕获菜单选择),public boolean onOptionsItemSelected
9、(MenuItem item) switch(item.getItemId() case OPTION_SNAPSHOT: camera.takePicture(shutterCallback, rawCallback, jpegCallback);,在真机上试一试,当然别忘了把权限打开,FF是JPEG文件的标记,D8是图像开始,C4:霍夫曼表;C0:帧开始;DA扫描线开始,Android图像采集中的Raw data,Raw data对后续图像处理及Vision很重要,takePicture中的rawCallback返回的data总是空的,takePicture实际上是将preview 中捕获
10、的某个image保存下来,要想在Android上获取图像的Raw data?,需对Android的深层进行学习!,Android Media Framework,Android的Media Framework,Android中的Camera,Android中Camera工作的具体过程(1),这个故事需要从内核说起:Video4linux2(简称V4L2),是linux中关于视频设备的内核驱动,从Libraries向上的一大堆东西只是应用程序而已,什么东西接通了应用和内核?,Java Application最终依靠什么获取Camera数据?,只能是Linux向上层提供的系统调用,int fd=o
11、pen(“/dev/video0”,O_RDWR);,Android中Camera工作的具体过程(2),Open Camera对应的文件以后会,int fd=open(“/dev/video0”,O_RDWR); struct v4l2_format fmt; fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; ioctl (fd, VIDIOC_STREAMON, /开始捕捉图像数据,V4L2_PIX_FMT_YUYV就是YUV4:2:2,两个像素4个字节:每个点有8bit 的亮度值(Y),每2 个点有一个色差(Cr和Cb),Android中Camera
12、工作的具体过程(3),YUV与RGB,YUV4:2:2的工作原理,四个像素:Y0 U0 V0 Y1 U1 V1 Y2 U2 V2 Y3 U3 V3,存放的码流为:Y0 U0 Y1 V1 Y2 U2 Y3 V3,映射出:Y0 U0 V1 Y1 U0 V1 Y2 U2 V3 Y3 U2 V3,从YUV解出RGB,R = Y + 1.14VG = Y - 0.39U - 0.58VB = Y + 2.03U,这说明从底层读出来的Camera数据是Raw Data,Android中Camera工作的具体过程(4),在哪里将这些YUV数据变成了JPEG,并将这些Raw Data撇去了?,需要读源代码,只
13、能在这里,这个显然在library层,是依靠JNI进入的native部分,Android对Camera的具体调用过程(5),UI,Android.hardware.camera,Applications,Java call,Frameworks,Libraries,Kernel,Camera Driver,libandroid_runtime.so,libcameraservice.so,libui.so,client,service,JNI,Binder IPC,libcamera.so,Android的Java层只是一个外壳,packages,frameworks,Android中Came
14、ra工作的具体过程(6),开始分析Camera的源代码,这部分属于Camera HAL层,由下面目录中的源代码编译而成,libcamera.so,hardware/msm7k/libcamera,每个目录下有个Android.mk文件,Makefile,LOCAL_SRC_FILES:= QualcommCameraHardware.cpp LOCAL_SHARED_LIBRARIES:= libutils libbinder libui liblog libcamera_client LOCAL_MODULE:= libcamera,Qualcomm是美国高通公司,Android中Camer
15、a工作的具体过程(7),来看看这个QualcommCameraHardware.cpp,这条线从哪里开始呢?,takepicture函数,QualcommCameraHardware:takePicture(shutter_callback shutter_cb, raw_callback raw_cb,.) mRawPictureCallback = raw_cb; mJpegPictureCallback = jpeg_cb; LINK_camera_take_picture(camera_cb, this); ,这些函数是回调函数,所以只是告诉下层,需要上下一起分析,从App开始,imp
16、ort android.hardware.Camera;,frameworks/base/core/java/android/hardware/Camera.java,Android中Camera工作的具体过程(8),看看那个Camera.java,frameworks/base/core/java/android/hardware/Camera.java,public final void takePicture(ShutterCallback shutter, PictureCallback raw,., PictureCallback jpeg) mShutterCallback = s
17、hutter; mRawImageCallback = raw; mJpegCallback = jpeg; native_takePicture(); ,private native final void native_takePicture();,显然要进入JNI,frameworks/base/core/jni/android_hardware_Camera.cpp,编译成libandroid_runtime.so,Android中Camera工作的具体过程(9),看看JNI:android_hardware_Camera.cpp,三个回调函数并没有往下传,android_hardwar
18、e_Camera_takePicture(JNIEnv *env,) sp camera = get_native_camera(env,); camera-takePicture() ;,private class EventHandler extends Handler public void handleMessage(Message msg) switch(msg.what) case CAMERA_MSG_RAW_IMAGE: if (mRawImageCallback != null) mRawImageCallback.onPictureTaken(byte)msg.obj,);
19、 case CAMERA_MSG_COMPRESSED_IMAGE: if (mJpegCallback != null).,再看看Camera.java,native_takePicture的JNI,依靠消息进行触发,Android中Camera工作的具体过程(10),Camera-takePicture(),到了libui.so (更准确的说是libcamera_client),frameworks/base/libs/ui/编译,主要是Camera.cpp,status_t Camera:takePicture() sp c = mCamera; return c-takePicture
20、(); ,应该是ICamera.cpp,mCamera成员变量在哪里初始化?,sp Camera:connect() sp c = new Camera(); sp,Camera.open() 时调用,Android中Camera工作的具体过程(11),Camera:getCameraService,获得Camera的服务器端,sp,mCamera是从cs-connect那里得到的ICamera指针,status_t takePicture() remote()-transact(TAKE_PICTURE, .);,这就是Binder了,Android中Camera工作的具体过程(12),Ca
21、mera运行时分成Client和Server两部分,分别在两个进程中运行,靠Binder进行通信,Binder IPC对上层透明,Android中Camera工作的具体过程(13),明白Binder的运作机理,(1)服务的注册,(5)BnABC的实现,实现onTransact(),(2)客户端获得接口ABC,(3)客户端调用接口ABC (BpABC),(4)BpABC实现代理功能,依靠BpABC: remote()-transact(),Android中Camera工作的具体过程(14),remote()-transact(TAKE_PICTURE, ),remote在ICamera.cpp中
22、BpCamera类中,class BpCamera: public BpInterface class BpInterface: public INTERFACE, public BpRefBase,在class BpRefBase中: inline IBinder* remote() return mRemote;,和CameraService Connect以后这个IBinder就打通了IPC通道,而transact就是利用/dev/binder进行消息传递了,c-mCamera = cs-connect(c);,Android中Camera工作的具体过程(15),现在的问题是谁接受了这个
23、TAKE_PICTURE消息,并且要干什么?,谁注册了media.camera服务?,void CameraService:instantiate() defaultServiceManager()-addService( String16(media.camera), new CameraService();,class CameraService : public BnCameraService class Client : public BnCamera . wp mClient; ,sp CameraService:connect(.) return mClient;,mCamera是
24、这个Client,Android中Camera工作的具体过程(16),到底谁接受了TAKE_PICTURE,要干什么?,是继承自BnCamera这个Client类,status_t BnCamera:onTransact(uint32_t code,.) case TAKE_PICTURE: reply-writeInt32(takePicture();,处理动作就是调用Client类中的takePicture函数,status_t CameraService:Client:takePicture() mHardware-enableMsgType(CAMERA_MSG_SHUTTER | C
25、AMERA_MSG_POSTVIEW_FRAME | CAMERA_MSG_RAW_IMAGE | CAMERA_MSG_COMPRESSED_IMAGE); return mHardware-takePicture();,Android中Camera工作的具体过程(17),mHardware从哪里来?,应该是在初始化时产生!,status_t CameraService:Client:Client(.) mHardware = openCameraHardware();,sp openCameraHardware() return CameraHardwareStub:createInsta
26、nce();,sp openCameraHardware() return QualcommCameraHardware:createInstance();,要打开Camera的硬件了! 但有两个open,一个是Stub,一个是Qualcomm,Android中Camera工作的具体过程(18),CameraHardwareStub如其名,是stub(存根类),运行在本地的Java程序调用运行在远程对象的方法时,首先在本地创建该对象的代理对象stub,CameraHardwareStub类的takePicture,status_t CameraHardwareStub:takePicture(
27、) stopPreview(); createThread(beginPictureThread, this);,启动线程完成相应工作,status_t CameraHardwareStub:stopPreview() mPreviewThread-requestExitAndWait();,先停止另一个线程! 猜猜这个线程干什么?,是Preview线程!,Android中Camera工作的具体过程(19),createThread(beginPictureThread, ,显然就是创建一个线程,执行函数begin,最后是通过pthread_create创建的线程,CameraHardware
28、Stub *c = cookie; return c-pictureThread();,int CameraHardwareStub:pictureThread() if (mMsgEnabled ,mem里面的内容应该就是核心了,Android中Camera工作的具体过程(20),看看CAMERA_MSG_COMPRESSED_IMAGE,heap = new MemoryHeapBase(kCannedJpegSize); mem = new MemoryBase(heap, 0, kCannedJpegSize); memcpy(heap-base(),kCannedJpeg,kCann
29、edJpegSize);,显然jpeg数据就保存在了kCannedJpeg里,int CameraHardwareStub:previewThread() FakeCamera* fakeCamera = mFakeCamera; fakeCamera-getNextFrameAsYuv422(frame);,kCannedJpeg是一个初始化好的文件!,再看一下Preview,这条路是假的Camera,模拟器中的,Android中Camera工作的具体过程(21),QualcommCameraHardware:createInstance,这个才是真的Camera硬件,回到了故事的一开始,*
30、cam = new QualcommCameraHardware(); cam-initDefaultParameters(); return hardware(cam);,回到QualcommCameraHardware:takePicture,QualcommCameraHardware:takePicture(shutter_callback shutter_cb, raw_callback raw_cb,.) mRawPictureCallback = raw_cb; LINK_camera_take_picture(camera_cb, this); ,这些参数不知道从哪里来?,An
31、droid中Camera工作的具体过程(22),LINK_camera_take_picture(camera_cb,应该是让硬件工作了,*(void *),libqcamera = :dlopen(liboemcamera.so, RTLD_NOW);,无法跟踪camera_take_picture,那么?,INK_camera_take_picture(camera_cb, this),这个应该是只有库,而没有源代码的,但应该是open(“/dev/video0),且包含对线程的控制,成了重点,Android中Camera工作的具体过程(23),camera_cb:一个Qualcomm.中
32、的函数,void QualcommCameraHardware:camera_cb( camera_cb_type cb, camera_func_type func, .) switch(func) CAMERA_STATE(CAMERA_FUNC_ENCODE_PICTURE) switch (cb) case CAMERA_RSP_CB_SUCCESS: break; /已经用camera_encode_picture()完成了编码 case CAMERA_EXIT_CB_DONE: if (obj-mCameraState = QCS_WAITING_JPEG) obj-receive
33、JpegPictureFragment(parm4); obj-receiveJpegPicture();,处理JPEG,Android中Camera工作的具体过程(24),receiveJpegPictureFragment,QualcommCameraHardware *obj = client_data;,camera_cb的参数,receiveJpegPictureFragment(encInfo) uint8_t *base = mJpegHeap-mHeap-base(); uint32_t size = encInfo-size; memcpy(base + mJpegSize,
34、 enc-buffer, size); mJpegSize += size; /拷贝最后一帧,receiveJpegPicture,if (mJpegPictureCallback) buffer=new MemoryBase(mJpegHeap-mHeap,.); mJpegPictureCallback(buffer, );,那个data!,有Preview这些堆才有内容,Android中Camera工作的具体过程(25),那么对于Raw Data又如何呢?,void QualcommCameraHardware:camera_cb( ) switch(func) CAMERA_STATE
35、(CAMERA_FUNC_TAKE_PICTURE) if (cb = CAMERA_RSP_CB_SUCCESS) TRANSITION(QCS_?, QCS_WAITING_RAW); else if (cb = CAMERA_EVT_CB_SNAPSHOT_DONE) obj-notifyShutter(); obj-receiveRawPicture(parm4); else if (cb = CAMERA_EXIT_CB_DONE) obj-receivePostLpmRawPicture(parm4); ,切换了状态!,ShutterCB在这里,Android中Camera工作的具
36、体过程(26),很关键的函数:receiveRawPicture,receiveRawPicture(frame) if (mRawPictureCallback != NULL) ssize_t offset = frame-buffer; offset -= (uint32_t)mRawHeap-mHeap-base(); offset /= frame_size; mRawPictureCallback(mRawHeap-mBuffersoffset,);,为什么data是空的呢?可能的原因:版本不一致;调用的不是这个函数;mRawHeap为空;回传过程出现的问题;raw_cb是什么;o
37、em库没处理mRawHeap,我们的故事到此为止,剩下的剖析和调试自己弄吧!,CV Image的表示,Image的数学表示和计算机表示,Images在数学上就表示成一个2-D函数f(x,y),x和y是spatial coordinates,f是图像在这个坐标点的值(可以使灰度,RGB等等),m和n是x和y离散化以后的结果,CV很困难,3D2D必然丢失了很多信息,所以2D3D困难,有大量噪声shadows, reflections, motion blur,(m,n)对应的点称为一个像素:pixel,目标的shape,size,color随pose和lighting变化,对Image的理解是“A
38、I-complete”的,making computers as intelligent as people,一个Image数据实例,m=0.15 n=0.15 value=0.255,X=0,15 Y=0,15 Z=0,255,f: XY Z,当进行数学处理时用f(x,y),当写算法时用u(m,n),16行,16列,Low-Level Vision Image Enhancement (图像增强),Image Enhancement,增强图像的特征(image features),特征包括边界(boundaries),对比度(contrast)等,图像增强,空间操作,点操作,变换操作,Con
39、trast stretching,Noise clipping,Window Slicing,Histogram modeling,Noise smoothing,Median Filtering,Unsharp masking,Low-pass, high-pass filtering,Linear filtering,Root filtering,Homomorphic filtering,Point Operations,将一个点的值变成另一个值,Contrast stretching(对比度拉伸),v=f(u),操作原因:曝光不足(或曝光不均匀),感知范围非线性,v = f(u) =,
40、u,0ua,(u-a),(u-b),aub,buc,对比度拉伸:让暗的更暗,亮的更亮,Point Operations,将一个点的值变成另一个值,Thresholding(二值化),v=f(u),v = f(u) =,255,Tu,0,uT,对比度拉伸的极限情况:只有最暗和最亮,Point Operations,有时候也可以是一堆点一起操作,Histogram equalization(直方图均衡化):可以增加整个图像的对比度,所有的像素都在中间灰度部分,很亮和很暗都有,v=f(u),Point Operations,Histogram equalization的具体实现,均衡化的含义就是让变
41、换后的图像其直方图分布累计函数(cumulative distribution function, CDF)为线性,x为原图,y为变换后的图,pxi = p(x=i) = ni/n,0iL,其中ni是灰度值为i的像素个数,n是所有的像素个数,CDFx(i) = j=0ipxj,CDFx(i),CDFy(i) = iK,CDFy(i),Point Operations,Histogram equalization的具体实现,y=T(x)=CDFx(x)(xmax-xmin)+xmin, x原图像素值,y变换后像素值,通常xmin=0,xmax=L-1,CDFy(i) = iK,设x=50,y=T
42、(50)0+xminxmin,设x=150,y=T(150)(xmax-xmin)+xminxmax,CDFy(i)=x=0up(x) = CDFx(u); T(u) = i =CDFx(u),x1x2CDF(x1)CDF(x2) y1y2,不改变像素之间的关系,所以不改变图像,Point Operations,Histogram equalization的一个实例,直方图,CDF,cdf(x)-cdfmin,cdfmax-cdfmin,T(x)=,255,46-1,63,T(78)=,255,= 182,Spatial Operations,这个操作表现为一个Spatial Filter,f
43、ilter对应的操作是进行一个mask(掩模),通常就是33 mask,xnew = i=08wixiold,w0,w1,w2,w3,w4,w5,w6,w7,w8,x,体现了Spatial,MN个像素挨个处理一遍,Spatial Operations,Spatial Average (Mean Filter),wi ,i=0.8 = 1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9,具有邻域平滑,平滑噪声(noise smoothing),低通滤波(low-pass filter),模糊(blur)的效果,Spatial Operations,Edge Detec
44、tion,Prewitt,-1,0,1,-1,0,1,-1,0,1,1,1,1,0,0,0,-1,-1,-1,Sobel,-1,0,1,-2,0,2,-1,0,1,1,2,1,0,0,0,-1,-2,-1,Sobel,Prewitt,Original,Spatial Operations,Median Filter(中值滤波),124,126,127,120,150,125,115,119,123,115, 119, 120, 123, 124, 125, 126, 127,150,150 124,有去噪效果(noise reduction) ,尤其是高斯噪声,Transformations,
45、应用信号处理中的数学变换,现在的变换对应的是二维变换(2-D)而不是1-D的,Fourier变换,Cosine变换,找到图像的几何特征,通过处理特定的频率来改变图像的几何特征,将图像分解成具有不同重要程度的parts(根据visual quality),Transformations,Fourier变换,将图像函数分解成sine和cosine分量,即频率分量的和,F(k,l) =,m=0N-1n=0N-1 f(m,n)e-2i/N(km+ln),DFT,DFT,取对数,DC值,DC值,当然都是幅值,Transformations,Cosine变换成cosine的和,类似DFT,DCT,DCT将
46、那些高频部分(人眼不明感)的系数略去,适合压缩,C(k,l) =,A(k,l)m=0N-1n=0N-1 f(m,n) cos(2m+1)k/2N)cos(2n+1)l/2N),A(k,l) = 1/N for k,l = 0; A(k,l) = 2/N for k,l = 1.N-1,1%系数,3%系数,低频到高频,通常图像DCT是按照88分块完成的,原图,Intermediate-Level Vision Image Analysis (图像分析),图像分析,找出图像中的features,objects,patterns等等,包括特征提取、图像分割、对象识别等等,图像分析,Segmentat
47、ion,特征提取,Classification,Spatial features,Transform features,Shape features,Edges and boundaries,Template matching,Texture matching,Thresholding,Boundary detection,Clustering,Decision trees,Similarity分析,典型的AI,Segmentation,Segmentation就是将一幅图片分割成多个segments,Segment是一个像素集合(也常被称为superpixels),Segmentation的
48、目标是将图片简化成一些更有意义,更容易分析的部分,Edge Detection是Segmentation的基础,Feature Extraction,图像上通常定义的feature,Area(面积),计数每个labeled blob中pixels个数,Blob label:每扫描到一个“on”像素,将和其connected的像素用同样的label标记,for i=1:1:width for j=1:1:height if(imageij = 2) area2 += 1;,Feature Extraction,图像上通常定义的feature,Perimeter(周长),计数blob的border
49、上0的个数,Perimeter Pixels,Compactness(密实程度),Compactness = 周长2/(4面积),圆的compactness?,Form factor(波形系数) =(4面积)/周长2,Solidity(实积度) =面积/Convex的面积,Pattern Classification,根据feature对图像分类,采样点,High-Level Vision Image Interpretation (图像解释),Image Interpretation,Identification(通常也包括measurement) targets,其目的是抽取有用的information,Recognizing targets是Image Interp
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 乡镇工作制度
- 区法院工作制度
- 内核工作制度
- 全村工作制度
- 养鸡场工作制度
- 三治工作制度
- 产业园工作制度
- 2026 年中职工程软件(软件基础)试题及答案
- 公务员面试组织计划能力培训
- 儿童培训店长年终总结
- 温室火灾的防控与处理
- 空调安装调试及售后服务方案
- 4.3.1空间直角坐标系市公开课一等奖课件公开课一等奖课件省赛课获奖课件
- 居然之家租赁合同
- 越野试驾活动方案
- 四乙基铅抗爆剂生产技术项目可行性研究报告
- 中考复习之标点符号的使用方法79张课件
- 社会建构主义
- 精神科护理临床实践能力考核表
- GB/T 5137.4-2020汽车安全玻璃试验方法第4部分:太阳能特性试验
- GB/T 30707-2014精细陶瓷涂层结合力试验方法划痕法
评论
0/150
提交评论