View in English

  • メニューを開く メニューを閉じる
  • Apple Developer
検索
検索を終了
  • Apple Developer
  • ニュース
  • 見つける
  • デザイン
  • 開発
  • 配信
  • サポート
  • アカウント
次の内容に検索結果を絞り込む

クイックリンク

5 クイックリンク

ビデオ

メニューを開く メニューを閉じる
  • コレクション
  • トピック
  • すべてのビデオ
  • 利用方法

WWDC25に戻る

  • 概要
  • トランスクリプト
  • コード
  • Visionフレームワークによるドキュメントの読み込み

    Visionフレームワークの最新機能を紹介します。RecognizeDocumentsRequestの概要と、この要素をテキスト行の読み取りとパラグラフへのグループ化、表の読み込みなどに使用する方法を説明します。また、カメラレンズの汚れ検出や、写真ライブラリやカメラキャプチャパイプラインの画像の潜在的な汚れを識別する方法についても詳しく解説します。

    関連する章

    • 0:00 - イントロダクション
    • 1:22 - ドキュメントの読み取り
    • 13:35 - カメラレンズの汚れ検出
    • 17:59 - 手の形に関するアップデート

    リソース

    • Classifying Images with Vision and Core ML
    • Image Classification with Vision and CoreML
    • Recognizing tables within a document
    • Vision
      • HDビデオ
      • SDビデオ

    関連ビデオ

    WWDC25

    • Appleプラットフォームでの機械学習/AIフレームワーク

    WWDC24

    • VisionフレームワークにおけるSwiftの機能強化

    WWDC23

    • Visionで動物のポーズを検出
    • Visionの3Dボディーポーズと人物セグメンテーションの詳細
  • このビデオを検索

    こんにちは Megan Williamsです Visionフレームワークチームのエンジニアです Visionは 人物検出やオブジェクト検出 全身や手のポーズ追跡軌道分析などを始めとして 様々なユースケースに向けた機械学習機能を アプリに 簡単に導入できるAPIを提供します

    ちなみに Vision APIはすべてデバイス上で実行され アプリ内で コンピュータビジョンタスクを最高のパフォーマンスで安全に実行します

    AppleのAPIは iOS、macOS、iPadOStvOS、visionOSで利用できます

    Visionは 各種画像分析用に31のAPIを用意しています 本日 さらに2つが加わります このビデオでは ドキュメント読み取り用とカメラレンズの汚れ検出用の 新しいAPIをご紹介します 最後に 手のポーズ検出機能のアップデート内容を説明します

    では始めましょう

    Visionは現在 RecognizeTextRequestで画像からテキスト行を正確に検出して 抽出する機能を提供しています 確かに優れた機能ですがさらに多くの情報を抽出できるような 高度に構造化されたドキュメントも存在します

    例えば このチラシにはタイトル、段落 リスト、表、バーコードがあります

    文書のテキストを読むだけなら 重要な構造情報は失われてしまいます 例えば この表でテキスト部分だけを抽出すると 行や列の配置具合の情報は失われてしまいます テキストの文面だけでなくフォーマットも知りたい時のために 今年 Visionに導入された新しいAPIはまさに打って付けの機能を提供します

    それが「RecognizeDocumentsRequest」 26の言語でのテキスト認識に対応しており デベロッパはこのAPIを使用してドキュメントから 構造要素や重要な情報を 抽出できます APIは テーブル、リスト段落を構成する行グループなどの

    構造を検出することができ

    QRコードなどの機械可読コードを検出し メールアドレス、電話番号、URLなどの重要な情報を識別します こうした機能によりドキュメントの理解度がアップし より短いコードで より簡単に解析できるようになります

    例えば 経営している店舗で来店したお客様に 毎月発行のニュースレターを申し込んでもらえるよう

    名前やメールアドレス電話番号を入力できる 購読申込書を作るとしましょう

    申込書をスキャンするアプリを作って一人ひとりの連絡先を作成します

    従来はRecognizeTextRequestで テキスト抽出し 各セルを個別のオブジェクトとして返していました

    一人分の連絡先を作成するにはどのセルが同じ行に属しているか テキストボックスの位置情報をもとに 特定する必要がありました

    これからはRecognizeDocumentsRequestが テーブルをペーストしてくれます セルは行ごとに自動でグループ化されるので 申込書の解析がはるかに簡単になります では APIの使い方を紹介します

    Recognize Documents Requestは他のリクエストと同じ操作感です Visionフレームワークの詳しい使用方法については WWDC 2024の「VisionフレームワークにおけるSwiftの機能強化」をご覧ください でも どうぞご安心を今からおさらいします

    Visionでは リクエストを利用して画像を処理します 実行する画像解析のタイプはリクエストによって決まります 画像に関するリクエストを実行すると Observation(観測値)が生成されます 例えば画像内で顔がある位置など 画像に関する情報を教えてくれます

    RecognizeDocumentsRequestはDocumentObservationを生成します

    DocumentObservationからはドキュメントの内容や 構造が分かります RecognizeDocumentsRequestを実行すると 現状では Visionが画像ごとにDocumentObservationを1つ返します DocumentObservationは階層構造になっていて 個々のドキュメントはコンテナとして テキスト、テーブル、リスト バーコードを保持します

    テーブルはセルで構成されリストは項目で構成され それ自体がコンテナとして テキストなど 他の要素を保持できます DocumentObservationについて紹介したところで 申込書を解析してみましょう

    まず ドキュメントからテーブル構造を抽出します

    ドキュメントの写真をiPadで撮影します

    アプリがRecognizeDocumentsRequestで テーブルを検出し 画面上に強調表示します

    コードを見てみましょう

    キャプチャしたばかりの画像からテーブルを抽出してみましょう まずはRecognizeDocumentsRequestを作成して 画像に関するリクエストを実行します DocumentObservationが返されます ドキュメントのTableプロパティにアクセスすると この画像のテーブルを抽出できます

    この場合 ドキュメントにはテーブルが1つだけと想定して 最初に検出したテーブル1つだけを返します

    テーブルの検出ができたので内容を見てみましょう

    テーブルは 2次元配列のセルで構成されています セルには 行からまたは列からアクセスできます

    テーブルの境界をboundingRegionとして定義し 画像に対するテーブルの座標を提供します 各テーブルセルには行や列への所属関係を示す プロパティがあります

    1つのセルは 複数の行や列に及ぶ場合があるので この値はRangeとして表現します

    セルの内容はContainerにあたり テキスト、テーブル、リスト、バーコードなどドキュメント内のコンテンツを保持します

    Containerは このほか固有のboundingRegionを収容します

    データをテーブルとして抽出したので 申込書を行単位で読めるようになりました

    テキストの抽出にあたって各セルの内容を確認します

    テキストを詳しく見てみましょう コンテナ内のテキストの表示方法は何通りかあります

    Transcriptはすべてのテキストを 1つの文字列として表示します Linesの場合は テキストを行の配列として表示します

    LinesをParagraphsにグループ化すれば実際の見え方に近い より自然なビューになります ある行が 段落グループに含まれない場合 それは 1行の段落とみなされます Wordsで単語レベルのリストも取得できますが 中国語、日本語韓国語、タイ語など 一部の言語はサポート対象外です

    最後に DetectedDataはメールアドレスや日付やURLなど テキスト内で検出される特殊文字列でドキュメント内の 重要な情報を表しています Visionは 新しいDataDetectionフレームワークにより 文字列をスキャンして重要なデータを取り出せます

    電話番号やメールアドレス郵便番号も 様々な書式の中から検出してくれます

    URLは Linkとして検出され日付と時間は CalendarEventとして検出されます

    測定値は単位とセットで検出され 金額や通貨の種類も同様です

    TrackingNumber、PaymentIdentifierFlightNumberも識別できます

    こうした機能をフルに活用してサンプルアプリを拡張してみましょう 検出済みのテーブルからテキストを抽出して 連絡先のリストを作成します 1番目の列には名前があります 次に データ検出機能を使って 他の列にある連絡先情報を識別します

    それでは サンプルコードを 更新しましょう 検出済みのテーブルを解析して連絡先のリストを生成します

    連絡先ごとに 名前、メールアドレスオプションで電話番号を収集します

    各行で同じ操作を繰り返し実行して 行ごとに連絡先を作成します

    申込書は通常最初の列が名前の欄なので 行頭のセルを取得します

    このセルのテキストから連絡先の氏名を取得します

    Transcriptで すべてのテキストを文字列として取得します

    この行にある 他の情報も取得していきます

    残りのセルで同じ処理を繰り返します

    各セルで検出したデータを確認できるようになりました

    他のデータも同様に処理して 検出結果を確認しましょう

    データの詳細表示に切り替えれば メールアドレスや電話番号などを確認できます

    メールアドレスが見つかった場合は検出情報をもとに連絡先を作成できます

    購読申込書から簡単に連絡先のリストが抽出できました

    リストをContactViewに渡すと 連絡先がアプリに表示されます 連絡先を見てみましょう

    上出来ですね

    テーブルを タブ区切りでエクスポートする機能も追加しました

    メモやNumbersなど互換性のあるアプリに テーブルをコピー&ペーストできます

    この機能のコードを確認したい方は AppleデベロッパWebサイトからサンプルアプリをダウンロードできます 要約すると RecognizeDocumentsRequestによって デベロッパは 重要な情報をドキュメントから簡単に抽出できるようになります

    APIは ドキュメント構造を把握できるシンプルなインターフェイスで テーブルなど フォーマット化されたテキストを 簡単に解析でき テキスト、メールアドレス、電話番号などの重要な情報も識別できます

    ここからは 今年Visionに加わったもう1つの新機能を紹介します

    カメラレンズの汚れ検出機能です

    デバイスを手に取って購読申込書をスキャンするとき ついうっかり レンズを指で汚すこともあるでしょう

    写真の画質が低下すると処理ができなくなってしまいます

    こんなとき 大活躍してくれるのがVisionの新機能です 「DetectLensSmudgeRequest」は 汚れたレンズで撮影された画像を識別して レンズの清掃や別の写真の提供をユーザに促すことができます このリクエストによってアプリ内で 高品質の画像だけを 処理できるようになります

    DetectLensSmudgeRequestはVisionの他のリクエストと同様に機能します 画像に対してリクエストを実行するとSmudgeObservationが生成されます

    観測値のConfidence(確信度)スコアは 画像が汚れている確率を伝えてくれます

    Confidenceは常に 0から1の範囲になります

    Confidenceが「1」に近い場合は画像に汚れがある可能性が高く

    「0」の場合は画像に汚れがない 可能性のほうが 高くなります コードで利用する方法を紹介します

    手元の画像に汚れがないか知りたいとします

    まず DetectLensSmudgeRequestを作成します

    次に 画像上でリクエストを実行します

    これで SmudgeObservationが生成されます

    観測値の確信度は画像汚れの確率を示します

    得られた確信度をしきい値と比較して 低品質の画像を除外します

    今回は「0.9」を選択しました

    スコアがしきい値を超える画像は汚れていると見なして 処理対象から外します

    しきい値はアプリに最適のものを選択できます 3つのドキュメントは 汚れの確信度スコアが異なります

    しきい値を上げれば画像処理数は多くなります ただし 画像の品質は低めになるでしょう

    しきい値を下げれば除外される数は増えます 時には誤検知によって高品質の画像も除外されるでしょう

    レンズ汚れのない画像なのに汚れのスコアが高く出る場合があります

    例えば この画像は手ブレのため あたかも汚れたレンズで撮影したような 画像になっています 露光時間が長い画像や雲や霧の画像などでも 同じことが言えます つまり 汚れのスコアが低いというだけでは 高品質の写真であるという保証にはならないのです 例えば この通気口の画像には汚れこそないものの 面白くもなければ視覚的な魅力もなく 友達と共有したいとは思えません 他にも DetectLens SmudgeRequestと組み合わせて 高品質の写真を検索できる APIが揃っています

    顔が写っている画像では「DetectFaceCaptureQualityRequest」で キャプチャ品質を上げられます このリクエストは 一人分ずつCaptureQualityScoreを生成して

    これも「0」から「1」のスコアで「1」に近ければ高品質のキャプチャです

    顔が含まれていない画像の場合は 「CalculateImageAestheticScores」で画像の全体的なスコアが得られます

    ユーティリティ画像も識別可能でドキュメントや領収書の画像など きれいに撮れているけれども記憶に残らない内容の 画像などを識別することができます リクエストの詳細についてはWWDC 2024の Visionに関するプレゼンテーションで 紹介しています

    ここで少し 手のポーズ検出機能の更新情報をお伝えします

    2020年以降 デベロッパは「DetectHandPoseRequest」で 手の関節21か所が特定可能になりました

    関節は HandPoseObservationとして返されます

    このテクノロジーは MLHandPoseClassifiersとHandActionClassifiersを強化して 手のポーズやジェスチャーの識別を可能にします

    例えば アプリ機能の操作に使うジェスチャーを認識するよう モデルをトレーニングできます HandPoseClassifierのトレーニング方法の詳細は WWDC21の「Create MLによる手のポーズや動作の識別」をご覧ください

    Visionは今年 手のポーズ検出用のモデルを よりコンパクトな 最新モデルに一新しました

    新しいモデルでも 21個の関節を検出しますが 精度は向上しています メモリ使用量とレイテンシーも削減できます 新しいモデルでは精度が向上しただけでなく 関節の位置も以前のモデルとは異なります ですから MLHandPoseClassifierやMLHandActionClassifierを すでにトレーニングしてある場合は 精度を向上させるためにも新しいモデルでの Classifierの再トレーニングをお勧めします

    今年登場予定の新機能をおさらいします 2つのリクエストを 新たに導入します 構造化された文書を把握するための「RecognizeDocumentsRequest」と 汚れたレンズで撮影された写真の識別を可能にする 「DetectCameraLensSmudgeRequest」です また 手のポーズ検出用のモデルもアップデートします

    ご紹介したサンプルアプリは AppleデベロッパWebサイトからダウンロードできます Visionが提供する多彩なAPIについて 詳しく紹介している WWDC24の「VisionフレームワークにおけるSwiftの機能強化」も ぜひご覧ください ご視聴ありがとうございました

    • 6:39 - Detect tables

      /// Process an image and return the first table detected
      func extractTable(from image: Data) async throws -> DocumentObservation.Container.Table {
          
          // The Vision request.
          let request = RecognizeDocumentsRequest()
          
          // Perform the request on the image data and return the results.
          let observations = try await request.perform(on: image)
      
          // Get the first observation from the array.
          guard let document = observations.first?.document else {
              throw AppError.noDocument
          }
          
          // Extract the first table detected.
          guard let table = document.tables.first else {
              throw AppError.noTable
          }
          
          return table
      }
    • 10:50 - Parse contacts

      /// Extract name, email addresses, and phone number from a table into a list of contacts.
      private func parseTable(_ table: DocumentObservation.Container.Table) -> [Contact] {
          var contacts = [Contact]()
          
          // Iterate over each row in the table.
          for row in table.rows {
              // The contact name will be taken from the first column.
              guard let firstCell = row.first else {
                  continue
              }
              // Extract the text content from the transcript.
              let name = firstCell.content.text.transcript
              
              // Look for emails and phone numbers in the remaining cells.
              var detectedPhone: String? = nil
              var detectedEmail: String? = nil
              
              for cell in row.dropFirst() {
                  // Get all detected data in the cell, then match emails and phone numbers.
                  let allDetectedData = cell.content.text.detectedData
                  for data in allDetectedData {
                      switch data.match.details {
                      case .emailAddress(let email):
                          detectedEmail = email.emailAddress
                      case .phoneNumber(let phoneNumber):
                          detectedPhone = phoneNumber.phoneNumber
                      default:
                          break
                      }
                  }
              }
              // Create a contact if an email was detected.
              if let email = detectedEmail {
                  let contact = Contact(name: name, email: email, phoneNumber: detectedPhone)
                  contacts.append(contact)
              }
          }
          return contacts
      }

Developer Footer

  • ビデオ
  • WWDC25
  • Visionフレームワークによるドキュメントの読み込み
  • メニューを開く メニューを閉じる
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    メニューを開く メニューを閉じる
    • アクセシビリティ
    • アクセサリ
    • App Extension
    • App Store
    • オーディオとビデオ(英語)
    • 拡張現実
    • デザイン
    • 配信
    • 教育
    • フォント(英語)
    • ゲーム
    • ヘルスケアとフィットネス
    • アプリ内課金
    • ローカリゼーション
    • マップと位置情報
    • 機械学習とAI
    • オープンソース(英語)
    • セキュリティ
    • SafariとWeb(英語)
    メニューを開く メニューを閉じる
    • 英語ドキュメント(完全版)
    • 日本語ドキュメント(一部トピック)
    • チュートリアル
    • ダウンロード(英語)
    • フォーラム(英語)
    • ビデオ
    Open Menu Close Menu
    • サポートドキュメント
    • お問い合わせ
    • バグ報告
    • システム状況(英語)
    メニューを開く メニューを閉じる
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles(英語)
    • フィードバックアシスタント
    メニューを開く メニューを閉じる
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program(英語)
    • News Partner Program(英語)
    • Video Partner Program(英語)
    • セキュリティ報奨金プログラム(英語)
    • Security Research Device Program(英語)
    Open Menu Close Menu
    • Appleに相談
    • Apple Developer Center
    • App Store Awards(英語)
    • Apple Design Awards
    • Apple Developer Academy(英語)
    • WWDC
    Apple Developerアプリを入手する
    Copyright © 2025 Apple Inc. All rights reserved.
    利用規約 プライバシーポリシー 契約とガイドライン