1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 07:13:02 +04:00
Maxim Smolskiy ad560f69f4 Merge pull request #27704 from MaximSmolskiy:fix_checking_that_point_lies_inside_ellipse
Fix checking that point lies inside ellipse #27704

### Pull Request Readiness Checklist

Previous `check_pt_in_ellipse` implementation was incorrect. For points on ellipse `cv::norm(to_pt)` should be equal to `el_dist`.

I tested current implementation with following Python script:
```
import cv2
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Ellipse

def check_pt_in_ellipse(pt, el):
    center, axes, angle = ellipse
    to_pt = pt - center
    el_angle = angle * np.pi / 180
    to_pt_r_x = to_pt[0] * np.cos(-el_angle) - to_pt[1] * np.sin(-el_angle)
    to_pt_r_y = to_pt[0] * np.sin(-el_angle) + to_pt[1] * np.cos(-el_angle)
    pt_angle = np.arctan2(to_pt_r_y / axes[1], to_pt_r_x / axes[0])
    x_dist = 0.5 * axes[0] * np.cos(pt_angle)
    y_dist = 0.5 * axes[1] * np.sin(pt_angle)
    el_dist = np.sqrt(x_dist * x_dist + y_dist * y_dist)
    assert abs(np.linalg.norm(to_pt) - el_dist) < 1e-10

# TEST(Imgproc_FitEllipse_Issue_4515, accuracy) {
points = np.array([
    [327, 317],
    [328, 316],
    [329, 315],
    [330, 314],
    [331, 314],
    [332, 314],
    [333, 315],
    [333, 316],
    [333, 317],
    [333, 318],
    [333, 319],
    [333, 320],
])

ellipse = cv2.fitEllipseDirect(points)

center, axes, angle = ellipse

angle_rad = np.deg2rad(angle)
points_on_ellipse = []
for point_angle_deg in range(0, 360, 10):
    point_angle = np.deg2rad(point_angle_deg)
    point = np.array([0., 0.])
    point_x = axes[0] * 0.5 * np.cos(point_angle)
    point_y = axes[1] * 0.5 * np.sin(point_angle)
    point[0] = point_x * np.cos(angle_rad) - point_y * np.sin(angle_rad)
    point[1] = point_x * np.sin(angle_rad) + point_y * np.cos(angle_rad)
    point[0] += center[0]
    point[1] += center[1]
    points_on_ellipse.append(point)

points_on_ellipse = np.array(points_on_ellipse)

for point in points_on_ellipse:
    check_pt_in_ellipse(point, ellipse)

plt.figure(figsize=(8, 8))
plt.scatter(points[:, 0], points[:, 1], c='red', label='points')
plt.scatter(points_on_ellipse[:, 0], points_on_ellipse[:, 1], c='yellow', label='ellipse')
ellipse = Ellipse(xy=center, width=axes[0], height=axes[1], 
                  angle=angle, facecolor='none', edgecolor='b')
plt.gca().add_patch(ellipse)
plt.gca().set_aspect('equal')
plt.legend()
plt.show()
```

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [ ] There is a reference to the original bug report and related work
- [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake
2025-08-26 14:02:53 +03:00
2025-08-17 08:19:52 +09:00
2020-02-26 15:12:45 +03:00
2018-10-11 17:57:51 +00:00
2025-08-01 09:50:10 +03:00
2024-03-03 23:37:07 +05:30

OpenCV: Open Source Computer Vision Library

Resources

Contributing

Please read the contribution guidelines before starting work on a pull request.

Summary of the guidelines:

  • One pull request per issue;
  • Choose the right base branch;
  • Include tests and documentation;
  • Clean up "oops" commits before submitting;
  • Follow the coding style guide.

Additional Resources

S
Description
No description provided
Readme Apache-2.0 3.3 GiB
Languages
C++ 87.6%
C 3.1%
Python 2.9%
CMake 2%
Java 1.5%
Other 2.7%