$30 off During Our Annual Pro Sale. View Details »

iPhoneのカメラで写真撮影から現像までの技術を紐解く

satoshin21
September 07, 2019

 iPhoneのカメラで写真撮影から現像までの技術を紐解く

https://fortee.jp/iosdc-japan-2019/proposal/a2e9b461-2c0d-47c5-b3cc-cef012e3f260

2019/09/07 早稲田大学 西早稲田キャンパス
Track B 13:30〜

iPhoneやスマートフォンにおける「カメラ」という機能。
写真を撮る、という日常的に行われている行動ではありますが、その実撮影という機能を実現するために様々な技術的処理が使われています。

このセッションでは、「カメラが光を取り込む仕組み」から「iOSで取り込んだデータを画像化する」という所を深掘りし
写真撮影という技術を皆さんと一緒に紐解いていければと思います。

satoshin21

September 07, 2019
Tweet

More Decks by satoshin21

Other Decks in Technology

Transcript

  1. iOSDC 2019 2019/9/3 at. Waseda Univ.
    @satoshin21
    iPhoneのカメラで
    写真撮影から現像までの
    技術を紐解く

    View Slide

  2. whoami
    - @satoshin21
    - iOS Application Developer at Eureka, Inc.
    ‧Pairs JP
    - Bitrise User Group Meetup Organizer
    - Camera
    ‧α7M3

    View Slide

  3. まず最初に諸注意

    View Slide

  4. ⚠ iOSの話は1/3ぐらいしかでてきません ⚠
    - 今回はカメラ技術について話します
    - 後半はMetalを使ったiOSでマニュアルカメラアプリの作り
    ⽅を紹介しますが、iOSの話が少ない
    - けど、どうしてもカメラの話がしたい!!
    ‧今後ARやDepthの技術が進んでいても切り離せないハード
    ウェアの素晴らしさ、問題、課題
    ‧単純に光学技術って⾯⽩い。カメラはエンジニアと相性
    最⾼

    View Slide

  5. 「カメラで写真を撮る」
    とは?

    View Slide

  6. 適切に光を操ること

    View Slide

  7. カメラの歴史 - カメラ‧オブスクラ
    - 紀元前350年頃
    - Camera(部屋) Obscra(暗い)
    - 物体に光が当たると特定の
    ⾊の波⻑を乱反射(錯乱)す
    る事で物が⾒える
    - 光の直進性を利⽤して壁に
    逆転した倒⽴像を映し出す
    https://kimuko.net/wpress/engawa/2015/09/13/写真家とつくる「カメラ·オブスキュラ」って?/

    View Slide

  8. カメラ‧オブスクラの問題点
    - 映し出される像が暗い
    ‧⽳から受光できる光の量が少ない
    - ⼩型化が難しい
    ‧⼩型化をすればするほど⽳が⼩さくなる
    より多くの光を、短い距離で受光体に映し出す仕組み
    = レンズの登場

    View Slide

  9. なぜレンズが必要か?

    View Slide

  10. なぜレンズが必要か?
    - 凸レンズは光の屈折性により強制的に集光することができ

    - レンズを⼤きくする事でより多くの光を短い距離で得るこ
    とができる

    View Slide

  11. ということでカメラは
    レンズ1枚あればOK !

    View Slide

  12. ということでカメラは
    レンズ1枚あればOK !
    ということにはならない

    View Slide

  13. レンズと収差
    - レンズ1枚では光を1点に集める事は難しい
    - ぼやけやにじみ、ゆがみ(=収差)が発⽣する
    ‧⾊収差
    ‧⾊の波⻑ごとに異なる屈折率によって発⽣する
    ‧軸上⾊収差、倍率⾊収差
    ‧単⾊収差(ザイデル収差)
    ‧同じ波⻑の光でも発⽣する収差
    ‧球⾯収差、コマ収差、⾮点収差、像⾯歪曲、歪曲収差

    View Slide

  14. ⾊収差 - 軸上⾊収差

    View Slide

  15. ⾊収差 - 軸上⾊収差
    - 凸レンズに光を当てた時に発⽣する⾊波⻑によって屈折率
    が異なる事に起因する
    - ⾚い⾊の焦点は遠くに、⻘い⾊の焦点は近くになる
    - ⼀枚のフィルム、撮像素⼦に写す際ににじみが発⽣する
    - この焦点距離の差が⼤きいレンズは分散が⼤きいと⾔われ

    - 分散の度合いを表す値にアッペ数があり、単位は「ν」
    - アッペ数が50以下をフリントガラス、50以上をクラウンガ
    ラスと呼ぶ

    View Slide

  16. 単⾊収差 - 球⾯収差
    https://ja.wikipedia.org/wiki/球⾯収差

    View Slide

  17. 単⾊収差 - 球⾯収差
    https://ja.wikipedia.org/wiki/球⾯収差
    - 単⼀波⻑の平⾏光でも凸レンズで1点に収束させるのは難し

    - 実際にはレンズの端の⽅では⼊射⾓度が急すぎるためにレ
    ンズよりに焦点を結んでしまう

    View Slide

  18. 単⾊収差 - 球⾯収差
    https://www.osapublishing.org/ao/abstract.cfm?uri=ao-58-4-1010

    View Slide

  19. 単⾊収差 - 球⾯収差
    https://www.osapublishing.org/ao/abstract.cfm?uri=ao-58-4-1010
    - メキシコ国⽴⾃治⼤学のRafael González⽒らが考案した
    「完全に球⾯収差を解消したレンズを解析的に設計する⽅
    法」
    - レンズの性能アップや⼩型化につながるかも?

    View Slide

  20. 収差に対応するために

    View Slide

  21. 収差に対応する - 凹レンズ

    View Slide

  22. 収差に対応する - 凹レンズ
    - 凹レンズは凸レンズと逆の性質を持ち、⾚の波⻑の屈折率
    が⼤きく、⻘の波⻑の屈折率は低い
    - また、球⾯収差が発⽣する⽅向も逆
    - 凸レンズと凹レンズを何枚も組み合わせる事で収差を打ち
    消す

    View Slide

  23. 収差に対応する - ⾮球⾯レンズ
    - レンズの表⾯を凸レンズや凹レンズと違い、球⾯ではない
    形にしたレンズを使⽤する
    - レンズの外側の屈折率を調整する事が可能
    https://ja.wikipedia.org/wiki/⾮球⾯レンズ

    View Slide

  24. ⾮球⾯レンズ
    http://appft1.uspto.gov/netacgi/nph-Parser?Sect1=PTO1&Sect2=HITOFF&d=PG01&p=1&u=%

    2Fnetahtml%2FPTO%2Fsrchnum.html&r=1&f=G&l=50&s1=%2220170299845%22.PGNR.&OS=DN/20170299845&RS=DN/20170299845

    View Slide

  25. ⾮球⾯レンズ
    http://appft1.uspto.gov/netacgi/nph-Parser?Sect1=PTO1&Sect2=HITOFF&d=PG01&p=1&u=%

    2Fnetahtml%2FPTO%2Fsrchnum.html&r=1&f=G&l=50&s1=%2220170299845%22.PGNR.&OS=DN/20170299845&RS=DN/20170299845
    - 2016/4に取得されたAppleのレンズ特許「IMAGING LENS
    SYSTEM」
    ‧現在のiPhoneがこのレンズ構成かどうかは不明
    - 特許⾃体はフレア(斜めから⼊ってくる光が意図せず映し出
    されてしまうこと)をレンズのみで抑える事が可能なレンズ
    の設計
    - ⾮球⾯レンズがふんだんに使われていることがわかる

    View Slide

  26. View Slide

  27. 集めた光をデータにする

    View Slide

  28. View Slide

  29. 銀塩カメラ‧フィルムの時代
    - フィルムには感光性のあるハ
    ロゲン化銀が塗布されている
    - ハロゲン化銀に光を当てると
    化学変化して感光核が作ら
    れ、フィルムに画像パターン
    が作られる
    - 現像液に付けると感光核の周
    囲が銀粒⼦に変化 = 現像
    - ハロゲン化銀に⾊素を加える
    と特定の⾊に感光する
    https://global.canon/ja/technology/s_labo/light/003/01.html

    View Slide

  30. 撮像素⼦(イメージセンサー)
    - デジタルカメラにおけるフィルムの役割を果たす
    - 光電効果により、光を電荷に変換する
    - CCDセンサーとCMOSセンサー
    ‧信号の読み出し⽅法に差。CMOSは各フォトダイオードで
    電荷の増幅を⾏う
    ‧省電⼒や技術の発展により今の主流はCMOS
    - 表⾯に実際に光を電荷に変換するフォトダイオードが並ん
    でいる

    View Slide

  31. 撮像素⼦の2つのポイント
    サイズ 画素

    View Slide

  32. 撮像素⼦ - サイズ
    - iPhone Xsなどのデュアルカメラにはそれぞれ別のサイズの
    撮像素⼦
    ‧広⾓側 1/2.5型
    ‧望遠側 1/3.6型
    - サイズ表記は真空管(撮像管 直径約1インチ)を使っていた
    時の名残
    https://ja.wikipedia.org/wiki/撮像管

    View Slide

  33. 撮像素⼦ - サイズ
    - 撮像素⼦のサイズが⼤きい場合、1pxに対するフォトダイ
    オードを⼤きく、多く配置する事ができる
    - 撮像素⼦のサイズが⼩さい場合、コンパクト化が可能
    フルサイズ(35mm) ⼀眼
    iPhone XS 広⾓ 1/2.5型

    View Slide

  34. 撮像素⼦ - 画素
    - 「n万画素」と表記されるアレ
    - 撮像素⼦上にフォトダイオードが画素数分配列されている
    - フォトダイオード1つ1つが光電変換により光を電荷に変更
    する
    - 電荷の⼤きさで1px毎の光の量 = 暗い、明るいをデータ化
    する

    View Slide

  35. 画素数が多い != ⾼画質
    - 1つの画素に対する受光可能な領域は100%ではない
    - 1画素のサイズが⼩さい程、受光できる光の量は少なくなる
    ‧信号増幅時にノイズが増幅されやすくなる
    - 様々な技術で1画素に対する受光領域を改良
    オンチップレンズ 配線部
    カラーフィルタ
    フォトダイオード
    1画素 4画素

    View Slide

  36. Sony Exmor IMX333
    - おそらくiPhone Xsで採⽤されている裏⾯照射式イメージセ
    ンサー
    - 1.4μmの画素(Pixel3などと同じ)
    - 裏⾯照射式とは、フォトダイオードと配線部分を裏返し、
    よりフォトダイオードへの光を受けやすくした構造
    オンチップレンズ 配線部
    カラーフィルタ
    フォトダイオード

    View Slide

  37. iPhone イメージセンサーの未来 IMX586
    - 1/2型 48MP、1画素あたり0.8μmの積層型イメージセンサー
    - ⾼解像度化と低照度時に隣接するpxの信号を加算すること
    で1.6μm相当の⾼感度撮影に対応。しかし12MPまで落ちる
    - おそらく⾼感度撮影モードと⾼解像度撮影モードを切り替
    える仕組み
    https://www.sony.co.jp/SonyInfo/News/Press/201807/18-060/index.html

    View Slide

  38. 適切に光(露出)を操る為に
    必要な3つの値

    View Slide

  39. 光(露出)を操る為の3つの値
    シャッター
    スピード
    (SS)
    F値 ISO感度

    View Slide

  40. シャッター
    スピード
    (SS)

    View Slide

  41. シャッタースピード
    - シャッターが開幕してから閉幕するまでの時間
    ‧早い
    ‧動体でもブレない
    ‧光量が少ないため、暗くなる
    ‧遅い
    ‧動体でブレる
    ‧光量を稼げる

    View Slide

  42. 44ඵ 44ඵ

    View Slide

  43. F値

    View Slide

  44. F値
    - F値が⼩さいほど絞り⽻根が開き、⼤きいほど閉まる
    - F値が⼩さい(開放)
    ‧光が多く取り⼊れることができる
    ‧被写界深度が浅くなる
    - F値が⼤きい(絞る)
    ‧光の量が少ない
    ‧被写界深度が深くなる
    https://ja.wikipedia.org/wiki/絞り_(光学)

    View Slide

  45. 被写界深度とは
    焦点深度
    ピントが合っているように⾒える範囲
    許容最⼩錯乱円
    被写界深度
    被写界深度が深い == 焦点深度が深い == ピントが合っている範囲が広い

    View Slide

  46. 絞りとは
    絞りを絞ると光の量は減るが、被写界深度は深くなる
    絞り⽻根

    View Slide

  47. 絞りと被写界深度
    絞り⽻根
    - 絞りは絞る事で被写界深度を深く == より⼤きな範囲にピ
    ントを合わせられる
    - また、収差が発⽣しやすいレンズの外側部分を使わないた
    め、収差の少ないよりキレイな写真を撮ることができる
    - iPhoneの絞りは固定で広⾓側F1.8と望遠側F2.4(iPhone Xs)
    の異なるF値を持つカメラを備えており、その差分を合成し
    てポートレートモードを実現している

    View Slide

  48. ' '

    View Slide

  49. ISO感度

    View Slide

  50. ISO感度
    - 電荷を増幅する割合。100を基準とする
    - ⾼い
    ‧暗い場所でも明るい写真が取れる
    ‧ノイズも⽬⽴ちやすくなる
    - 低い
    ‧ノイズが発⽣しにくい
    ‧写真が暗くなりがち

    View Slide

  51. *40 *40

    View Slide

  52. SS‧F値‧ISO感度の関係性
    - よくこのの関係性はバケツと蛇⼝に例えられる
    - 適正な量の⽔(光)が⼊るバケツ(ISO感度)
    ‧ISO感度が低いとバケツが⼤きくなり多く⽔を⼊れる必要
    がある
    - 蛇⼝の⼤きさ(F値)と蛇⼝を開ける時間(SS)
    ‧SSが短いと適正な量の光を得られない

    View Slide

  53. iOSでマニュアル撮影

    & RAW現像アプリを
    作ってみよう

    View Slide

  54. 今回実現するもの
    - シャッタースピード‧ISO感度を調整、撮影
    - RAW Fileを撮影
    - RAW Fileを編集

    View Slide

  55. Camera Architecture
    AVCaptureDevice .builtInTelephotoCamera .builtInDualCamera
    AVCaptureSession
    AVCaptureInput
    AVCaptureOutput
    +1(3"8pMF
    AVCaptureVideoPreviewLayer

    View Slide

  56. AVCaptureSession
    - AVCaptureDevice
    ‧物理上のカメラ‧マイクなどを抽象化したもの
    - AVCaptureDeviceInput
    ‧AVCaptureDeviceを⼊⼒⽤として扱う
    - AVCaptureSession
    ‧InputからOutputへの橋渡し
    - AVCaptureOutput
    ‧出⼒⽅法を定義

    View Slide

  57. AVCaptureDevice
    let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(
    deviceTypes: [.builtInWideAngleCamera],
    mediaType: .video,
    position: .back)
    // ϓϩύςΟͷ৚݅Λຬͨͨ͠ΧϝϥσόΠεͷऔಘ
    let devices = deviceDiscoverySession.devices
    let device = devices.first(where: { $0.deviceType
    == .builtInWideAngleCamera })

    View Slide

  58. AVCaptureDevice
    let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(
    deviceTypes: [.builtInWideAngleCamera],
    mediaType: .video,
    position: .back)
    // ϓϩύςΟͷ৚݅Λຬͨͨ͠ΧϝϥσόΠεͷऔಘ
    let devices = deviceDiscoverySession.devices
    let device = devices.first(where: { $0.deviceType
    == .builtInWideAngleCamera })

    View Slide

  59. add CaptureDevice as Input
    let captureSession = AVCaptureSession()
    captureSession.sessionPreset = .photo
    let input = try AVCaptureDeviceInput(device: device)
    captureSession.addInput(wideInput)

    View Slide

  60. AVCapturePhotoOutput
    let photoOutput = AVCapturePhotoOutput()
    captureSession.addOutput(photoOutput)

    View Slide

  61. AVCaptureVideoPreviewLayer
    final class PreviewView: UIView {
    var previewLayer: AVCaptureVideoPreviewLayer {
    return self.layer as! AVCaptureVideoPreviewLayer
    }
    func set(session: AVCaptureSession) {
    previewLayer.session = session
    }
    override public class var layerClass: Swift.AnyClass {
    get {
    return AVCaptureVideoPreviewLayer.self
    }
    }
    }

    View Slide

  62. iOS & RAW
    - iOS10からRAW(DNG)のキャプチャが可能に
    - DNG = Digital Negative
    ‧Adobe Systemsの開発したRAWファイル形式
    ‧Open Source

    View Slide

  63. RAWとは
    - 撮像素⼦で受け取った光の量、⾊情報を加⼯しやすい形で
    保持する画像データの形式
    - JPEGへの変換時、以下の処理を⾏い最終的な画像ができる
    ‧de-mosaic(各原⾊フィルタの補完)
    ‧ホワイトバランス
    ‧その他処理
    - RAWはそれらの処理を⾏う前の⽣のデータ
    ‧そのままでは画像として⾒ることはできない

    View Slide

  64. RAWでキャプチャすることのメリット
    - JPEGなどの画像データはRAWを元に各Image Processorが独
    ⾃に露出、⾊などを決めて出⼒されている
    - 後から加⼯する場合、JPEGは既に⾊や露出が決められた上
    で上塗りのような形で加⼯するため、画質低下を引き起す
    - RAW画像であれば、後からホワイトバランス、彩度、コント
    ラストなどを編集ソフト上で可逆的に編集できる = 画質が
    ⾼くレタッチが可能

    View Slide

  65. iOSでRAWをキャプチャするには
    - Appleのドキュメント「Capturing Photos in RAW Format」
    がわかりやすい
    - 以下、ドキュメントの内容をかいつまんで説明します
    https://developer.apple.com/documentation/avfoundation/cameras_and_media_capture/
    capturing_still_and_live_photos/capturing_photos_in_raw_format

    View Slide

  66. シャッター
    @IBAction func shutter(_ sender: ShutterButton) {
    guard let availableRawFormat =
    photoOutput.availableRawPhotoPixelFormatTypes.first else
    { return }
    let photoSettings = AVCapturePhotoSettings(
    rawPixelFormatType: availableRawFormat,
    processedFormat: [AVVideoCodecKey : AVVideoCodecType.jpeg])
    photoSettings.isAutoStillImageStabilizationEnabled = false
    photoOutput.capturePhoto(
    with: photoSettings,
    delegate: captureProcessor
    )
    }

    View Slide

  67. シャッター
    @IBAction func shutter(_ sender: ShutterButton) {
    guard let availableRawFormat =
    photoOutput.availableRawPhotoPixelFormatTypes.first else
    { return }
    let photoSettings = AVCapturePhotoSettings(
    rawPixelFormatType: availableRawFormat,
    processedFormat: [AVVideoCodecKey : AVVideoCodecType.jpeg])
    photoSettings.isAutoStillImageStabilizationEnabled = false
    photoOutput.capturePhoto(
    with: photoSettings,
    delegate: captureProcessor
    )
    }

    View Slide

  68. RAWImageProcessor
    class RAWCaptureProcessor: NSObject, AVCapturePhotoCaptureDelegate {
    func photoOutput(_ output: AVCapturePhotoOutput,
    didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
    if photo.isRawPhoto {
    // Save the RAW (DNG) file data to a URL.
    let dngFileURL = self.makeUniqueTempFileURL(extension: "dng")
    do {
    try photo.fileDataRepresentation()!.write(to: dngFileURL)
    rawImageFileURL = dngFileURL
    } catch {
    fatalError("couldn't write DNG file to URL")
    }
    } else {
    self.compressedFileData = photo.fileDataRepresentation()!
    }
    }

    View Slide

  69. RAWImageProcessor
    class RAWCaptureProcessor: NSObject, AVCapturePhotoCaptureDelegate {
    func photoOutput(_ output: AVCapturePhotoOutput,
    didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
    if photo.isRawPhoto {
    // Save the RAW (DNG) file data to a URL.
    let dngFileURL = self.makeUniqueTempFileURL(extension: "dng")
    do {
    try photo.fileDataRepresentation()!.write(to: dngFileURL)
    rawImageFileURL = dngFileURL
    } catch {
    fatalError("couldn't write DNG file to URL")
    }
    } else {
    self.compressedFileData = photo.fileDataRepresentation()!
    }
    }

    View Slide

  70. ISO感度、シャッタースピードをiOSで変更する
    - ISO感度
    ‧⾼い値を設定する事で暗所でも明るく撮影可能
    - シャッタースピード
    ‧短い時間を指定することで動体でもブレずに撮影
    - F値はiPhoneは固定されている
    - 普段はAVCaptureDevice.exposureModeが.autoExposureと
    なっているため、最適な露出設定を⾃動で⾏う

    View Slide

  71. ISO感度設定
    // 18.0
    captureDevice.activeFormat.minISO
    // 1728.0
    captureDevice.activeFormat.maxISO
    try? captureDevice.lockForConfiguration()
    captureDevice.setExposureModeCustom(
    duration: captureDevice.exposureDuration,
    iso: 100,
    completionHandler: nil)
    captureDevice.unlockForConfiguration()

    View Slide

  72. シャッタースピード
    // CMTime(value: 24, timescale: 1000000) = 24/1000000, 1/42000
    captureDevice.activeFormat.minExposureDuration
    // CMTime(value: 1, timescale: 1) = 1s
    captureDevice.activeFormat.maxExposureDuration
    try? captureDevice.lockForConfiguration()
    captureDevice.setExposureModeCustom(
    duration: .init(value: 1, timescale: 1000),
    iso: captureDevice.iso,
    completionHandler: nil)
    captureDevice.unlockForConfiguration()

    View Slide

  73. AVCaptureDevice まとめ
    - 基本的な部分は普段使っているAVFoundationと仕組みは変
    わらない
    - AVCapturePhotoSettingsでrawPixelFormatTypeを指定する

    View Slide

  74. RAWファイルを
    iOSで編集‧現像しよう

    View Slide

  75. Appleの提供するRAW現像サンプルコード
    - RawExpose: Using CIRAWFilter to Decode RAW Images
    - CIFilter & CIRAWFilter API
    - OpenGL(GLKView)
    ‧Deprecated in iOS 12
    - MetalKitを使って書き直す
    https://developer.apple.com/library/archive/samplecode/RawExpose/Introduction/Intro.html#//apple_ref/doc/uid/TP40017310

    View Slide

  76. RAW Processing Flow
    - CoreImage & MetalでDNGを表⽰
    ‧CIFilterをDNGファイルで初期化
    ‧出⼒されたCIImageをMTKViewにレンダリング
    - CIFilterをCIRAWFilterOptionで編集
    https://developer.apple.com/library/archive/samplecode/RawExpose/Introduction/Intro.html#//apple_ref/doc/uid/TP40017310

    View Slide

  77. DNG -> CIFilter
    let ciRawFilter = CIFilter(imageURL: dngFileURL, options: [:])

    View Slide

  78. Metal周り初期化
    private let device: MTLDevice
    private let context: CIContext
    private let commandQueue: MTLCommandQueue
    required init?(coder aDecoder: NSCoder) {
    device = MTLCreateSystemDefaultDevice()!
    context = CIContext(mtlDevice: device)
    commandQueue = device.makeCommandQueue()!
    }

    View Slide

  79. MTLCommandBuffer & MTLDevice
    - MTLDevice
    ‧GPUを抽象化したクラス
    - MTLCommandQueue
    ‧GPUへの処理命令をキューイングする
    ‧処理の単位はMTLCommandBuffer
    - CIContext
    ‧フィルタのコンパイルやレンダリングをMetalを通して⾏

    View Slide

  80. MTKViewの初期化
    @IBOutlet weak var mtkView: MTKView
    override func viewDidLoad() {
    super.viewDidLoad()
    mtkView.framebufferOnly = false
    mtkView.delegate = self
    mtkView.enableSetNeedsDisplay = true
    mtkView.device = device
    }

    View Slide

  81. Metal Rendering 1
    extension ViewController: MTKViewDelegate {
    func draw(in view: MTKView) {
    guard let drawable = view.currentDrawable, let extentSize = extentSize
    else {
    return
    }
    guard let outputImage = ciRawFilter?.outputImage else {
    return
    }
    guard let commandBuffer = commandQueue.makeCommandBuffer() else {
    return
    }
    //...

    View Slide

  82. Metal Rendering 2
    extension DetailViewController: MTKViewDelegate {
    func draw(in view: MTKView) {
    //…
    let colorSpace = CGColorSpaceCreateDeviceRGB()
    context.render(outputImage, to: drawable.texture,
    commandBuffer: commandBuffer,
    bounds: imageRect,
    colorSpace: colorSpace)
    commandBuffer.present(drawable)
    commandBuffer.commit()
    }
    }

    View Slide

  83. CIRAWFilter &
    CIRAWFilterOption

    View Slide

  84. CIRAWFilterを使ったフィルタリング
    - CIRAWFilterはCIFilterのextension
    - 使い⽅は普通のCIFilterと同じ
    - CIRAWFilterOptionでRAW加⼯可能なオプションを取得でき

    View Slide

  85. 1 .neutralTemplature

    View Slide

  86. CIRAWFilterOption.neutralTemperature
    @IBAction func tempChanged(_ sender: UISlider) {
    ciRawFilter?.setValue(sender.value, forKey:
    CIRAWFilterOption.neutralTemperature.rawValue)
    mtkView.setNeedsDisplay()
    }

    View Slide

  87. CIRAWFilterOption.neutralTemperature
    - ホワイトバランス(⾊温度)を調整できるFilterOption
    - ホワイトバランスを調整する値として他には.neutralTint
    が存在する
    https://ja.wikipedia.org/wiki/⾊温度

    View Slide

  88. ホワイトバランスとは?
    - 写真を撮る際、様々な光源の環境(電球、蛍光灯、etc)が存
    在する
    - ⽩いものを⽩く表現するために写真全体の⾊温度などを調
    整する
    - iPhone含めカメラはオートホワイトバランスで画像処理に
    より中間⾊(⽩orグレー)を判断しているが完璧ではない。
    - CIRAWFilterで調整できる範囲は2000K~8000K(Float)
    https://ja.wikipedia.org/wiki/⾊温度

    View Slide

  89. CIRAWFilterOption.neutralTemperature
    , ,

    View Slide

  90. 2 .baselineExposure

    View Slide

  91. CIRAWFilterOption.baselineExposure
    @IBAction func exposureChanged(_ sender: UISlider) {
    ciRawFilter?.setValue(sender.value, forKey:
    CIRAWFilterOption.baselineExposure.rawValue)
    mtkView.setNeedsDisplay()
    }

    View Slide

  92. CIRAWFilterOption.baselineExposure
    - 露光量を調整できるFilterOption
    - RAWを編集する場合、元の露光量を調整するため、jpegの画
    像を直接修正するよりもノイズなどが発⽣しにくい
    https://ja.wikipedia.org/wiki/⾊温度

    View Slide

  93. 露光量とは
    - 画像全体の明るさを⽰す値
    - 露光量をEV、絞り値をN,
    シャッタースピードをtとし
    て以下の計算式で算出する
    -
    - 絞り値が2, SSが4の場合は露
    光量は0
    - baselineExposureはこの値を
    調整する
    EV = log2
    N2 − log2
    t
    https://ja.wikipedia.org/wiki/露出(写真)

    View Slide

  94. 他にも様々なFilterOption
    - .boostShadowAmount
    ‧暗い部分のみを明るくすることができる
    - .neutralTint
    ‧ホワイトバランスの1種「⾊かぶり」を補正する
    ‧⻘かぶり、⾚かぶり

    View Slide

  95. まとめ

    View Slide

  96. まとめ
    - カメラは光をうまく操る技術が詰まっている
    - カメラの技術を少し理解するだけで写真を撮る楽しさがバ
    ク上がりする
    - RAW現像もサポートされて、今後のiOSとカメラの進化から
    ⽬が話せない
    - iPhone 11(仮)に期待!

    View Slide

  97. END

    View Slide