- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我有一个应用程序设置,可以使用相机拍摄照片(基于计时器)来检测人脸的存在。当我向应用程序提供我已添加到 Assets 中的照片时,检测过程运行良好。然而,当我尝试直接使用相机的输出,甚至在将图像保存到文件后,生成的图像太暗以至于面部识别完全不可靠。
如果我显示相机看到的图像,它看起来是正确的。我捕获了以下两张图像 - 一张来自实时看到的相机,另一张是从 AVCapturePhotoOutput 创建图像后的相同 View 。如果我只是在 ImageView 中显示捕获的图像,也会出现同样的黑暗。
请注意评论:“我将断点放在这里并截取了屏幕截图”。然后我在代码完成时拍摄了第二个屏幕截图。这些是在高光下拍摄的。 这是基本代码:
class CRSFaceRecognitionViewController: UIViewController, UIImagePickerControllerDelegate {
var sentBy : String?
//timers
var faceTimer : Timer?
var frvcTimer : Timer?
//capture
var captureSession = AVCaptureSession()
var settings = AVCapturePhotoSettings()
var backCamera : AVCaptureDevice?
var frontCamera : AVCaptureDevice?
var currentCamera : AVCaptureDevice?
var photoOutput : AVCapturePhotoOutput?
var cameraPreviewLayer : AVCaptureVideoPreviewLayer?
var image : UIImage?
var outputImage : UIImage?
@IBOutlet weak var imageView: UIImageView!
//MARK: - Setup
override func viewDidLoad() {
super.viewDidLoad()
}//viewDidLoad
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
}//viewWillAppear
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
//check for camera
if (UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera)) {
setupCaptureSession()
setupDevices()
setupInputOutput()
setupPreviewLayer()
startRunningCaptureSession()
photoOutput?.capturePhoto(with:settings, delegate: self)
} else {
print("Camera not present")
}
}//viewDidAppear
//MARK: - Video
@objc func showFaceRecognitionViewController() {
//all this does is present the image in a new ViewController imageView
performSegue(withIdentifier: "showSavedCameraPhoto", sender: self)
}//showThePhotoView
func setupCaptureSession() {
captureSession.sessionPreset = AVCaptureSession.Preset.photo
}//setupCaptureSession
func setupDevices() {
let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera], mediaType: .video, position: .unspecified)
let devices = deviceDiscoverySession.devices
for device in devices {
if device.position == AVCaptureDevice.Position.back {
backCamera = device
} else if device.position == AVCaptureDevice.Position.front {
frontCamera = device
}//if else
}//for in
currentCamera = frontCamera
}//setupDevices
func setupInputOutput() {
do {
let captureDeviceInput = try AVCaptureDeviceInput(device: currentCamera!)
captureSession.addInput(captureDeviceInput)
photoOutput = AVCapturePhotoOutput()
photoOutput?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format: [AVVideoCodecKey: AVVideoCodecType.jpeg])], completionHandler: {(success, error) in
print("in photoOutput completion handler")
})
captureSession.addOutput(photoOutput!)
} catch {
print("Error creating AVCaptureDeviceInput:", error)
}//do catch
}//setupInputOutput
func setupPreviewLayer() {
cameraPreviewLayer = AVCaptureVideoPreviewLayer(session : captureSession)
cameraPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
cameraPreviewLayer?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait
cameraPreviewLayer?.frame = view.frame
view.layer.insertSublayer(cameraPreviewLayer!, at: 0)
}//setupPreviewLayer
func startRunningCaptureSession() {
captureSession.startRunning()
}//startRunningCaptureSession
//MARK: - Segue
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showSavedCameraPhoto" {
let controller = segue.destination as! JustToSeeThePhotoViewController
controller.inImage = outputImage
}//if segue
}//prepare
//MARK: - Look for Faces
func findTheFaces() {
let myView : UIView = self.view
guard let outImage = outputImage else {return}
let imageView = UIImageView(image: outImage)
imageView.contentMode = .scaleAspectFit
let scaledHeight = myView.frame.width / outImage.size.width * outImage.size.height
imageView.frame = CGRect(x: 0, y: 0, width: myView.frame.width, height: myView.frame.height)
imageView.backgroundColor = UIColor.blue
myView.addSubview(imageView)
let request = VNDetectFaceRectanglesRequest { (req, err) in
if let err = err {
print("VNDetectFaceRectanglesRequest failed to run:", err)
return
}//if let err
print(req.results ?? "req.results is empty")
req.results?.forEach({ (res) in
DispatchQueue.main.async {
guard let faceObservation = res as? VNFaceObservation else {return}
let x = myView.frame.width * faceObservation.boundingBox.origin.x
let width = myView.frame.width * faceObservation.boundingBox.width
let height = scaledHeight * faceObservation.boundingBox.height
let y = scaledHeight * (1 - faceObservation.boundingBox.origin.y) - height
let redView = UIView()
redView.backgroundColor = .red
redView.alpha = 0.4
redView.frame = CGRect(x: x, y: y, width: width, height: height)
myView.addSubview(redView)
print("faceObservation bounding box:")
print(faceObservation.boundingBox)
//if you get here, then you have a face bounding box
}//main
})//forEach block
}//let request
guard let cgImage = outImage.cgImage else {return}
DispatchQueue.global(qos: .utility).async {
let handler = VNImageRequestHandler(cgImage: cgImage, options: [:])
do {
try handler.perform([request])
print("handler request was successful")
self.performSegue(withIdentifier: "showSavedCameraPhoto", sender: self)
} catch let reqErr {
print("Failed to perform request:", reqErr)
}
}//DispatchQueue
}//findTheFaces
//MARK: - Memory
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}//didReceiveMemoryWarning
}//class
extension CRSFaceRecognitionViewController : AVCapturePhotoCaptureDelegate {
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
if let imageData = photo.fileDataRepresentation() {
print(imageData)
outputImage = UIImage(data : imageData)
//
//I put breakpoint here and took a screen shot
//
if let outImage = outputImage?.updateImageOrientionUpSide() {
self.outputImage = outImage
}
DispatchQueue.main.async {
self.findTheFaces()
}
}//if let imageData
}//photoOutput
}//extension
extension UIImage {
//you need to do this to ensure that the image is in portrait mode
//the face recognition method will not work if the face is horizontal
func updateImageOrientionUpSide() -> UIImage? {
if self.imageOrientation == .up {
return self
}
UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
self.draw(in: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height))
if let normalizedImage:UIImage = UIGraphicsGetImageFromCurrentImageContext() {
UIGraphicsEndImageContext()
return normalizedImage
}
UIGraphicsEndImageContext()
return nil
}//updateImageOrientionUpSide
}//image
我一定是在拍摄相机时做错了什么。任何帮助,将不胜感激。 swift 4、iOS 11.2.5、Xcode 9.2
最佳答案
我会尝试在 startRunningCaptureSession()
和 photoOutput?.capturePhoto(with:settings, delegate: self)
之间添加延迟
例如,
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(4), 执行: {
//拍张照片
startRunningCaptureSession()
photoOutput?.capturePhoto(with:settings, delegate: self)
})
关于ios - AVCapturePhotoOutput iOS 相机超暗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48478430/
捕获图像时,输出图像的颜色与我在预览图层上看到的颜色不同。出于某种原因,颜色略有变化。有没有人遇到过这个问题?我怎样才能解决这个问题? 当我从 didFinishProcessingPhotoSamp
我正在运行 ios 12 swift 4.2。 我已经实现了一个基本的相机捕捉 session ,并且正在从中点击图像。一切都很好,直到我在自动/开/关模式之间切换闪光灯。单击第一张照片然后更改闪光灯
我的应用程序因崩溃而被拒绝。我无法在本地重现崩溃,但感谢 Apple 提供的崩溃日志,我能够将有问题的代码缩小为: func capturePhoto() { let photoOutputS
使用 AVCapturePhotoOutput 设置自定义相机。配置 AVCapturePhotoOutput 以提供除了主 JPEG 缓冲区之外的预览缓冲区(缩略图)。 问题是我只收到一次预览缓冲区
我一直致力于使用自定义相机,最近升级到 Xcode 8 beta 和 Swift 3。我最初有这个: var stillImageOutput: AVCaptureStillImageOutput?
我有一个带有 SwiftUI 生命周期的简单 SwiftUI 应用程序,我正在尝试使用AVFoundation 自动拍照。我会根据条件或基于计时器 - 但对于这个例子,我只想在启动时拍照并显示它(不是
我正在创建一个相机应用程序,一切运行良好,但上传到 Firebase 的照片的文件大小太大。它们属于 3MB 类别,我希望它们属于 ±600KB 类别。 我设置了 AVCapturePhotoSett
我看到 iOS 10 引入了 AVCapturePhotoOutput 作为处理照片捕获的新类,并且能够通过将两个缓冲区传递给 来在主图像旁边创建预览/缩略图图像AVCapturePhotoCaptu
我正在制作一个自定义相机应用程序,我可以在其中通过 takePhoto 按钮拍摄我的照片,但是 takePhoto 中出现错误,提示 AVCapturePhotoOutput 没有成员“capture
我有一个应用程序设置,可以使用相机拍摄照片(基于计时器)来检测人脸的存在。当我向应用程序提供我已添加到 Assets 中的照片时,检测过程运行良好。然而,当我尝试直接使用相机的输出,甚至在将图像保存到
我正试图摆脱 AVCaptureStillImageOutput 并采用 iOS 10 中引入的 AVCapturePhotoOutput。 但是,我的部署操作系统是 iOS 9.0。 AVCaptu
我正在关注 Apple 的最新示例代码 AVCam Swift,该代码已更新为使用 AVCapture Photo Output。 var isFlashScene: Bool { get } A B
我正在开发相机应用程序。我正在为 ios 10.x 设备使用 AVCapturePhotoOutput,为 10.x 以下设备使用 AVCaptureStillImageOutput。 我在拍摄照片时
请帮我重构这段代码,它不起作用,我在互联网上搜索但没有找到任何解决方案。我不能自己重构它。 这一行: imageOutput.captureStillImageAsynchronously(from:
我目前正在编写一段代码,如下所示: if error == nil && (captureSession?.canAddInput(input))! { captureSession?.add
很好奇,这在 Swift 4 中会是什么? stimageout = AVCapturePhotoOutput() stimageout?.outputSettings = [AVVideoCodec
以 1080 x 1440 分辨率显示预览;使用代码在 iPhone 8 Plus 上获取最大分辨率 (3024 x 4032) 和质量的照片: capturePhotoOutput?.capture
我发现了以下问题,不幸的是其他帖子没有帮助我找到有效的解决方案。 我有一个简单的应用程序可以显示相机预览 (AVCaptureVideoPreviewLayer),其中视频重力已设置为 resizeA
在新的 Xcode 12 中,出现错误:Value of type 'AVCapturePhotoOutput' has no member 'supportedFlashModes'当我尝试联系 h
背景 我使用 AVCaptureSession 和 AVCapturePhotoOutput 将捕获保存为 JPEG 图像。 let captureSession = AVCaptureSession
我是一名优秀的程序员,十分优秀!