📐

Vision標準で用意されている座標変換関数ライブラリ

2024/04/23に公開

Visionでは、左下原点を持つ0.0から1.0の正規化座標空間を使用する。

たとえばこれをCore Graphicsで扱うためにピクセル単位の座標に変換したい、といった座標変換が必要になるケースは多い。

で、そういう変換処理をいつも自前で書いてしまうのだが、そういえばVision標準で既に用意されてるのだったと思い出したので備忘録としてここに貼り付けておく。[1]

VNImageRectForNormalizedRect

正規化された CGRect をピクセル単位での CGRect に変換する。

@discussion Returns a rectangle in (possibly non-integral) image coordinates that is projected from a rectangle in a normalized coordinate space.

(正規化座標空間内の矩形を投影した(非積分の) 画像座標内の矩形を返します。)

/**
    @param    normalizedRect    The rectangle in the normalized coordinate space of [0..1].
    @param    imageWidth        The pixel width of the image.
    @param    imageHeight       The pixel height of the image.
    @return the rectangle in pixel coordinates.
*/
@available(iOS 11.0, *)
public func VNImageRectForNormalizedRect(_ normalizedRect: CGRect, _ imageWidth: Int, _ imageHeight: Int) -> CGRect

たとえばこれは物体検出・トラッキング系でこんな感じで使う:

let imageRect = VNImageRectForNormalizedRect(bestResult.boundingBox, 
                     imageSize.width, 
                     imageSize.height)

ただし、この関数は原点の変換はやってくれない。Visionの座標系に則った左下原点のまま。つまりこの imageRectorigin は矩形の左下の座標を表している。

これを補正するには、たとえば次のようにY座標を反転するextensionを書いておき、

extension CGRect {
    var flipped: CGRect {
        return CGRect(x: origin.x,
                      y: 1 - origin.y - height,
                      width: width, height: height)
    }
}

反転させたものを VNImageRectForNormalizedRect で変換する。

let imageRect = VNImageRectForNormalizedRect(bestResult.boundingBox.flipped, 
                     imageSize.width, 
                     imageSize.height)

本関数は拙作OSSである MLModelCamera でも使用している:

https://github.com/shu223/MLModelCamera

VNNormalizedRectForImageRect

上の逆バージョン。

@discussion Returns an image rectangle in normalized coordinates.

(画像の矩形を正規化座標で返します。)

/**
    @param    imageRect        The rectangle in image coordinate space.   
    @param    imageWidth       The pixel width of the image.
    @param    imageHeight      The pixel height of the image.
    @return the normalized rectangle.
*/
@available(iOS 11.0, *)
public func VNNormalizedRectForImageRect(_ imageRect: CGRect, _ imageWidth: Int, _ imageHeight: Int) -> CGRect

画像上で検出した矩形をVisionの正規化座標に戻したい場合に有用。

VNImagePointForNormalizedPoint

正規化された座標をピクセル単位での座標に変換する。

@discussion Returns a point in (possibly non-integral) image coordinates that is projected from a point in a normalized coordinate space.

(正規化座標空間内の点から投影された(非積分の可能性のある)画像座標内の点を返 します。)

/**
    @param    normalizedPoint   The point in the normalized coordinate space of [0..1].
    @param    imageWidth        The pixel width of the image.
    @param    imageHeight       The pixel height of the image.
    @return the point in normalized coordinates.
*/
@available(iOS 11.0, *)
public func VNImagePointForNormalizedPoint(_ normalizedPoint: CGPoint, _ imageWidth: Int, _ imageHeight: Int) -> CGPoint

Visionで検出したランドマークや特徴点をUIKit座標系上で描画したい際に、正規化された点座標を実画素座標に戻すといった使い方ができる。

VNNormalizedFaceBoundingBoxPointForLandmarkPoint

@discussion Returns the cooridnate of a given face landmark point relative to a face bounding box.
(指定された顔のランドマーク点の、顔のバウンディングボックスに対する相対座標を返します。)

/**
    @param    faceLandmarkPoint  A face landmark point obtained from a VNFaceLandmarkRegion2D instance.
    @param    faceBoundingBox    The normalized bounding box of a face obtaining from a VNFaceObservation.
    @param    imageWidth         The pixel width of the image from which the VNFaceObservation was generated.
    @param    imageHeight        The pixel height of the image from which the VNFaceObservation was generated.
    @return    the face landmark point in face bounding box coordinates.
*/
@available(iOS 11.0, *)
public func VNNormalizedFaceBoundingBoxPointForLandmarkPoint(_ faceLandmarkPoint: vector_float2, _ faceBoundingBox: CGRect, _ imageWidth: Int, _ imageHeight: Int) -> CGPoint

顔検出後に特定の特徴点(目や口など)を画像上にプロットする際、顔領域内での相対位置が欲しい場合に有用。

VNImagePointForFaceLandmarkPoint

@discussion Returns the (possibly non-integral) image cooridnate of a given face landmark point.

(与えられた顔ランドマーク点の(おそらく非整数)画像座標を返します。)

/**
    @param    faceLandmarkPoint  A face landmark point obtained from a VNFaceLandmarkRegion2D instance.
    @param    faceBoundingBox    The normalized bounding box of a face obtaining from a VNFaceObservation.
    @param    imageWidth         The pixel width of the image from which the VNFaceObservation was generated.
    @param    imageHeight        The pixel height of the image from which the VNFaceObservation was generated.
    @return    the face landmark point in image coordinates.
*/
@available(iOS 11.0, *)
public func VNImagePointForFaceLandmarkPoint(_ faceLandmarkPoint: vector_float2, _ faceBoundingBox: CGRect, _ imageWidth: Int, _ imageHeight: Int) -> CGPoint

顔検出後に特定の特徴点(目や口など)を画像上にプロットする際、画像全体の座標系における位置が必要な場合に有用。

VNNormalizedIdentityRect

{ {0, 0}, {1, 1} }CGRect を返す。

/**
    @brief    The normalized identity rect of { {0, 0}, {1, 1} }.
*/
@available(iOS 11.0, *)
public let VNNormalizedIdentityRect: CGRect

VNNormalizedRectIsIdentityRect

{ {0, 0}, {1, 1} }CGRect かどうかを判定する。

@discussion Determines whether or not the normalized rect describes the identity rect of { {0, 0}, {1, 1} }.

(正規化された矩形が、 {0, 0}, {1, 1} } の同一矩形を記述 し ているかどうかを決定し ます。)

/**
    @param    normalizedRect        The rectangle in the normalized coordinate space of [0..1].
    @return YES if the rect is the identity rect; otherwise, NO.
*/
@available(iOS 11.0, *)
public func VNNormalizedRectIsIdentityRect(_ normalizedRect: CGRect) -> Bool

VNElementTypeSize

Feature Print 要素のサイズを返す。

/**
    @brief Obtain the size, in bytes, of a given element type.

    @param    elementType        The element type.
    @return a byte count, or 0 if the element type is unknown.
*/
@available(iOS 13.0, *)
public func VNElementTypeSize(_ elementType: VNElementType) -> Int

Feature Printとは

Feature PrintはVisionが特徴抽出時に用いるデータのこと。詳細はこちら:

https://zenn.dev/shu223/articles/vision_image-feature-print

脚注
  1. 本記事はnoteマガジンに2020年3月6日に書いた記事をベースにリライトしたものです。(2024.12.16 修正・追記しました) ↩︎

Discussion