转:ios通过摄像头获取特定数据(http://www.2cto.com/kf/201404/290777.html)

凝视: 因为近期项目需求,须要一个可以实现对摄像头图片获取当中部分内容的功能,类似于二维码扫描。

可是仅仅须要获取特定位置的像素块进行简单计算就可以,所以听上去还是非常easy的。可是经过实践,发现,现实似乎与想象中不一样,因为摄像头拍到的数据,採用的是QZ(也就是CG框架)进行绘制。所以涉及到坐标系与frame的坐标系不一致的问题。

1:尝试直接拿到摄像头数据,先输出看下。 code: 代码略。 

总结: 直接使用摄像头数据再用imageView的方式显示出来的时刻。我们发现,数据是正确的==。所见即所得的方式。 须要注意的是: 当图片是横向拍摄的时刻。我们能够看到。相机会自己主动将图片进行90度旋转,也就是说。系统在你横向拍摄的时刻。会自己主动将图片旋转90度。满足你正常情况下的观看。

所以: 我们使用imageView对拿到的数据进行展示的时刻,数据并没有颠倒的现象。

为了防止出现这个现象的原因是出于imageView的内部实现,我们使用CgimageRef的方式。再次验证 从摄像头拿到的数据真的和我们所示一样吗? 

code:

CGImageRef oldImageRef=image.CGImage;

UIImage* newImage=[UIImage imageWithCGImage:oldImageRef];

凝视: 

在这里,我们仅仅是对拿到的Image对象,先转换成了CGimage。再使用UIImage的方法得到新的Image对象。 

结果:我们发现,得到的图像果然就是旋转90度的图片。而不再是原图了。

UIImage* newImage=[UIImage imageWithCGImage:oldImageRef scale:.1 orientation:UIImageOrientationRight];

使用上面的语句,能够将图像旋转90度变成我们须要的样子。

思考: 

这么简单的变化中,图片会不会丢失数据? ---------

NSData* data=UIImageJPEGRepresentation(image, 0);

NSLog(@"%lu",(unsigned long)data.length);



还好,数据没有丢失。既然数据没有丢失,那么我们应该能够获取到当中特定的一块数据得出。再显示出来才对。 

问题来了: 我们要获取某一块数据的内容,我们应该怎么传递rect呢?由于我们默认的rect与CG的坐标系并不同。是否须要转换呢? 







1:我们先试一下,先把数据转过来。再从里面拿一部分. code:

CGImageRef imageRef=image.CGImage;

CGImageRef newimage=CGImageCreateWithImageInRect(imageRef, rect);

结果发现: 拿到的数据还是倾斜了90度。也就是说,我们上面对数据这种转换事实上根本没有起到作用,数据在底层存储的方式就是使用CG的坐标系存储的。 

经过试验发现,[UIImage imageWithCGImage:oldImageRef scale:.1 orientation:UIImageOrientationRight]中,对orientation的改变。不会对我们的实验结果产生不论什么影响。 也就是说,这种方法,事实上并没有对底层的数据进行操作,而仅仅只是是在初始化新的UIImage的时刻,对底层像素的读取,orientation不同。方向也不同而已。 

思考: 

由于,我们使用上面的方法,并没有操作究竟层的像素矩阵。也就是我。我们假设想要解决问题,有两种方式, 1:将底层数据矩阵转换成我们须要的相应坐标系的内容。

这也就是CTM转换。 将Image对象内部数据进行转换。

code:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
-
(UIImage *)image:(UIImage *)image rotation:(UIImageOrientation)orientation
{
    longdoublerotate
=
0.0;
    CGRect
rect;
    floattranslateX
=
0;
    floattranslateY
=
0;
    floatscaleX
=
1.0;
    floatscaleY
=
1.0;
     
    switch(orientation)
{
        caseUIImageOrientationLeft:
            rotate
= M_PI_2;
            rect
= CGRectMake(
0,0,
image.size.height, image.size.width);
            translateX
=
0;
            translateY
= -rect.size.width;
            scaleY
= rect.size.width/rect.size.height;
            scaleX
= rect.size.height/rect.size.width;
            break;
        caseUIImageOrientationRight:
            rotate
=
3*
M_PI_2;
            rect
= CGRectMake(
0,0,
image.size.height, image.size.width);
            translateX
= -rect.size.height;
            translateY
=
0;
            scaleY
= rect.size.width/rect.size.height;
            scaleX
= rect.size.height/rect.size.width;
            break;
        caseUIImageOrientationDown:
            rotate
= M_PI;
            rect
= CGRectMake(
0,0,
image.size.width, image.size.height);
            translateX
= -rect.size.width;
            translateY
= -rect.size.height;
            break;
        default:
            rotate
=
0.0;
            rect
= CGRectMake(
0,0,
image.size.width, image.size.height);
            translateX
=
0;
            translateY
=
0;
            break;
    }
     
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef
context = UIGraphicsGetCurrentContext();
    //做CTM变换
    CGContextTranslateCTM(context,0.0,
rect.size.height);
    CGContextScaleCTM(context,1.0,
-
1.0);
    CGContextRotateCTM(context,
rotate);
    CGContextTranslateCTM(context,
translateX, translateY);
     
    CGContextScaleCTM(context,
scaleX, scaleY);
    //绘制图片
    CGContextDrawImage(context,
CGRectMake(
0,0,
rect.size.width, rect.size.height), image.CGImage);
     
    UIImage
*newPic = UIGraphicsGetImageFromCurrentImageContext();
     
    returnnewPic;
}

结论:

这里的解决方式。就是对底层像素矩阵进行装换之后,在对里面数据截取一部分。

能够解决截取部分内容的问题。

-------------------

2:解决方式二:就是对rect进行装换。依据数据底层,进行rect的转换。

直接获取摄像头传回的图像数据(人脸、微笑、眨眼: 识别-->第一步):图像识别第一步的更多相关文章

  1. OpenCV 学习笔记 05 人脸检测和识别

    本节将介绍 Haar 级联分类器,通过对比分析相邻图像区域来判断给定图像或子图像与已知对象是否匹配. 本章将考虑如何将多个  Haar 级联分类器构成一个层次结构,即一个分类器能识别整体区域(如人脸) ...

  2. MATLAB获取“非免驱的相机或者摄像头”的图像数据

    Image Acquisition Toolbox™ Adaptor Kit 图像採集工具箱 当要使用MATLAB获取"非免驱的相机或者摄像头"的图像数据时,须要开发一个插件,MA ...

  3. vc/mfc获取rgb图像数据后动态显示及保存图片的方法

    vc/mfc获取rgb图像数据后动态显示及保存图片的方法 该情况可用于视频通信中获取的位图数据回放显示或显示摄像头捕获的本地图像 第一种方法 #include<vfw.h> 加载 vfw3 ...

  4. Opencv+MFC获取摄像头数据,显示在Picture控件

    分为两步:OpenCV获取摄像头数据+图像在Picture上显示 第一步:OpenCV获取摄像头数据 参考:http://www.cnblogs.com/epirus/archive/2012/06/ ...

  5. Hi3516开发笔记(十):Qt从VPSS中获取通道图像数据存储为jpg文件

    前言   上一篇已经将himpp套入qt的基础上进行开发.那么qt中拿到frame则是很关键的交互,这是qt与海思可能编解码交叉开发的关键步骤.   受限制   因为直接配置sample的vi比较麻烦 ...

  6. C++ DirectShow读取摄像头后然后保存图像数据

    #include <stdio.h> #include "camerads.h" #include <highgui.h> const char *g_sz ...

  7. 使用OpenCV通过摄像头捕获实时视频并探测人脸

    在Opencv初接触,图片的基本操作这篇手记中,我介绍了一些图片的基本操作,视频可以看作是一帧一帧的图片,因此图片操作其实是视频操作的基础,这篇手记就来讲讲OpenCV中的视频操作,并实现一个用笔记本 ...

  8. 人脸检测及识别python实现系列(3)——为模型训练准备人脸数据

    人脸检测及识别python实现系列(3)——为模型训练准备人脸数据 机器学习最本质的地方就是基于海量数据统计的学习,说白了,机器学习其实就是在模拟人类儿童的学习行为.举一个简单的例子,成年人并没有主动 ...

  9. 人脸检测及识别python实现系列(1)——配置、获取实时视频流

    人脸检测及识别python实现系列(1)——配置.获取实时视频流 1. 前言 今天用多半天的时间把QQ空间里的几篇年前的旧文搬到了这里,算是完成了博客搬家.QQ空间里还剩下一些记录自己数学学习路线的学 ...

随机推荐

  1. 配置Jenkins的slave节点的详细步骤适合windows等其他平台

    @  新建一个slave节点在Jenkins服务器上 1,进入Jenkins的主界面,进入"Manage Jenkins" 页面: 2,点击如下图中的"Manage  N ...

  2. Eclipe快捷键

    常用的快捷键其实不多,但是用的少了又忘记了,所以讲常用的快捷键整理一下,方便以后自己来看. Ctrl+1 快速修复(最经典的快捷键,就不用多说了) Ctrl+D: 删除当前行 Ctrl+Q 定位到最后 ...

  3. 最长公共子序列(POJ1458)

    题目链接:http://poj.org/problem?id=1458 题目大意:给出两个字符串,求出这样的一个最长的公共子序列的长度:子序列中的每个字符都能在两个原串中找到,而且每个字符的先后顺序和 ...

  4. 51单片机和Arduino—闪烁灯实现

        技术:51单片机学习.Keil4环境安装.Arduino环境安装.闪烁灯教程   概述 本文提供51单片机.Arduino单片机入门软件安装和一些需要使用的软件介绍,为后续单片机.嵌入式开发做 ...

  5. 微信小程序,创业新选择

    微信小程序,创业新选择 创业者们 总是站在时代的风口浪尖,他们踌躇满志无所畏惧,这大概就是梦想的力量.但是,如果没有把梦想拆解成没有可预期的目标和可执行的实现路径那么一切都只能叫做梦想. 小程序 张小 ...

  6. net.sf.json.JSONException: &#39;object&#39; is an array. Use JSONArray instead

    list集合转换JSON出错误 意思是:对象"是一个数组. 使用jsonarray取代. 解决方法: 将JSONObject替换为JSONArray 代码: JsonConfig jsonC ...

  7. 简单原始的ASP.NET WEBFORM中多文件上传【参考其他资料修改】

    首先是ASPX页面中添加file标签 <input onclick="addFile()" type="button" value="增加&qu ...

  8. Spring MVC 教程,快速入门,深入分析[1-11]

    资源下载: Spring_MVC_教程_快速入门_深入分析V1.1.pdf SpringMVC核心配置文件示例.rar     作者:赵磊 博客:http://elf8848.iteye.com   ...

  9. Docker : endpoint with name xxx already exists.

    停止不了容器,在尝试过: docker stop [container_id] docker kill  [container_id] 都不行之后,强制删除容器: docker rm -f [cont ...

  10. 通过管理员命令进入D盘

    第一步:Windows键+R打开运行 输入cmd敲回车,打开命令提示符程序.或者点击开始,再点击运行,即可打开命令提示符程序:或者在开始菜单的搜索框中输入CMD:点击运行. 第二步:输入CMD,回车. ...