Menu
Woocommerce Menu

【银河国际网址手机版】扫一扫实现,OpenCV学习开发笔记一

0 Comment


下面是在官方文档中列出的最重要的模块。

函数可以赋值给一个变量

银河国际网址手机版 1二维码银河国际网址手机版 2条形码

本文章采用的的开发环境为:1)Xcode 8.22)OpenCV for iOS 3.2

func abc(a:Int,b:Int...,c:Int = 10){ }

银河国际网址手机版 3新的一年加油

导入 OpenCV 到 Xcode 的工程中还是比较简单的,从官网下载对应的
framework,直接丢到 Xcode
的工程中,从xcode7以后拖入的工程会自动添加到Building
phase里面,检查一下。

可变长参数最多一个

到这里已经实现了扫一扫的功能。图片附上:

最近公司项目进入了较为稳定的维护周期,考虑到后面很可能会进行需要生物特征识别的项目,提前学习下OpenCV,也在此和大家分享一下。

函数调用为abc(x:1,y:2,z:3)标签名可以重复,不推荐

大家有什么问题可以给我回复。

cv::Mat

使用默认值参数,实际上函数会被重载为两个函数,函数调用为abc,abc(a:1,b:2,c:3)默认值参数的位置没有要求

.全局视图变量

/// 扫描容器

var customContainerView: UIView!

/// 底部工具条

var customTabbar: UITabBar!

/// 结果文本

var customLabel: UILabel!

/// 冲击波视图

var scanLineView: UIImageView!

///框

var borderIV: UIImageView!

加载UI

private func setUpUI() {

let rightItem: UIBarButtonItem = UIBarButtonItem(title: “相册”, style:
.plain, target: self, action: #selector(choosePicFromPhotoLib)

navigationItem.rightBarButtonItem = rightItem

customContainerView = UIView(frame: CGRect(x: 0, y: 0, width:
kScreenWidth-100, height: kScreenWidth-100))

customContainerView.center = self.view.center;

customContainerView.backgroundColor = UIColor.yellow

customContainerView.clipsToBounds = true

view.addSubview(customContainerView)

customLabel = UILabel(frame: CGRect(x: 0, y: kNavbarHeight+20, width:
kScreenWidth, height: 40))

customLabel.textColor = UIColor.white

customLabel.textAlignment = NSTextAlignment.center

view.addSubview(customLabel)

borderIV = UIImageView(frame: customContainerView.frame)

borderIV.image = UIImage(named: “codeframe”)

borderIV.clipsToBounds = true

view.addSubview

scanLineView = UIImageView(frame: CGRect(x: 0, y:
0-customContainerView.frame.size

.height, width: customContainerView.frame.size.width, height:
customContainerView.frame.size.height))

scanLineView.image = UIImage(named: “qrcode_scanline_qrcode”)

borderIV.addSubview(scanLineView)

customTabbar = UITabBar(frame: CGRect(x: 0, y:
(kScreenHeight-kTabBarHeight), width: kScreenWidth, height: 49))

customTabbar.delegate = self

customTabbar.backgroundColor = UIColor.red

customTabbar.barTintColor = UIColor.red

view.addSubview(customTabbar)

let leftBarItem: UITabBarItem = UITabBarItem(title: “”, image:
UIImage(named: “qrcode_tabbar_icon_qrcode”), selectedImage:
UIImage(named: “qrcode_tabbar_icon_qrcode_highlighted”));

let rightBarItem: UITabBarItem = UITabBarItem(title: “”, image:
UIImage(named: “qrcode_tabbar_icon_barcode”), selectedImage:
UIImage(named: “qrcode_tabbar_icon_barcode_highlighted”));

customTabbar.setItems([leftBarItem,rightBarItem], animated: true)

customTabbar.selectedItem = customTabbar.items?.first

scanQRCode()

}

// MARK: -懒加载

//设备输入

private lazy var input: AVCaptureDeviceInput? = {

let device = AVCaptureDevice.defaultDevice(withMediaType:
AVMediaTypeVideo)

return try? AVCaptureDeviceInput(device: device)

}()

//创建Session

private lazy var session:AVCaptureSession = AVCaptureSession()

//设备输出

private lazy var output: AVCaptureMetadataOutput = {

let out = AVCaptureMetadataOutput()

let viewRect = self.view.frame

let containerRect = customContainerView.frame;

let x = containerRect.origin.y / viewRect.height;

let y = containerRect.origin.x / viewRect.width;

let width = containerRect.height / viewRect.height;

let height = containerRect.width / viewRect.width;

out.rectOfInterest = CGRect(x: x, y: y, width: width, height: height)

return out

}()

lazy var containerLayer:CALayer = CALayer()

/// 预览图层

lazy var previewLayer: AVCaptureVideoPreviewLayer =
AVCaptureVideoPreviewLayer(session: self.session)

// MARK: – 内部控制方法

private func scanQRCode()

{

// 1.判断输入能否添加到会话中

if !session.canAddInput

{

return

}

// 2.判断输出能够添加到会话中

if !session.canAddOutput

{

return

}

// 3.添加输入和输出到会话中

session.addInput

session.addOutput

// 4.设置输出能够解析的数据类型

// 注意点: 设置数据类型一定要在输出对象添加到会话之后才能设置

output.metadataObjectTypes = output.availableMetadataObjectTypes

// 5.设置监听监听输出解析到的数据

output.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)

// 6.添加预览图层

view.layer.insertSublayer(previewLayer, at: 0)

previewLayer.frame = view.bounds

// 7.添加容器图层

view.layer.addSublayer(containerLayer)

containerLayer.frame = view.bounds

// 8.开始扫描

session.startRunning()

}

func startAnimation()

{

//2.执行扫描动画

UIView.animate(withDuration: 1.5) { () -> Void in

UIView.setAnimationRepeatCount

if (customTabbar.selectedItem == customTabbar.items?.first){

scanLineView.frame = CGRect(x: scanLineView.frame.origin.x, y:
scanLineView.frame.origin.y+customContainerView.frame.size.height+100,
width: scanLineView.frame.size.width, height:
scanLineView.frame.size.height)

}else {

scanLineView.frame = CGRect(x:scanLineView.frame.origin.x,
y:borderIV.frame.origin.y+borderIV.frame.size.height,
width:borderIV.frame.size.width, height:borderIV.frame.size.height)

}

}

}

extension QRCodeScanViewController: UITabBarDelegate {

func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {

// 根据当前选中的按钮重新设置二维码容器高度

if (tabBar.selectedItem == customTabbar.items?.first){

UIView.animate(withDuration: 0.5) { () -> Void in

borderIV.frame = customContainerView.frame

borderIV.center = self.view.center;

scanLineView.image = UIImage(named: “qrcode_scanline_qrcode”)

}

}else{

UIView.animate(withDuration: 0.5) { () -> Void in

borderIV.frame = CGRect(x:borderIV.frame.origin.x,
y:borderIV.frame.origin.y, width:borderIV.frame.size.width,
height:borderIV.frame.size.width/2)

borderIV.center = self.view.center;

scanLineView.image = UIImage(named: “qrcode_scanline_barcode”)

}

}

}

}

extension QRCodeScanViewController: UINavigationControllerDelegate,
UIImagePickerControllerDelegate {

private func imagePickerController(picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : AnyObject]) {

// 1.取出选中的图片

guard let image = info[UIImagePickerControllerOriginalImage] as?
UIImage else

{

return

}

guard let ciImage = CIImage(image: image) else

{

return

}

// 2.从选中的图片中读取二维码数据

// 2.1创建一个探测器

if #available(iOS 8.0, *) {

let detector = CIDetector(ofType: CIDetectorTypeQRCode, context: nil,
options: [CIDetectorAccuracy: CIDetectorAccuracyLow])

// 2.2利用探测器探测数据

let results = detector?.features(in: ciImage)

// 2.3取出探测到的数据

for result in results!

{

print((result as! CIQRCodeFeature).messageString)

customLabel.text = (result as! CIQRCodeFeature).messageString

}

} else {

// Fallback on earlier versions

}

picker.dismiss(animated: true) { () -> Void in

self.startAnimation()

}

}

}

extension QRCodeScanViewController:
AVCaptureMetadataOutputObjectsDelegate

{

/// 只要扫描到结果就会调用

private func captureOutput(captureOutput: AVCaptureOutput!,
didOutputMetadataObjects metadataObjects: [AnyObject]!,
fromConnection connection: AVCaptureConnection!)

{

// 1.显示结果

print(metadataObjects.last?.stringValue)

customLabel.text = metadataObjects.last?.stringValue

clearLayers()

// 2.拿到扫描到的数据

guard let metadata = metadataObjects.last as? AVMetadataObject else

{

return

}

// 通过预览图层将corners值转换为我们能识别的类型

let objc = previewLayer.transformedMetadataObject(for: metadata)

// 2.对扫描到的二维码进行描边

drawLines(objc: objc as! AVMetadataMachineReadableCodeObject)

}

// 绘制描边

private func drawLines(objc: AVMetadataMachineReadableCodeObject)

{

// 0.安全校验

guard let array = objc.corners else

{

return

}

// 1.创建图层, 用于保存绘制的矩形

let layer = CAShapeLayer()

layer.lineWidth = 2

layer.strokeColor = UIColor.green.cgColor

layer.fillColor = UIColor.clear.cgColor

// 2.创建UIBezierPath, 绘制矩形

let path = UIBezierPath()

let point = CGPoint(x: 0, y: 0)

var index = 0

index+=1

CGPoint(dictionaryRepresentation: (array[index] as! CFDictionary))

// CGPointWithDictionaryRepresentation((array[index++] as!
CFDictionary), &point)

// 2.1将起点移动到某一个点

path.move(to: point)

// 2.2连接其它线段

while index < array.count

{

index+=1

CGPoint(dictionaryRepresentation: (array[index] as! CFDictionary))

path.addLine(to: point)

}

// 2.3关闭路径

path.close()

layer.path = path.cgPath

// 3.将用于保存矩形的图层添加到界面上

containerLayer.addSublayer

}

/// 清空描边

private func clearLayers()

{

guard let subLayers = containerLayer.sublayers else

{

return

}

for layer in subLayers

{

layer.removeFromSuperlayer()

}

}

}

override func viewDidLoad() {

super.viewDidLoad()

title = “扫一扫”

setUpUI()

startAnimation()

}

把使用到 OpenCV 中 C++方法的实现文件后缀名改成.mm,就可以开始使用 OpenCV
的方法了。

在参数类型后加...

完整demo戳这里

银河国际网址手机版 4搭建环境

函数名相同,参数表不同的函数。返回值不作为重载的标准。参数表:参数个数,参数类型,参数顺序,参数标签名

#ifdef __cplusplus#import <opencv2/opencv.hpp>#endif
func abc(x a:Int,y b:Int,z c:Int){ }

OpenCV
,是一个开源的跨平台计算机视觉和机器学习库,通俗点的说,就是他给计算机提供了一双眼睛,一双可以从图片中获取信息的眼镜,从而完成人脸识别、去红眼、追踪移动物体等等的图像相关的功能。更多具体的说明可参见
OpenCV 官网。

以上参数标签为a,b,c,函数调用为abc(a:1,b:2,c:3)指定参数标签

OpenCV
包含几百个类。为简便起见,我们只看几个基础的类和操作,进一步阅读请参考全部文档。过一遍这几个核心类应该足以对这个库的机理产生一些感觉认识。

赋值给变量后的函数调用,不需要加函数标签名

标签:

发表评论

电子邮件地址不会被公开。 必填项已用*标注

相关文章

网站地图xml地图