Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 118 additions & 12 deletions cpp/FOCV_Function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -953,13 +953,18 @@ jsi::Object FOCV_Function::invoke(jsi::Runtime& runtime, const jsi::Value* argum
} break;
case hashString("drawContours", 12): {
auto img = args.asMatPtr(1);
auto contours = args.asMatVectorPtr(2);
auto contourIdx = args.asNumber(3);
auto color = args.asScalarPtr(4);
auto thickness = args.asNumber(5);
auto line_type = args.asNumber(6);

cv::drawContours(*img, *contours, contourIdx, *color, thickness, line_type);

if (args.isMatVector(2)) {
auto contours = args.asMatVectorPtr(2);
cv::drawContours(*img, *contours, contourIdx, *color, thickness, line_type);
} else {
auto contours = args.asPointVectorOfVectorsPtr(2);
cv::drawContours(*img, *contours, contourIdx, *color, thickness, line_type);
}
} break;
case hashString("drawMarker", 10): {
auto img = args.asMatPtr(1);
Expand Down Expand Up @@ -1000,11 +1005,16 @@ jsi::Object FOCV_Function::invoke(jsi::Runtime& runtime, const jsi::Value* argum
} break;
case hashString("fillPoly", 8): {
auto img = args.asMatPtr(1);
auto pts = args.asMatVectorPtr(2);
auto color = args.asScalarPtr(3);
auto line_type = args.asNumber(4);

cv::fillPoly(*img, *pts, *color, line_type);

if (args.isMatVector(2)) {
auto pts = args.asMatVectorPtr(2);
cv::fillPoly(*img, *pts, *color, line_type);
} else {
auto pts = args.asPointVectorOfVectorsPtr(2);
cv::fillPoly(*img, *pts, *color, line_type);
}
} break;
case hashString("line", 4): {
auto img = args.asMatPtr(1);
Expand All @@ -1018,13 +1028,18 @@ jsi::Object FOCV_Function::invoke(jsi::Runtime& runtime, const jsi::Value* argum
} break;
case hashString("polylines", 9): {
auto img = args.asMatPtr(1);
auto pts = args.asMatVectorPtr(2);
auto isClosed = args.asBool(3);
auto color = args.asScalarPtr(4);
auto thickness = args.asNumber(5);
auto line_type = args.asNumber(6);

cv::polylines(*img, *pts, isClosed, *color, thickness, line_type);

if (args.isMatVector(2)) {
auto pts = args.asMatVectorPtr(2);
cv::polylines(*img, *pts, isClosed, *color, thickness, line_type);
} else {
auto pts = args.asPointVectorOfVectorsPtr(2);
cv::polylines(*img, *pts, isClosed, *color, thickness, line_type);
}
} break;
case hashString("rectangle", 9): {
auto img = args.asMatPtr(1);
Expand Down Expand Up @@ -1062,12 +1077,40 @@ jsi::Object FOCV_Function::invoke(jsi::Runtime& runtime, const jsi::Value* argum
} break;
case hashString("goodFeaturesToTrack", 19): {
auto image = args.asMatPtr(1);
auto corners = args.asMatPtr(2);
auto maxCorners = args.asNumber(3);
auto qualityLevel = args.asNumber(4);
auto minDistance = args.asNumber(5);

cv::goodFeaturesToTrack(*image, *corners, maxCorners, qualityLevel, minDistance);
auto blockSize = count > 6 ? args.asNumber(6) : 3;
auto useHarrisDetector = count > 7 ? args.asBool(7) : false;
auto k = count > 8 ? args.asNumber(8) : 0.04;

if (args.isPoint2fVector(2)) {
auto corners = args.asPoint2fVectorPtr(2);
cv::goodFeaturesToTrack(
*image,
*corners,
maxCorners,
qualityLevel,
minDistance,
cv::noArray(),
blockSize,
useHarrisDetector,
k
);
} else {
auto corners = args.asMatPtr(2);
cv::goodFeaturesToTrack(
*image,
*corners,
maxCorners,
qualityLevel,
minDistance,
cv::noArray(),
blockSize,
useHarrisDetector,
k
);
}
} break;
case hashString("HoughCircles", 12): {
auto image = args.asMatPtr(1);
Expand Down Expand Up @@ -1494,6 +1537,17 @@ jsi::Object FOCV_Function::invoke(jsi::Runtime& runtime, const jsi::Value* argum
}

} break;
case hashString("fitEllipse", 10): {
cv::RotatedRect rect;

if (args.isMat(1)) {
rect = cv::fitEllipse(*args.asMatPtr(1));
} else {
rect = cv::fitEllipse(*args.asPointVectorPtr(1));
}

return FOCV_JsiObject::wrap(runtime, "rotated_rect", std::make_shared<cv::RotatedRect>(rect));
} break;
case hashString("fitLine", 7): {
auto points = args.asMatPtr(1);
auto line = args.asMatPtr(2);
Expand Down Expand Up @@ -1684,12 +1738,64 @@ jsi::Object FOCV_Function::invoke(jsi::Runtime& runtime, const jsi::Value* argum
return FOCV_JsiObject::wrap(runtime, "mat", std::make_shared<cv::Mat>(H));
} break;

case hashString("calcOpticalFlowPyrLK", 19): {
auto prevImg = args.asMatPtr(1);
auto nextImg = args.asMatPtr(2);
auto prevPts = args.asPoint2fVectorPtr(3);
auto nextPts = args.asPoint2fVectorPtr(4);
auto status = args.asMatPtr(5);
auto err = args.asMatPtr(6);
auto winSize = args.asSizePtr(7);
auto maxLevel = args.asNumber(8);
auto criteria = args.asTermCriteriaPtr(9);

cv::calcOpticalFlowPyrLK(
*prevImg,
*nextImg,
*prevPts,
*nextPts,
*status,
*err,
*winSize,
maxLevel,
*criteria
);
} break;

case hashString("estimateAffinePartial2D", 22): {
auto from = args.asPoint2fVectorPtr(1);
auto to = args.asPoint2fVectorPtr(2);
auto inliers = args.asMatPtr(3);
auto method = count > 4 ? static_cast<int>(args.asNumber(4)) : cv::RANSAC;
auto ransacReprojThreshold = count > 5 ? args.asNumber(5) : 3.0;
auto maxIters = count > 6 ? static_cast<size_t>(args.asNumber(6)) : 2000;
auto confidence = count > 7 ? args.asNumber(7) : 0.99;
auto refineIters = count > 8 ? static_cast<size_t>(args.asNumber(8)) : 10;

cv::Mat transform = cv::estimateAffinePartial2D(
*from,
*to,
*inliers,
method,
ransacReprojThreshold,
maxIters,
confidence,
refineIters
);

return FOCV_JsiObject::wrap(runtime, "mat", std::make_shared<cv::Mat>(transform));
} break;

// ================== END FEATURE MATCHING FUNCTIONS ==================
}
} catch (cv::Exception& e) {
std::string message(e.what());
std::cout << "Fast OpenCV Invoke Error: " << message << "\n";
throw std::runtime_error("Fast OpenCV Error: " + message);
} catch (std::exception& e) {
std::string message(e.what());
std::cout << "Fast OpenCV Invoke Error: " << message << "\n";
throw std::runtime_error("Fast OpenCV Error: " + message);
}

return value;
Expand Down
10 changes: 5 additions & 5 deletions docs/content/apidetails.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,11 @@ Represents a rotated rectangle.

**Properties:**
- `type`: `ObjectType.RotatedRect`
- `x`: `number`
- `y`: `number`
- `width`: `number`
- `height`: `number`
- `angle`: `number`
- `x`: `number` - center x coordinate
- `y`: `number` - center y coordinate
- `width`: `number` - full width of the rotated rectangle
- `height`: `number` - full height of the rotated rectangle
- `angle`: `number` - rotation angle in degrees

**Methods:**
- `release(): void`
Expand Down
82 changes: 80 additions & 2 deletions docs/content/availablefunctions.md
Original file line number Diff line number Diff line change
Expand Up @@ -1561,10 +1561,41 @@ Determines strong corners on an image

```js
OpenCV.goodFeaturesToTrack(image: Mat,
corners: Mat,
corners: Mat | Point2fVector,
maxCorners: number,
qualityLevel: number,
minDistance: number
minDistance: number,
blockSize?: number,
useHarrisDetector?: boolean,
k?: number
): void;
```

### calcOpticalFlowPyrLK

Calculates an optical flow for a sparse feature set using the iterative Lucas-Kanade method with pyramids

- name Function name.
- prevImg First 8-bit input image
- nextImg Second input image of the same size and type as prevImg
- prevPts Vector of 2D points for which the flow needs to be found
- nextPts Output vector of 2D points containing the calculated new positions of input features in the second image
- status Output status vector (1 if the flow for the corresponding feature has been found, otherwise 0)
- err Output vector of errors
- winSize Size of the search window at each pyramid level
- maxLevel 0-based maximal pyramid level number
- criteria Parameter specifying the termination criteria of the iterative search algorithm

```js
OpenCV.calcOpticalFlowPyrLK(prevImg: Mat,
nextImg: Mat,
prevPts: Point2fVector,
nextPts: Point2fVector,
status: Mat,
err: Mat,
winSize: Size,
maxLevel: number,
criteria: TermCriteria
): void;
```

Expand Down Expand Up @@ -1752,6 +1783,34 @@ OpenCV.findHomographyFromMatches(
): Mat;
```

### estimateAffinePartial2D

Computes an optimal limited affine transform (4 degrees of freedom) between two 2D point sets.

- from First input 2D point set
- to Second input 2D point set
- inliers Output inlier mask
- method Robust method (`cv::RANSAC` = 8 by default)
- ransacReprojThreshold Maximum reprojection error in pixels for inliers
- maxIters Maximum robust-method iterations
- confidence Confidence level between 0 and 1
- refineIters Maximum number of refinement iterations

Returns a 2x3 affine transform `Mat`, or an empty `Mat` on failure.

```js
OpenCV.estimateAffinePartial2D(
from: Point2fVector,
to: Point2fVector,
inliers: Mat,
method?: number,
ransacReprojThreshold?: number,
maxIters?: number,
confidence?: number,
refineIters?: number
): Mat;
```

## Imgproc – Image Filtering

### bilateralFilter
Expand Down Expand Up @@ -2370,6 +2429,25 @@ OpenCV.findContoursWithHierarchy(image: Mat,
): void;
```

### fitEllipse

Fits an ellipse around a set of 2D points.

- points Input 2D point set, stored in a Mat or PointVector. It should contain at least 5 points.
@returns the rotated rectangle in which the ellipse is inscribed. In this library, `x` and `y` are the ellipse center coordinates, while `width` and `height` are the full axis lengths.

```js
OpenCV.fitEllipse(points: Mat | PointVector): RotatedRect;
```

```js
const ellipse = OpenCV.fitEllipse(contour);

console.log(ellipse.x, ellipse.y); // center
console.log(ellipse.width, ellipse.height); // full axis lengths
console.log(ellipse.angle); // degrees
```

### fitLine

Fits a line to a 2D or 3D point set.
Expand Down
1 change: 1 addition & 0 deletions docs/content/examples/_meta.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export default {
realtimedetection: 'Real-time detection',
blur: 'Blur image on separated thread',
fitellipse: 'Fit ellipse to a contour',
};
Loading
Loading