2015年7月30日星期四

IOS 通过摄像头读取每一帧的图片,并且做识别做人脸识别(swift) - qg

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
IOS 通过摄像头读取每一帧的图片,并且做识别做人脸识别(swift) - qg  阅读原文»

最近帮别人做一个项目,主要是使用摄像头做人脸识别

github地址:https://github.com/qugang/AVCaptureVideoTemplate

要使用IOS的摄像头,需要使用AVFoundation 库,库里面的东西我就不介绍。

启动摄像头需要使用AVCaptureSession 类。

然后得到摄像头传输的每一帧数据,需要使用AVCaptureVideoDataOutputSampleBufferDelegate 委托。

首先在viewDidLoad 里添加找摄像头设备的代码,找到摄像头设备以后,开启摄像头

captureSession.sessionPreset = AVCaptureSessionPresetLow
let devices
= AVCaptureDevice.devices()
for device in devices {
if (device.hasMediaType(AVMediaTypeVideo)) {
if (device.position == AVCaptureDevicePosition.Front) {
captureDevice
= device as?AVCaptureDevice
if captureDevice != nil {
println(
"Capture Device found")
beginSession()
}
}
}
}

beginSession,开启摄像头:

func beginSession() {
var err : NSError
? = nil
captureSession.addInput(AVCaptureDeviceInput(device: captureDevice, error:
&err))
let output
= AVCaptureVideoDataOutput()

let cameraQueue
= dispatch_queue_create("cameraQueue", DISPATCH_QUEUE_SERIAL)
output.setSampleBufferDelegate(self, queue: cameraQueue)
output.videoSettings
= [kCVPixelBufferPixelFormatTypeKey: kCVPixelFormatType_32BGRA]
captureSession.addOutput(output)


if err != nil {
println(
"error: \(err?.localizedDescription)")
}
previewLayer
= AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer
?.videoGravity = "AVLayerVideoGravityResizeAspect"
previewLayer
?.frame = self.view.bounds
self.view.layer.addSublayer(previewLayer)

captureSession.startRunning()
}

开启以后,实现captureOutput 方法:

func captureOutput(captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, fromConnection connection: AVCaptureConnection!) {

if(self.isStart)
{
let resultImage
= sampleBufferToImage(sampleBuffer)

let context
= CIContext(options:[kCIContextUseSoftwareRenderer:true])
let detecotr
= CIDetector(ofType:CIDetectorTypeFace, context:context, options:[CIDetectorAccuracy: CIDetectorAccuracyHigh])




let ciImage
= CIImage(image: resultImage)

let results:NSArray
= detecotr.featuresInImage(ciImage,options: ["CIDetectorImageOrientation" : 6])

for r in results {
let face:CIFaceFeature
= r as! CIFaceFeature;
let faceImage
= UIImage(CGImage: context.createCGImage(ciImage, fromRect: face.bounds),scale: 1.0, orientation: .Right)

NSLog(
"Face found at (%f,%f) of dimensions %fx%f", face.bounds.origin.x, face.bounds.origin.y,pickUIImager.frame.origin.x, pickUIImager.frame.origin.y)

dispatch_async(dispatch_get_main_queue()) {
if (self.isStart)
{
self.dismissViewControllerAnimated(
true, completion: nil)
self.didReceiveMemoryWarning()

self.callBack
!(face: faceImage!)
}
self.isStart
= false
}
}
}
}

在每一帧图片上使用CIDetector 得到人脸,CIDetector 还可以得到眨眼,与微笑的人脸,如果要详细使用去官方查看API

上面就是关键代码,设置了有2秒的延迟,2秒之后开始人脸检测。

全部代码:

//
// ViewController.swift
// AVSessionTest
//
// Created by qugang on 15/7/8.
// Copyright (c) 2015年 qugang. All rights reserved.
//

import UIKit
import AVFoundation

class AVCaptireVideoPicController: UIViewController,AVCaptureVideoDataOutputSampleBufferDelegate {

var callBack :((face: UIImage)
->())?
let captureSession
= AVCaptureSession()
var captureDevice : AVCaptureDevice
?
var previewLayer : AVCaptureVideoPreviewLayer
?
var pickUIImager : UIImageView
= UIImageView(image: UIImage(named: "pick_bg"))
var line : UIImageView
= UIImageView(image: UIImage(named: "line"))
var timer : NSTimer
!
var upOrdown
= true
var isStart
= false


override func viewDidLoad() {
super.viewDidLoad()

captureSession.sessionPreset
= AVCaptureSessionPresetLow
let devices
= AVCaptureDevice.devices()
for device in devices {
if (device.hasMediaType(AVMediaTypeVideo)) {
if (device.position == AVCaptureDevicePosition.Front) {
captureDevice
= device as?AVCaptureDevice
if captureDevice != nil {
println(
"Capture Device foundWebdriver配合Tesseract-OCR 自动识别简单的验证码 - to be crazy  阅读原文»


验证码: 如下,在进行自动化测试,遇到验证码的问题,一般有两种方式

1.找开发去掉验证码或者使用万能验证码

2.使用OCR自动识别


使用OCR自动化识别,一般识别率不是太高,处理一般简单验证码还是没问题

这里使用的是Tesseract-OCR,下载地址:https://github.com/A9T9/Free-Ocr-Windows-Desktop/releases

怎么使用呢?

进入安装后的目录:

tesseract.exe test.png test -1


准备一份网页,上面使用该验证码

<html>
<head>
<title>Table test by Young</title>
</head>
<body>
</br>
<h1> Test </h1>
<img src="http://csujwc.its.csu.edu.cn/sys/ValidateCode.aspx?t=1">
</br>
</body>
</html>

要识别验证码,首先得取得验证码,这两款采取对 页面元素部分截图的方式,首先获取整个页面的截图

然后找到页面元素坐标进行截取

/**
* This method for screen shot element
*
*
@param driver
*
@param element
*
@param path
*
@throws InterruptedException
*/
public static void screenShotForElement(WebDriver driver,
WebElement element, String path)
throws InterruptedException {
File scrFile
= ((TakesScreenshot) driver)
.getScreenshotAs(OutputType.FILE);
try {
Point p
= element.getLocation();
int width = element.getSize().getWidth();
int height = element.getSize().getHeight();
Rectangle rect
= new Rectangle(width, height);
BufferedImage img
= ImageIO.read(scrFile);
BufferedImage dest
= img.getSubimage(p.getX(), p.getY(),
rect.width, rect.height);
ImageIO.write(dest,
"png", scrFile);
Thread.sleep(
1000);
FileUtils.copyFile(scrFile,
new File(path));
}
catch (IOException e) {
e.printStackTrace();
}
}

截取完元素,就可以调用Tesseract-OCR生成text

// use Tesseract to get strings
Runtime rt = Runtime.getRuntime();
rt.exec(
"cmd.exe /C tesseract.exe D:\\Tesseract-OCR\\test.png D:\\Tesseract-OCR\\test -1 ");

接下来通过java读取txt

/**
* This method for read TXT file
*
*
@param filePath
*/
public static void readTextFile(String filePath) {
try {
String encoding
= "GBK";
File file
= new File(filePath);
if (file.isFile() && file.exists()) { // 判断文件是否存在
InputStreamReader read = new InputStreamReader(
new FileInputStream(file), encoding);// 考虑到编码格式
BufferedReader bufferedReader = new BufferedReader(read);
String lineTxt
= null;
while ((lineTxt = bufferedReader.readLine()) != null) {
System.out.println(lineTxt);
}
read.close();
}
else {
System.out.println(
"找不到指定的文件");
}
}
catch (Exception e) {
System.out.println(
"读取文件内容出错");
e.printStackTrace();
}
}

整体代码如下:

1 package com.dbyl.tests;
2
3 import java.awt.Rectangle;
4 import java.awt.image.BufferedImage;
5 import java.io.BufferedReader;
6 import java.io.File;
7 import java.io.FileInputStream;
8 import java.io.IOException;
9 import java.io.InputStreamReader;
10 import java.io.Reader;
11 import java.util.concurrent.TimeUnit;
阅读更多内容

没有评论:

发表评论