Skip to content

Commit a755a61

Browse files
committed
Apply review suggestions
1 parent be4870d commit a755a61

File tree

5 files changed

+49
-16
lines changed

5 files changed

+49
-16
lines changed

docs/docs/04-typescript-api/02-computer-vision/InstanceSegmentationModule.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,15 @@ Use [`fromCustomConfig`](../../06-api-reference/classes/InstanceSegmentationModu
6060
- `postprocessorConfig` (optional) - Postprocessing settings (`applyNMS`).
6161
- `defaultConfidenceThreshold` (optional) - Default confidence threshold.
6262
- `defaultIouThreshold` (optional) - Default IoU threshold.
63-
- `availableInputSizes` and `defaultInputSize` (optional) - Supported input sizes and the default.
63+
- `availableInputSizes` and `defaultInputSize` - **Required** if your model supports multiple input sizes (i.e., exports multiple forward methods like `forward_384`, `forward_512`, `forward_640`). Both must be specified together or omitted together.
6464
- `onDownloadProgress` (optional) - Callback to track download progress.
6565

66+
:::tip
67+
If your model supports **multiple input sizes**, you must specify both `availableInputSizes` (an array of supported sizes) and `defaultInputSize` (the default size to use when no `inputSize` is provided in options). The model must expose separate methods named `forward_{inputSize}` for each size.
68+
69+
If your model supports only **one input size**, omit both fields and export a single `forward` method.
70+
:::
71+
6672
```typescript
6773
const MyLabels = { GRAPE_GREEN: 0, GRAPE_RED: 1, LEAF: 2 } as const;
6874

packages/react-native-executorch/common/rnexecutorch/data_processing/ImageProcessing.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,5 +249,13 @@ readImageToTensor(const std::string &path,
249249
}
250250
return {image_processing::getTensorFromMatrix(tensorDims, input), imageSize};
251251
}
252+
253+
cv::Mat applySigmoid(const cv::Mat &logits) {
254+
cv::Mat probMat;
255+
cv::exp(-logits, probMat);
256+
probMat = 255.0f / (1.0f + probMat);
257+
probMat.convertTo(probMat, CV_8UC1);
258+
return probMat;
259+
}
252260
} // namespace image_processing
253261
} // namespace rnexecutorch

packages/react-native-executorch/common/rnexecutorch/data_processing/ImageProcessing.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,10 @@ readImageToTensor(const std::string &path,
5454
bool maintainAspectRatio = false,
5555
std::optional<cv::Scalar> normMean = std::nullopt,
5656
std::optional<cv::Scalar> normStd = std::nullopt);
57+
/**
58+
* @brief Applies sigmoid activation to logits and converts to uint8 binary mask
59+
* @param logits Input matrix containing raw logits (pre-sigmoid)
60+
* @return 8-bit unsigned integer matrix with values scaled to [0, 255]
61+
*/
62+
cv::Mat applySigmoid(const cv::Mat &logits);
5763
} // namespace rnexecutorch::image_processing

packages/react-native-executorch/common/rnexecutorch/models/instance_segmentation/BaseInstanceSegmentation.cpp

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,15 @@ std::vector<types::Instance> BaseInstanceSegmentation::runInference(
5353
ensureMethodLoaded(methodName);
5454

5555
auto inputShapes = getAllInputShapes(methodName);
56-
modelInputShape_ = inputShapes[0];
56+
if (inputShapes.empty() || inputShapes[0].empty()) {
57+
throw RnExecutorchError(RnExecutorchErrorCode::UnexpectedNumInputs,
58+
"Method '" + methodName +
59+
"' has invalid input tensor shape.");
60+
}
5761

58-
cv::Size modelInputSize = getInputSize(methodName);
62+
modelInputShape_ = inputShapes[0];
63+
const auto &shape = modelInputShape_;
64+
cv::Size modelInputSize(shape[shape.size() - 1], shape[shape.size() - 2]);
5965
cv::Size originalSize(image.cols, image.rows);
6066

6167
cv::Mat preprocessed = preprocess(image);
@@ -156,14 +162,6 @@ cv::Rect BaseInstanceSegmentation::addPaddingToRect(const cv::Rect &rect,
156162
return cv::Rect(x1, y1, x2 - x1, y2 - y1);
157163
}
158164

159-
cv::Mat BaseInstanceSegmentation::applySigmoid(const cv::Mat &logits) {
160-
cv::Mat probMat;
161-
cv::exp(-logits, probMat);
162-
probMat = 255.0f / (1.0f + probMat);
163-
probMat.convertTo(probMat, CV_8UC1);
164-
return probMat;
165-
}
166-
167165
cv::Mat BaseInstanceSegmentation::warpToOriginalResolution(
168166
const cv::Mat &probMat, const cv::Rect &maskRect, cv::Size originalSize,
169167
cv::Size maskSize, const utils::computer_vision::BBox &bboxOriginal) {
@@ -202,7 +200,7 @@ cv::Mat BaseInstanceSegmentation::processMaskFromLogits(
202200
}
203201

204202
cv::Mat cropped = logitsMat(cropRect);
205-
cv::Mat probMat = applySigmoid(cropped);
203+
cv::Mat probMat = image_processing::applySigmoid(cropped);
206204

207205
if (warpToOriginal) {
208206
probMat = warpToOriginalResolution(probMat, cropRect, originalSize,
@@ -260,13 +258,30 @@ void BaseInstanceSegmentation::ensureMethodLoaded(
260258
module_->unload_method(currentlyLoadedMethod_);
261259
}
262260
currentlyLoadedMethod_ = methodName;
263-
module_->load_method(methodName);
261+
auto loadResult = module_->load_method(methodName);
262+
if (loadResult != executorch::runtime::Error::Ok) {
263+
throw RnExecutorchError(
264+
loadResult, "Failed to load method '" + methodName +
265+
"'. Ensure the method exists in the exported model.");
266+
}
264267
}
265268
}
266269

267270
cv::Size BaseInstanceSegmentation::getInputSize(const std::string &methodName) {
268271
auto inputShapes = getAllInputShapes(methodName);
269-
std::vector<int32_t> inputShape = inputShapes[0];
272+
if (inputShapes.empty()) {
273+
throw RnExecutorchError(RnExecutorchErrorCode::UnexpectedNumInputs,
274+
"Method '" + methodName +
275+
"' has no input tensors.");
276+
}
277+
278+
const auto &inputShape = inputShapes[0];
279+
if (inputShape.empty()) {
280+
throw RnExecutorchError(RnExecutorchErrorCode::UnexpectedNumInputs,
281+
"Method '" + methodName +
282+
"' input tensor has no dimensions.");
283+
}
284+
270285
int32_t inputSize = inputShape[inputShape.size() - 1];
271286
return cv::Size(inputSize, inputSize);
272287
}

packages/react-native-executorch/common/rnexecutorch/models/instance_segmentation/BaseInstanceSegmentation.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,6 @@ class BaseInstanceSegmentation : public VisionModel {
8080

8181
cv::Rect addPaddingToRect(const cv::Rect &rect, cv::Size maskSize);
8282

83-
cv::Mat applySigmoid(const cv::Mat &logits);
84-
8583
cv::Mat
8684
warpToOriginalResolution(const cv::Mat &probMat, const cv::Rect &maskRect,
8785
cv::Size originalSize, cv::Size maskSize,

0 commit comments

Comments
 (0)