Depth in Depth #iOSDC

19d7ae634445d4bd9b10c7961a462260?s=47 shu223
September 01, 2018

Depth in Depth #iOSDC

iOSDC Japan 2018での発表「Depth in Depth」の資料です。

## 概要

原始のiPhoneからカメラは搭載されていましたが、深度センサが搭載されたのは比較的最近のことです。カメラやGPSが、デジタルの世界と我々が生きる現実世界を繋ぐ重要な役割を担い、アプリ開発者に多くの創造性を与えてくれたのと同様に、「奥行き」がわかるようになったというのはアプリ開発の次元がひとつ増えたようなものです。本トークではiOSでの深度の扱いについて、取得方法だけではなく、細かいパラメータの意味やMetalでの処理まで詳解します。

## アジェンダ

- 深度の種類とセンサのしくみ
- 深度データを取得する
- 深度データを使ってみる
- できること・できないこと事例集

19d7ae634445d4bd9b10c7961a462260?s=128

shu223

September 01, 2018
Tweet

Transcript

  1. Depth in Depth Shuichi Tsutsumi @shu223 iOSDC 2018

  2. ࣗݾ঺հ • Fyusion Inc.ࣾһ@αϯϑϥϯγείʢH-1BϏβʣ • Senior Principal Software Engineer •

    ࠓ೥͔ΒύʔτλΠϜܖ໿ʹ → ॊೈʹಇ͖ͭͭϏβ͸ҡ ࣋ • ϑϦʔϥϯε@౦ژ • ݱࡏΞΫςΟϒʹ͓ख఻͍͍ͯ͠Δͷ͸8ࣾ΄ͲʢIoTܥɺ MetalɺARKitɺNFCɺυϩʔϯɺٕज़ސ໰ɺւ֎ɺetc...ʣ
  3. • GitHub: shu223 • ϒϩά: ͸ͯͳɺQiitaɺNote • ॻ੶:

  4. Depth in Depth σϓεʢਂ౓ʣৄղ

  5. ਂ౓ͱ͸ʁ

  6. Ԟߦ͖Λࣔ͢৘ใ 1νϟϯωϧͷը૾σʔλʢਂ౓Ϛοϓͱݺ͹ΕΔʣͰද͞ΕΔ ʢࠨɿRGBը૾ɹʗɹӈɿਂ౓Ϛοϓʣ

  7. ʮ͋ʔ͸͍͸͍ɻࣸਅΛϘέͤ͞Δ΍ͭͰ͠ΐʯ

  8. ਂ౓ͷ༻్: എܠΛඈ͹͢ • ྫɿϑϦϚܥΞϓϦͰग़඼࣌ʹഎܠΛҰൃͰඈ͹ͤΔػೳ

  9. ʢσϞʣ

  10. ਂ౓ͷ༻్: 3DεΩϟϯ • 3DϞσϧΛ࡞੒ • ෦԰ͷݟऔΓਤΛ࡞੒

  11. ਂ౓ͷ༻్: ͦͷଞ ԕִࡱӨ࣌ͷ Ի੠ʹΑΔΠϯετϥΫγϣϯ ʮ30ηϯνޙΖʹԼ͕͍ͬͯͩ͘͞ʯ ※࣮ࡍʹਂ౓͸࢖ͬͯͳ͍͔΋͠Ε·ͤΜ͕ɺਂ౓ͷ༻్ͷՄೳੑ ͱͯ͠ྫ͍ࣔͯ͠·͢

  12. ਂ౓͸ൃ૝࣍ୈͰ ৭ʑͳ࢖͍ํ͕Ͱ͖Δʂ

  13. Ͳͷ͋ͨΓΛʮৄղʯ͢Δͷ͔ʁ • ʮiOSͷAPIͷ࢖͍ํʯ͸࠷খݶʹ • εϥΠυʹ͸ࡌ͓͖ͤͯ·͢ • ຊ࣭తɾ൚༻తͳʮਂ౓σʔλͷऔΓѻ͍ํ๏ʯΛཧղ͢Δ

  14. ΞδΣϯμ • ਂ౓ͷछྨͱηϯαͷ͘͠Έ • ਂ౓σʔλΛऔಘ͢Δ • ਂ౓σʔλΛ࢖ͬͯΈΔ • Ͱ͖Δ͜ͱɾͰ͖ͳ͍͜ͱࣄྫू

  15. ΞδΣϯμ • ਂ౓ͷछྨͱηϯαͷ͘͠Έ • ਂ౓σʔλΛऔಘ͢Δ • ਂ౓σʔλΛ࢖ͬͯΈΔ • Ͱ͖Δ͜ͱɾͰ͖ͳ͍͜ͱࣄྫू

  16. Disparityʢࢹࠩʣ iPhone 7/8 Plus, Xͷഎ໘Χϝϥ

  17. ϐϯϗʔϧΧϝϥ

  18. ̎୆ͷಉ͡Focal LengthΛ࣋ͭΧϝϥ

  19. Disparityʢࢹࠩʣ

  20. DepthͱDisparityͷؔ܎

  21. Depth͸Disparity͔ΒܭࢉͰ͖Δ • Depth(z) ͷٯ਺ = ਖ਼نԽ͞Εͨ Disparity(d)

  22. Time of Flight (ToF) • DepthΛ௚઀ଌΔํࣜ • ର৅ʹরࣹͨ͠ޫ͕൓ࣹͯ͠໭ͬͯ͘Δ·Ͱͷԟ෮ͷ࣌ؒ ͔Βڑ཭Λܭଌ

  23. TrueDepth iPhone Xͷલ໘Χϝϥ

  24. • Proximity sensorʢۙ઀ηϯαʣɾɾɾToFํࣜͰإ·Ͱͷڑ ཭Λܭଌ

  25. • Dot projector (υοτϓϩδΣΫλ)ɾɾɾ3ສҎ্ͷݟ͑ͳ͍ υοτΛإͷ্ʹরࣹ

  26. • Infrated camera (੺֎ઢΧϝϥ)ɾɾɾυοτͷύλʔϯΛಡ ΈऔΔ → إͷϚοϓը૾

  27. ΞδΣϯμ • ਂ౓ͷछྨͱηϯαͷ͘͠Έ • ਂ౓σʔλΛऔಘ͢Δ • ਂ౓σʔλΛ࢖ͬͯΈΔ • Ͱ͖Δ͜ͱɾͰ͖ͳ͍͜ͱࣄྫू

  28. AVDepthData • ਂ౓Λද͢Ϋϥε • Ͳͷํ๏Ͱऔಘͯ͠΋࠷ऴతʹ͸͜Ε͕ಘΒΕΔ • @available(iOS 11.0, *)

  29. AVDepthData var depthDataMap: CVPixelBuffer { get } • ਂ౓ϚοϓͷϐΫηϧσʔλ •

    ैདྷ͔Β͋ΔCVPixelBufferͳͷͰɺCore ImageͰ΋ MetalͰ΋ɺͦͷޙͷॲཧํ๏͸ࣗࡏ
  30. iOSͰਂ౓σʔλΛऔಘ͢Δํ๏ ༻్ผʹ෼͚Δͱ̏छྨ • ํ๏1: ࡱӨࡁΈࣸਅ͔Βऔಘ • ํ๏2: Χϝϥ͔ΒϦΞϧλΠϜʹऔಘ • ํ๏3:

    ARKit͔Βऔಘ
  31. ਂ౓औಘํ๏1: ࡱӨࡁΈࣸਅ͔Βऔಘ • ImageIOΛར༻ • ʢΧϝϥϩʔϧ͔ΒಡΈࠐΜͰΞηοτͷURLΛಛఆ͢Δͱ ͜Ζ·Ͱ͸Photosʣ

  32. ΞηοτͷURL͔ΒCGImageSourceΛ࡞੒ let source = CGImageSourceCreateWithURL(url as CFURL, nil)

  33. CGImageSource͔Βਂ౓σʔλͷDictionaryΛऔಘ let info = CGImageSourceCopyAuxiliaryDataInfoAtIndex( source, 0, kCGImageAuxiliaryDataTypeDisparity // ଞͷλΠϓ΋͋Γ

    ) as? [String : AnyObject] // infoʹ͸ਂ౓Ϛοϓͷ CFDataRef ΍ // ϝλσʔλͷCGImageMetadataRef͕ೖ͍ͬͯΔ
  34. औಘͨ͠Dictionary͔ΒAVDepthDataΛॳظԽ let depthData = try! AVDepthData(fromDictionaryRepresentation: info)

  35. ਂ౓औಘํ๏2: Χϝϥ͔ΒϦΞϧλΠϜʹऔಘ • AVFoundationΛར༻ • جຊతʹ͸ैདྷͷΧϝϥࡱӨͷ࡞๏௨Γ

  36. ਂ౓͕औΕΔσόΠελΠϓͷ AVCaptureDevice Λ࢖͏ .builtInDualCamera, .builtInTrueDepthCamera let device = AVCaptureDevice.DiscoverySession( deviceTypes:

    [.builtInDualCamera], mediaType: .video, position: .back).devices.first
  37. ਂ౓͕औΕΔΩϟϓνϟʔϑΥʔϚοτΛࢦఆ͢Δ var supportedDepthDataFormats: [AVCaptureDevice.Format] • AVCaptureDevice.Format ͷϓϩύςΟ • ॴ๬ͷ΋ͷΛબͼɺAVCaptureDevice ͷ

    activeDepthDataFormat ʹηοτ͢Δ
  38. ηογϣϯͷग़ྗʹ AVCaptureDepthDataOutput Λ௥Ճ let depthOutput = AVCaptureDepthDataOutput() captureSession.addOutput(depthOutput) depthOutput.setDelegate( self,

    callbackQueue: dataOutputQueue) • AVCaptureVideoDataOutputʢϏσΦग़ྗʣ΍ AVCaptureAudioʙʢΦʔσΟΦग़ྗʣΛ௥Ճ͢Δͷͱಉ౳
  39. AVCaptureDepthDataOutputDelegate ͷ didOutput ϝιου ͔Β AVDepthData ͕ಘΒΕΔ func depthDataOutput( _

    output: AVCaptureDepthDataOutput, didOutput depthData: AVDepthData, timestamp: CMTime, connection: AVCaptureConnection)
  40. ਂ౓औಘํ๏3: ARKit͔Βऔಘ ARFrameʹcapturedDepthDataͱ͍͏ϓϩύςΟ͕͋Δ var capturedDepthData: AVDepthData? { get }

  41. ⚠ ํ๏ʹ༏ྼ͸ͳ͍ɻ༻్ʹΑͬͯબͿɻ • ํ๏1: ࡱӨࡁΈࣸਅ͔Βऔಘ • ํ๏2: Χϝϥ͔ΒϦΞϧλΠϜʹऔಘ • ํ๏3:

    ARKit͔Βऔಘ
  42. ΞδΣϯμ • ਂ౓ͷछྨͱηϯαͷ͘͠Έ • ਂ౓σʔλΛऔಘ͢Δ • ਂ౓σʔλΛ࢖ͬͯΈΔ • Ͱ͖Δ͜ͱɾͰ͖ͳ͍͜ͱࣄྫू

  43. ਂ౓σʔλΛ࢖ͬͯΈΔ ਂ౓σʔλͰഎܠ߹੒

  44. None
  45. എܠ߹੒ͷख๏ ϚεΫը૾Λج४ʹɺΦϦδφϧը૾ͱഎܠը૾ΛϒϨϯυ͢ Δ • ΫϩϚΩʔ߹੒͸ɺϚεΫͷ୅ΘΓʹchromaʢ࠼౓ʣΛར ༻

  46. CIBlendWithMask Parameters inputImage ೖྗը૾ inputBackgroundImage എܠը૾ inputMaskImage ϚεΫը૾ • ೖྗը૾͕ἧ͍ͬͯ͑͞Ε͹͜ΕΛ࢖͏͚ͩʂ

    • CIFilter͸MetalύΠϓϥΠϯͰ΋ॲཧͰ͖Δ
  47. ϚεΫͱͯ͠ਂ౓Λ༻͍Ε͹OK!?

  48. ࣮૷ • ϑϩϯτΧϝϥ͔ΒϦΞϧλΠϜʹਂ౓Λऔಘ • CIFilterͷCIBlendWithMaskͰϒϨϯυ • MetalͰϨϯμϦϯάɺMTKViewʹඳը

  49. ݁ՌʢσϞʣ

  50. None
  51. Կ͕ى͖͍ͯΔͷ͔ʁ

  52. ਂ౓ΛՄࢹԽͯ͠ΈΔ

  53. ໰୊఺ͦͷ̍ɿ നͱࠇ͕൓ର • ϚεΫ͸ɺΦϦδφϧ෦෼͕നͰ͋ Δ΂͖

  54. ըૉ஋Λ൓సʢന˱ࠇʣͤ͞Ε͹Α͍ʁ

  55. ໰୊఺ͦͷ̎ɿ إ͕άϨʔͷ·· • ׬શʹനͰͳ͍ͱɺഎܠ͕ϒϨϯυ ͞Εͯ͠·͏

  56. ରࡦɿ إͷਂ౓Λ͖͍͠஋ʹɺਂ౓ ϚοϓΛ2஋Խ͢Δ • AVCaptureMetadataOutputͰإΛೝ ࣝ • إͷத৺ͷਂ౓+offsetΛ͖͍͠஋ ʢcutOffʣͱ͢Δ •

    ਂ౓Ϛοϓʹ͓͍ͯɺ • ਂ౓͕cutOffҎ্Ͱ͋Ε͹ࠇ • ਂ౓͕cutOffҎԼͰ͋Ε͹ന
  57. ݁ՌʢσϞʣ

  58. None
  59. ͦͷଞͷ໰୊఺ • ڥք͕ΪβΪβ • ϝΨω͕എܠʹɾɾɾ"Holes"

  60. ରࡦɿ • ΪβΪβɾɾɾεϜʔδϯά͢Δ • HolesɾɾɾRGBΛར༻ͯ͠ຒΊΔ

  61. isFilteringEnabled • AVCaptureDepthDataOutputͷϓϩύςΟ • ۭؒํ޲͚ͩͰͳ͘ɺ࣌ܥྻํ޲ʹ΋εϜʔδϯά • "Holes"΋ຒΊͯ͘ΕΔʢRGBΛར༻ʣ

  62. None
  63. ݁ՌʢσϞʣ

  64. ׬੒ʂ

  65. ඍົʁ • ൅ͷໟͷ·ΘΓ • إͷਂ౓Λج४ʹ͖͍͠஋Λઃఆ͠ ͍ͯΔɾɾɾ൚༻ੑʹ͚ܽΔ

  66. Portrait Matte

  67. Portrait Matteͱ͸ʁ • എܠͱલܠͷ෼཭ʢηάϝϯςʔγϣϯʣʹಛԽͨ͠ϑΥʔ Ϛοτ • iOS 12͔ΒऔಘՄೳʹͳͬͨ

  68. ैདྷͷਂ౓ϚοϓʢࠨʣͱPortrait Matteʢӈʣ

  69. ൅ͷໟ΋͖Ε͍ʹ෼཭

  70. औಘํ๏ • લड़ͷCGImageSourceΛར༻͢Δํ๏ͱ΄΅ಉ͡ • λΠϓͱͯ͠ ʙPortraitEffectsMatte Λࢦఆ͢Δ • AVDapthData ͷ୅ΘΓʹ

    AVPortraitEffectsMatte
  71. guard let info = CGImageSourceCopyAuxiliaryDataInfoAtIndex( self, 0, kCGImageAuxiliaryDataTypePortraitEffectsMatte ) as?

    [String : AnyObject] else { return } let matte = AVPortraitEffectsMatte(fromDictionaryRepresentation: info)
  72. None
  73. Portrait Matteͷ੍໿ • ੩ࢭըͷΈ • ਓ͕ө͍ͬͯΔ৔߹ͷΈ • iOS 12Ҏ্

  74. ΞδΣϯμ • ਂ౓ͷछྨͱηϯαͷ͘͠Έ • ਂ౓σʔλΛऔಘ͢Δ • ਂ౓σʔλΛ࢖ͬͯΈΔ • Ͱ͖Δ͜ͱɾͰ͖ͳ͍͜ͱࣄྫू

  75. Ͳ͏͍͏έʔεͰɺԿ͕Ͱ͖ͯԿ͕Ͱ͖ͳ͍ͷ͔ ೺Ѳͮ͠Β͍ • ࡱӨࡁΈࣸਅ͔Β / ϦΞϧλΠϜ / ARKit • Dual

    / TrueDepth / ͦΕҎ֎ • ϑϩϯτ / ϦΞ • iOS 12 / 11 / ͦΕҎԼ • ର৅͕إ / શ਎ / ෺ମ
  76. ۩ମతͳࣄྫͰઆ໌ͯ͠Έ·͢

  77. ʮ͜ΕͰ΋͏੾Γൈ͖࡞ۀ͸Photoshop͍Βͣ ͩʂʯ • ର৅ը૾ʹਂ౓σʔλ͕ೖ͍ͬͯΔඞཁ͕͋Δ • Portrait Matteͷ඼࣭Λظ଴͢ΔͳΒɺਓ͕ؒࣸͬͯͳ͍ͱ͍ ͚ͳ͍

  78. ʮ෦԰͕ࢄΒ͔ͬͯͯ΋ϏσΦձٞͰ͖Δʂʯ • Portrait Matte͸ϦΞϧλΠϜͰ͸ར༻Ͱ͖ͳ͍ • Ͱ΋ϑϩϯτΧϝϥͰਓؒͷإΛத৺ʹࡱӨ͢ΔͷͰɺී௨ ͷਂ౓ϕʔεͰ΋ͦΕͳΓʹ͍͚ͦ͏

  79. ʮϑϦϚΞϓϦͰग़඼࣌ʹࣗಈͰഎܠΛඈ͹ͤΔ ػೳΛೖΕΑ͏ʯ • ਓҎ֎ͷʮϞϊʯ͸Portrait Matte͸औΕͳ͍ • Disprityϕʔεͷਂ౓͸ͱΕΔ • ͦͷʮϞϊʯͷਂ౓ͷ͖͍͠஋͸Ͳ͏΍ܾͬͯΊΔʁ •

    ϑΝογϣϯ౳ʹݶఆ͢Ε͹ྑͦ͞͏
  80. ʮARKitͷΦΫϧʔδϣϯ͕͜ΕͰͰ ͖Δʂʯ • ϑϩϯτɾɾɾOK • ϦΞɾɾɾNG • ARFaceTrackingConfiguration࢖༻࣌ͷΈ༗ޮ • എ໘ΧϝϥΛ࢖͏ίϯϑΟΪϡϨʔγϣϯʢྫɿ

    ARWorldTrackingʙʣͰ͸ capturedDepth ͕ nil
  81. ·ͱΊ • ਂ౓͸ʢࣸਅͷϘέҎ֎ʹ΋ʣൃ૝࣍ୈͰ͍Ζ͍Ζͱ࢖͑Δ • ਂ౓͸Ͳ͏΍ͬͯܭଌ͢Δͷ͔ʁ • ਂ౓σʔλɺͲ͏΍ͬͯ࢖͏ͷ͔ʁ • Կ͕Ͱ͖ͯɺԿ͕Ͱ͖ͳ͍ͷ͔ʁ

  82. ͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ʂ • Twitter: https://twitter.com/shu223 • GitHub: https://github.com/shu223 • ϒϩά: http://shu223.hatenablog.com/

  83. ิ଍༻ࢿྉ

  84. AVCaptureDataOutputSynchronizer

  85. // ϏσΦग़ྗͱਂ౓ग़ྗΛಉظ synchronizer = AVCaptureDataOutputSynchronizer( dataOutputs: [videoOutput, depthOutput])

  86. ಉظͨ͠ग़ྗΛड͚औΔ AVCaptureDataOutputSynchronizerDelegate didOutputσϦήʔτϝιου͔Β AVCaptureSynchronizedDataCollectionΦϒδΣΫτ͕ಘΒΕ Δ • → AVCaptureSynchronizedDepthData • →

    AVDepthData
  87. // ਂ౓σʔλ͕AVCaptureSynchronizedDepthDataܕͰऔΓग़ͤΔ if let syncedDepthData = synchronizedDataCollection.synchronizedData(for: depthOutput) as? AVCaptureSynchronizedDepthData,

    !syncedDepthData.depthDataWasDropped { // AVDepthDataΦϒδΣΫτΛऔಘ let depthData = syncedDepthData.depthData ... }
  88. ਂ౓σʔλΛ࢖ͬͯΈΔ MetalͰࣸਅΛ3DϚοϐ ϯά

  89. Processed by Focos

  90. • ௖఺γΣʔμ • ਂ౓σʔλΛz࠲ඪʹ • ϑϥάϝϯτγΣʔμ • RGBΧϥʔΛద༻