Merge pull request #4538 from priankakariatyml:ios-segmentation-mask
PiperOrigin-RevId: 541944396
This commit is contained in:
		
						commit
						bd3a8d885d
					
				| 
						 | 
					@ -64,3 +64,17 @@ objc_library(
 | 
				
			||||||
        "@com_google_absl//absl/status:statusor",
 | 
					        "@com_google_absl//absl/status:statusor",
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					objc_library(
 | 
				
			||||||
 | 
					    name = "MPPMask",
 | 
				
			||||||
 | 
					    srcs = ["sources/MPPMask.mm"],
 | 
				
			||||||
 | 
					    hdrs = ["sources/MPPMask.h"],
 | 
				
			||||||
 | 
					    copts = [
 | 
				
			||||||
 | 
					        "-ObjC++",
 | 
				
			||||||
 | 
					        "-std=c++17",
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    deps = [
 | 
				
			||||||
 | 
					        "//mediapipe/tasks/ios/common:MPPCommon",
 | 
				
			||||||
 | 
					        "//mediapipe/tasks/ios/common/utils:MPPCommonUtils",
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										118
									
								
								mediapipe/tasks/ios/vision/core/sources/MPPMask.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								mediapipe/tasks/ios/vision/core/sources/MPPMask.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,118 @@
 | 
				
			||||||
 | 
					// Copyright 2023 The MediaPipe Authors.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//      http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#import <Foundation/Foundation.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NS_ASSUME_NONNULL_BEGIN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** The underlying type of the segmentation mask. */
 | 
				
			||||||
 | 
					typedef NS_ENUM(NSUInteger, MPPMaskDataType) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** Represents the native `UInt8 *` type. */
 | 
				
			||||||
 | 
					  MPPMaskDataTypeUInt8,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** Represents the native `float *` type. */
 | 
				
			||||||
 | 
					  MPPMaskDataTypeFloat32,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} NS_SWIFT_NAME(MaskDataType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * The wrapper class for MediaPipe segmentation masks.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Masks are stored as `UInt8 *` or `float *` objects.
 | 
				
			||||||
 | 
					 * Every mask has an underlying type which can be accessed using `dataType`. You can access the
 | 
				
			||||||
 | 
					 * mask as any other type using the appropriate properties. For example, if the underlying type is
 | 
				
			||||||
 | 
					 * `MPPMaskDataTypeUInt8`, in addition to accessing the mask using `uint8Data`, you can access
 | 
				
			||||||
 | 
					 * `float32Data` to get the 32 bit float data (with values ranging from 0.0 to 1.0). The first
 | 
				
			||||||
 | 
					 * time you access the data as a type different from the underlying type, an expensive type
 | 
				
			||||||
 | 
					 * conversion is performed. Subsequent accesses return a pointer to the memory location fo the same
 | 
				
			||||||
 | 
					 * type converted array. As type conversions can be expensive, it is recommended to limit the
 | 
				
			||||||
 | 
					 * accesses to data of types different from the underlying type.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Masks that are returned from a MediaPipe Tasks are owned by by the underlying C++ Task. If you
 | 
				
			||||||
 | 
					 * need to extend the lifetime of these objects, you can invoke the `[MPPMask copy:]` method.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NS_SWIFT_NAME(Mask)
 | 
				
			||||||
 | 
					@interface MPPMask : NSObject <NSCopying>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** The width of the mask. */
 | 
				
			||||||
 | 
					@property(nonatomic, readonly) NSInteger width;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** The height of the mask. */
 | 
				
			||||||
 | 
					@property(nonatomic, readonly) NSInteger height;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** The data type of the mask. */
 | 
				
			||||||
 | 
					@property(nonatomic, readonly) MPPMaskDataType dataType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * The pointer to the memory location where the underlying mask as a single channel `UInt8` array is
 | 
				
			||||||
 | 
					 * stored. Uint8 values use the full value range and range from 0 to 255.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					@property(nonatomic, readonly, assign) const UInt8 *uint8Data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * The pointer to the memory location where the underlying mask as a single channel float 32 array
 | 
				
			||||||
 | 
					 * is stored. Float values range from 0.0 to 1.0.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					@property(nonatomic, readonly, assign) const float *float32Data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Initializes an `MPPMask` object of type `MPPMaskDataTypeUInt8` with the given `UInt8*` data,
 | 
				
			||||||
 | 
					 * width and height.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * If `shouldCopy` is set to `YES`, the newly created `MPPMask` stores a reference to a deep copied
 | 
				
			||||||
 | 
					 * `uint8Data`. Since deep copies are expensive, it is recommended to not set `shouldCopy` unless
 | 
				
			||||||
 | 
					 * the `MPPMask` must outlive the passed in `uint8Data`.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param uint8Data A pointer to the memory location of the `UInt8` data array.
 | 
				
			||||||
 | 
					 * @param width The width of the mask.
 | 
				
			||||||
 | 
					 * @param height The height of the mask.
 | 
				
			||||||
 | 
					 * @param shouldCopy The height of the mask.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return A new `MPPMask` instance with the given `UInt8*` data, width and height.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					- (nullable instancetype)initWithUInt8Data:(const UInt8 *)uint8Data
 | 
				
			||||||
 | 
					                                     width:(NSInteger)width
 | 
				
			||||||
 | 
					                                    height:(NSInteger)height
 | 
				
			||||||
 | 
					                                shouldCopy:(BOOL)shouldCopy NS_DESIGNATED_INITIALIZER;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Initializes an `MPPMask` object of type `MPPMaskDataTypeFloat32` with the given `float*` data,
 | 
				
			||||||
 | 
					 * width and height.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * If `shouldCopy` is set to `YES`, the newly created `MPPMask` stores a reference to a deep copied
 | 
				
			||||||
 | 
					 * `float32Data`. Since deep copies are expensive, it is recommended to not set `shouldCopy` unless
 | 
				
			||||||
 | 
					 * the `MPPMask` must outlive the passed in `float32Data`.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param float32Data A pointer to the memory location of the `float` data array.
 | 
				
			||||||
 | 
					 * @param width The width of the mask.
 | 
				
			||||||
 | 
					 * @param height The height of the mask.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return A new `MPPMask` instance with the given `float*` data, width and height.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					- (nullable instancetype)initWithFloat32Data:(const float *)float32Data
 | 
				
			||||||
 | 
					                                       width:(NSInteger)width
 | 
				
			||||||
 | 
					                                      height:(NSInteger)height
 | 
				
			||||||
 | 
					                                  shouldCopy:(BOOL)shouldCopy NS_DESIGNATED_INITIALIZER;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO: Add methods for CVPixelBuffer conversion.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Unavailable. */
 | 
				
			||||||
 | 
					- (instancetype)init NS_UNAVAILABLE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					+ (instancetype)new NS_UNAVAILABLE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NS_ASSUME_NONNULL_END
 | 
				
			||||||
							
								
								
									
										135
									
								
								mediapipe/tasks/ios/vision/core/sources/MPPMask.mm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								mediapipe/tasks/ios/vision/core/sources/MPPMask.mm
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,135 @@
 | 
				
			||||||
 | 
					// Copyright 2023 The MediaPipe Authors.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//      http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#import "mediapipe/tasks/ios/vision/core/sources/MPPMask.h"
 | 
				
			||||||
 | 
					#import "mediapipe/tasks/ios/common/sources/MPPCommon.h"
 | 
				
			||||||
 | 
					#import "mediapipe/tasks/ios/common/utils/sources/MPPCommonUtils.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@interface MPPMask () {
 | 
				
			||||||
 | 
					  const UInt8 *_uint8Data;
 | 
				
			||||||
 | 
					  const float *_float32Data;
 | 
				
			||||||
 | 
					  std::unique_ptr<UInt8[]> _uint8DataPtr;
 | 
				
			||||||
 | 
					  std::unique_ptr<float[]> _float32DataPtr;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					@end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@implementation MPPMask
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- (nullable instancetype)initWithUInt8Data:(const UInt8 *)uint8Data
 | 
				
			||||||
 | 
					                                     width:(NSInteger)width
 | 
				
			||||||
 | 
					                                    height:(NSInteger)height
 | 
				
			||||||
 | 
					                                shouldCopy:(BOOL)shouldCopy {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  self = [super init];
 | 
				
			||||||
 | 
					  if (self) {
 | 
				
			||||||
 | 
					    _width = width;
 | 
				
			||||||
 | 
					    _height = height;
 | 
				
			||||||
 | 
					    _dataType = MPPMaskDataTypeUInt8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (shouldCopy) {
 | 
				
			||||||
 | 
					      size_t length = _width * _height;
 | 
				
			||||||
 | 
					      _uint8DataPtr = std::unique_ptr<UInt8[]>(new UInt8[length]);
 | 
				
			||||||
 | 
					      _uint8Data = _uint8DataPtr.get();
 | 
				
			||||||
 | 
					      memcpy((UInt8 *)_uint8Data, uint8Data, length * sizeof(UInt8));
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      _uint8Data = uint8Data;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return self;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- (nullable instancetype)initWithFloat32Data:(const float *)float32Data
 | 
				
			||||||
 | 
					                                       width:(NSInteger)width
 | 
				
			||||||
 | 
					                                      height:(NSInteger)height
 | 
				
			||||||
 | 
					                                  shouldCopy:(BOOL)shouldCopy {
 | 
				
			||||||
 | 
					  self = [super init];
 | 
				
			||||||
 | 
					  if (self) {
 | 
				
			||||||
 | 
					    _width = width;
 | 
				
			||||||
 | 
					    _height = height;
 | 
				
			||||||
 | 
					    _dataType = MPPMaskDataTypeFloat32;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (shouldCopy) {
 | 
				
			||||||
 | 
					      size_t length = _width * _height;
 | 
				
			||||||
 | 
					      _float32DataPtr = std::unique_ptr<float[]>(new float[length]);
 | 
				
			||||||
 | 
					      _float32Data = _float32DataPtr.get();
 | 
				
			||||||
 | 
					      memcpy((float *)_float32Data, float32Data, length * sizeof(float));
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      _float32Data = float32Data;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return self;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- (const UInt8 *)uint8Data {
 | 
				
			||||||
 | 
					  switch (_dataType) {
 | 
				
			||||||
 | 
					    case MPPMaskDataTypeUInt8: {
 | 
				
			||||||
 | 
					      return _uint8Data;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    case MPPMaskDataTypeFloat32: {
 | 
				
			||||||
 | 
					      if (_uint8DataPtr) {
 | 
				
			||||||
 | 
					        return _uint8DataPtr.get();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      size_t length = _width * _height;
 | 
				
			||||||
 | 
					      _uint8DataPtr = std::unique_ptr<UInt8[]>(new UInt8[length]);
 | 
				
			||||||
 | 
					      UInt8 *data = _uint8DataPtr.get();
 | 
				
			||||||
 | 
					      for (int i = 0; i < length; i++) {
 | 
				
			||||||
 | 
					        data[i] = _float32Data[i] * 255;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      return data;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					      return NULL;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- (const float *)float32Data {
 | 
				
			||||||
 | 
					  switch (_dataType) {
 | 
				
			||||||
 | 
					    case MPPMaskDataTypeUInt8: {
 | 
				
			||||||
 | 
					      if (_float32DataPtr) {
 | 
				
			||||||
 | 
					        return _float32DataPtr.get();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      size_t length = _width * _height;
 | 
				
			||||||
 | 
					      _float32DataPtr = std::unique_ptr<float[]>(new float[length]);
 | 
				
			||||||
 | 
					      float *data = _float32DataPtr.get();
 | 
				
			||||||
 | 
					      for (int i = 0; i < length; i++) {
 | 
				
			||||||
 | 
					        data[i] = (float)_uint8Data[i] / 255;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      return data;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    case MPPMaskDataTypeFloat32: {
 | 
				
			||||||
 | 
					      return _float32Data;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					      return NULL;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- (id)copyWithZone:(NSZone *)zone {
 | 
				
			||||||
 | 
					  switch (_dataType) {
 | 
				
			||||||
 | 
					    case MPPMaskDataTypeUInt8:
 | 
				
			||||||
 | 
					      return [[MPPMask alloc] initWithUInt8Data:self.uint8Data
 | 
				
			||||||
 | 
					                                          width:self.width
 | 
				
			||||||
 | 
					                                         height:self.height
 | 
				
			||||||
 | 
					                                     shouldCopy:YES];
 | 
				
			||||||
 | 
					    case MPPMaskDataTypeFloat32:
 | 
				
			||||||
 | 
					      return [[MPPMask alloc] initWithFloat32Data:self.float32Data
 | 
				
			||||||
 | 
					                                            width:self.width
 | 
				
			||||||
 | 
					                                           height:self.height
 | 
				
			||||||
 | 
					                                       shouldCopy:YES];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@end
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user