CARVIEW |
Select Language
HTTP/2 200
date: Sat, 26 Jul 2025 17:39:35 GMT
content-type: text/html; charset=utf-8
vary: X-PJAX, X-PJAX-Container, Turbo-Visit, Turbo-Frame, X-Requested-With,Accept-Encoding, Accept, X-Requested-With
x-repository-download: git clone https://github.com/opencv/opencv.git
etag: W/"402ead48af34d335691d47c1e58b5ed5"
cache-control: max-age=0, private, must-revalidate
strict-transport-security: max-age=31536000; includeSubdomains; preload
x-frame-options: deny
x-content-type-options: nosniff
x-xss-protection: 0
referrer-policy: no-referrer-when-downgrade
content-security-policy: default-src 'none'; base-uri 'self'; child-src github.githubassets.com github.com/assets-cdn/worker/ github.com/assets/ gist.github.com/assets-cdn/worker/; connect-src 'self' uploads.github.com www.githubstatus.com collector.github.com raw.githubusercontent.com api.github.com github-cloud.s3.amazonaws.com github-production-repository-file-5c1aeb.s3.amazonaws.com github-production-upload-manifest-file-7fdce7.s3.amazonaws.com github-production-user-asset-6210df.s3.amazonaws.com *.rel.tunnels.api.visualstudio.com wss://*.rel.tunnels.api.visualstudio.com objects-origin.githubusercontent.com copilot-proxy.githubusercontent.com proxy.individual.githubcopilot.com proxy.business.githubcopilot.com proxy.enterprise.githubcopilot.com *.actions.githubusercontent.com wss://*.actions.githubusercontent.com productionresultssa0.blob.core.windows.net/ productionresultssa1.blob.core.windows.net/ productionresultssa2.blob.core.windows.net/ productionresultssa3.blob.core.windows.net/ productionresultssa4.blob.core.windows.net/ productionresultssa5.blob.core.windows.net/ productionresultssa6.blob.core.windows.net/ productionresultssa7.blob.core.windows.net/ productionresultssa8.blob.core.windows.net/ productionresultssa9.blob.core.windows.net/ productionresultssa10.blob.core.windows.net/ productionresultssa11.blob.core.windows.net/ productionresultssa12.blob.core.windows.net/ productionresultssa13.blob.core.windows.net/ productionresultssa14.blob.core.windows.net/ productionresultssa15.blob.core.windows.net/ productionresultssa16.blob.core.windows.net/ productionresultssa17.blob.core.windows.net/ productionresultssa18.blob.core.windows.net/ productionresultssa19.blob.core.windows.net/ github-production-repository-image-32fea6.s3.amazonaws.com github-production-release-asset-2e65be.s3.amazonaws.com insights.github.com wss://alive.github.com api.githubcopilot.com api.individual.githubcopilot.com api.business.githubcopilot.com api.enterprise.githubcopilot.com; font-src github.githubassets.com; form-action 'self' github.com gist.github.com copilot-workspace.githubnext.com objects-origin.githubusercontent.com; frame-ancestors 'none'; frame-src viewscreen.githubusercontent.com notebooks.githubusercontent.com; img-src 'self' data: blob: github.githubassets.com media.githubusercontent.com camo.githubusercontent.com identicons.github.com avatars.githubusercontent.com private-avatars.githubusercontent.com github-cloud.s3.amazonaws.com objects.githubusercontent.com release-assets.githubusercontent.com secured-user-images.githubusercontent.com/ user-images.githubusercontent.com/ private-user-images.githubusercontent.com opengraph.githubassets.com copilotprodattachments.blob.core.windows.net/github-production-copilot-attachments/ github-production-user-asset-6210df.s3.amazonaws.com customer-stories-feed.github.com spotlights-feed.github.com objects-origin.githubusercontent.com *.githubusercontent.com; manifest-src 'self'; media-src github.com user-images.githubusercontent.com/ secured-user-images.githubusercontent.com/ private-user-images.githubusercontent.com github-production-user-asset-6210df.s3.amazonaws.com gist.github.com; script-src github.githubassets.com; style-src 'unsafe-inline' github.githubassets.com; upgrade-insecure-requests; worker-src github.githubassets.com github.com/assets-cdn/worker/ github.com/assets/ gist.github.com/assets-cdn/worker/
server: github.com
content-encoding: gzip
accept-ranges: bytes
set-cookie: _gh_sess=rrES%2Fgzlv5uIEgWXgiAcERDxb%2Bhb%2FPQ4ofMXWWwirfyFX3GeUN4HFETVg5hekeHARRnrfqP4rFv8ud%2BYlvSSX27dUqLuHsIdaGe7%2B%2Bau%2BJyAJXMfua1fBGab5JskI6IW8bbZERcwonHCldsdIXdWFp75Kotg5kzomezimzr0PgTLZ%2FPPDtyUDHZXEss1jqm8dcR5ocYEqSu7w9Oq7F3EQTzgOkdEDN3QIxEMVf%2FaiR3TFdO%2FWOxZwQe80Sgf%2BJPhdqsi7Ie4m60Vi9%2BKgBfUxw%3D%3D--GBeJNwN7sgtuMnJE--4hUGWVzulzHo6obe1ooW6Q%3D%3D; Path=/; HttpOnly; Secure; SameSite=Lax
set-cookie: _octo=GH1.1.1084155547.1753551574; Path=/; Domain=github.com; Expires=Sun, 26 Jul 2026 17:39:34 GMT; Secure; SameSite=Lax
set-cookie: logged_in=no; Path=/; Domain=github.com; Expires=Sun, 26 Jul 2026 17:39:34 GMT; HttpOnly; Secure; SameSite=Lax
x-github-request-id: 898C:15E61D:7109C6:8E7667:688512D6
Merge pull request #26299 from s-trinh:feat/getClosestEllipsePoints_2 · opencv/opencv@e258f25 · GitHub
Copy file name to clipboardExpand all lines: modules/imgproc/include/opencv2/imgproc.hpp
Copy file name to clipboardExpand all lines: modules/imgproc/src/shapedescr.cpp
Skip to content
Navigation Menu
{{ message }}
-
-
Notifications
You must be signed in to change notification settings - Fork 56.2k
Commit e258f25
authored
Merge pull request #26299 from s-trinh:feat/getClosestEllipsePoints_2
Add getClosestEllipsePoints() function to get the closest point on an ellipse #26299
Following #26078, I was thinking that a function to get for a considered 2d point the corresponding closest point (or maybe directly the distance?) on an ellipse could be useful.
This would allow computing the fitting error with `fitEllipse()` for instance.
Code is based from:
- https://stackoverflow.com/questions/22959698/distance-from-given-point-to-given-ellipse/46007540#46007540
- https://blog.chatfield.io/simple-method-for-distance-to-ellipse/
- https://github.com/0xfaded/ellipse_demo
---
Demo code:
<details>
<summary>code</summary>
```cpp
#include <iostream>
#include <opencv2/opencv.hpp>
namespace
{
void scaleApplyColormap(const cv::Mat &img_float, cv::Mat &img)
{
cv::Mat img_scale = cv::Mat::zeros(img_float.size(), CV_8UC3);
double min_val = 0, max_val = 0;
cv::minMaxLoc(img_float, &min_val, &max_val);
std::cout << "min_val=" << min_val << " ; max_val=" << max_val << std::endl;
if (max_val - min_val > 1e-2) {
float a = 255 / (max_val - min_val);
float b = -a * min_val;
cv::convertScaleAbs(img_float, img_scale, a, b);
cv::applyColorMap(img_scale, img, cv::COLORMAP_TURBO);
}
else {
std::cerr << "max_val - min_val <= 1e-2" << std::endl;
}
}
cv::Mat drawEllipseDistanceMap(const cv::RotatedRect &ellipse_params)
{
float bb_rect_w = ellipse_params.center.x + ellipse_params.size.width;
float bb_rect_h = ellipse_params.center.y + ellipse_params.size.height;
std::vector<cv::Point2f> points_list;
points_list.resize(1);
cv::Mat pointsf;
cv::Mat closest_pts;
cv::Mat dist_map = cv::Mat::zeros(bb_rect_h*1.5, bb_rect_w*1.5, CV_32F);
for (int i = 0; i < dist_map.rows; i++) {
for (int j = 0; j < dist_map.cols; j++) {
points_list[0].x = j;
points_list[0].y = i;
cv::Mat(points_list).convertTo(pointsf, CV_32F);
cv::getClosestEllipsePoints(ellipse_params, pointsf, closest_pts);
dist_map.at<float>(i, j) = std::hypot(closest_pts.at<cv::Point2f>(0).x-j, closest_pts.at<cv::Point2f>(0).y-i);
}
}
cv::Mat dist_map_8u;
scaleApplyColormap(dist_map, dist_map_8u);
return dist_map_8u;
}
}
int main()
{
std::vector<cv::Point2f> points_list;
// [1434, 308], [1434, 309], [1433, 310], [1427, 310], [1427, 312], [1426, 313], [1422, 313], [1422, 314],
points_list.push_back(cv::Point2f(1434, 308));
points_list.push_back(cv::Point2f(1434, 309));
points_list.push_back(cv::Point2f(1433, 310));
points_list.push_back(cv::Point2f(1427, 310));
points_list.push_back(cv::Point2f(1427, 312));
points_list.push_back(cv::Point2f(1426, 313));
points_list.push_back(cv::Point2f(1422, 313));
points_list.push_back(cv::Point2f(1422, 314));
// [1421, 315], [1415, 315], [1415, 316], [1414, 317], [1408, 317], [1408, 319], [1407, 320], [1403, 320],
points_list.push_back(cv::Point2f(1421, 315));
points_list.push_back(cv::Point2f(1415, 315));
points_list.push_back(cv::Point2f(1415, 316));
points_list.push_back(cv::Point2f(1414, 317));
points_list.push_back(cv::Point2f(1408, 317));
points_list.push_back(cv::Point2f(1408, 319));
points_list.push_back(cv::Point2f(1407, 320));
points_list.push_back(cv::Point2f(1403, 320));
// [1403, 321], [1402, 322], [1396, 322], [1396, 323], [1395, 324], [1389, 324], [1389, 326], [1388, 327],
points_list.push_back(cv::Point2f(1403, 321));
points_list.push_back(cv::Point2f(1402, 322));
points_list.push_back(cv::Point2f(1396, 322));
points_list.push_back(cv::Point2f(1396, 323));
points_list.push_back(cv::Point2f(1395, 324));
points_list.push_back(cv::Point2f(1389, 324));
points_list.push_back(cv::Point2f(1389, 326));
points_list.push_back(cv::Point2f(1388, 327));
// [1382, 327], [1382, 328], [1381, 329], [1376, 329], [1376, 330], [1375, 331], [1369, 331], [1369, 333],
points_list.push_back(cv::Point2f(1382, 327));
points_list.push_back(cv::Point2f(1382, 328));
points_list.push_back(cv::Point2f(1381, 329));
points_list.push_back(cv::Point2f(1376, 329));
points_list.push_back(cv::Point2f(1376, 330));
points_list.push_back(cv::Point2f(1375, 331));
points_list.push_back(cv::Point2f(1369, 331));
points_list.push_back(cv::Point2f(1369, 333));
// [1368, 334], [1362, 334], [1362, 335], [1361, 336], [1359, 336], [1359, 1016], [1365, 1016], [1366, 1017],
points_list.push_back(cv::Point2f(1368, 334));
points_list.push_back(cv::Point2f(1362, 334));
points_list.push_back(cv::Point2f(1362, 335));
points_list.push_back(cv::Point2f(1361, 336));
points_list.push_back(cv::Point2f(1359, 336));
points_list.push_back(cv::Point2f(1359, 1016));
points_list.push_back(cv::Point2f(1365, 1016));
points_list.push_back(cv::Point2f(1366, 1017));
// [1366, 1019], [1430, 1019], [1430, 1017], [1431, 1016], [1440, 1016], [1440, 308]
points_list.push_back(cv::Point2f(1366, 1019));
points_list.push_back(cv::Point2f(1430, 1019));
points_list.push_back(cv::Point2f(1430, 1017));
points_list.push_back(cv::Point2f(1431, 1016));
points_list.push_back(cv::Point2f(1440, 1016));
points_list.push_back(cv::Point2f(1440, 308));
cv::Mat pointsf;
cv::Mat(points_list).convertTo(pointsf, CV_32F);
cv::RotatedRect ellipse_params = cv::fitEllipseAMS(pointsf);
std::cout << "ellipse_params, center=" << ellipse_params.center << " ; size=" << ellipse_params.size
<< " ; angle=" << ellipse_params.angle << std::endl;
cv::TickMeter tm;
tm.start();
cv::Mat dist_map_8u = drawEllipseDistanceMap(ellipse_params);
tm.stop();
std::cout << "Elapsed time: " << tm.getAvgTimeSec() << " sec" << std::endl;
cv::Point center(ellipse_params.center.x, ellipse_params.center.y);
cv::Point axis(ellipse_params.size.width/2, ellipse_params.size.height/2);
std::vector<cv::Point> ellipse_pts_list;
cv::ellipse2Poly(center, axis, ellipse_params.angle, 0, 360, 1, ellipse_pts_list);
cv::polylines(dist_map_8u, ellipse_pts_list, false, cv::Scalar(0, 0, 0), 3);
// Points to be fitted
cv::Mat closest_pts;
cv::getClosestEllipsePoints(ellipse_params, pointsf, closest_pts);
for (int i = 0; i < closest_pts.rows; i++) {
cv::Point pt;
pt.x = closest_pts.at<cv::Point2f>(i).x;
pt.y = closest_pts.at<cv::Point2f>(i).y;
cv::circle(dist_map_8u, pt, 8, cv::Scalar(0, 0, 255), 2);
}
cv::imwrite("dist_map_8u.png", dist_map_8u);
return EXIT_SUCCESS;
}
```
</details>

---
### Pull Request Readiness Checklist
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
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake1 parent 17d9427 commit e258f25Copy full SHA for e258f25
File tree
Expand file treeCollapse file tree
4 files changed
+351
-13
lines changedFilter options
- doc
- modules/imgproc
- include/opencv2
- src
- test
Expand file treeCollapse file tree
4 files changed
+351
-13
lines changed+7Lines changed: 7 additions & 0 deletions
Original file line number | Diff line number | Diff line change | |
---|---|---|---|
| |||
301 | 301 |
| |
302 | 302 |
| |
303 | 303 |
| |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
304 | 311 |
| |
305 | 312 |
| |
306 | 313 |
| |
|
modules/imgproc/include/opencv2/imgproc.hpp
Copy file name to clipboardExpand all lines: modules/imgproc/include/opencv2/imgproc.hpp+36-13Lines changed: 36 additions & 13 deletions
Original file line number | Diff line number | Diff line change | |
---|---|---|---|
| |||
118 | 118 |
| |
119 | 119 |
| |
120 | 120 |
| |
121 |
| - | |
| 121 | + | |
122 | 122 |
| |
123 | 123 |
| |
124 | 124 |
| |
| |||
1467 | 1467 |
| |
1468 | 1468 |
| |
1469 | 1469 |
| |
1470 |
| - | |
| 1470 | + | |
1471 | 1471 |
| |
1472 | 1472 |
| |
1473 | 1473 |
| |
| |||
1549 | 1549 |
| |
1550 | 1550 |
| |
1551 | 1551 |
| |
1552 |
| - | |
| 1552 | + | |
1553 | 1553 |
| |
1554 | 1554 |
| |
1555 | 1555 |
| |
| |||
1659 | 1659 |
| |
1660 | 1660 |
| |
1661 | 1661 |
| |
1662 |
| - | |
| 1662 | + | |
1663 | 1663 |
| |
1664 | 1664 |
| |
1665 | 1665 |
| |
| |||
1874 | 1874 |
| |
1875 | 1875 |
| |
1876 | 1876 |
| |
1877 |
| - | |
| 1877 | + | |
1878 | 1878 |
| |
1879 | 1879 |
| |
1880 | 1880 |
| |
| |||
2143 | 2143 |
| |
2144 | 2144 |
| |
2145 | 2145 |
| |
2146 |
| - | |
| 2146 | + | |
2147 | 2147 |
| |
2148 | 2148 |
| |
2149 | 2149 |
| |
| |||
2986 | 2986 |
| |
2987 | 2987 |
| |
2988 | 2988 |
| |
2989 |
| - | |
| 2989 | + | |
2990 | 2990 |
| |
2991 | 2991 |
| |
2992 | 2992 |
| |
2993 | 2993 |
| |
2994 | 2994 |
| |
2995 |
| - | |
| 2995 | + | |
2996 | 2996 |
| |
2997 | 2997 |
| |
2998 | 2998 |
| |
| |||
3022 | 3022 |
| |
3023 | 3023 |
| |
3024 | 3024 |
| |
3025 |
| - | |
| 3025 | + | |
3026 | 3026 |
| |
3027 | 3027 |
| |
3028 | 3028 |
| |
| |||
3507 | 3507 |
| |
3508 | 3508 |
| |
3509 | 3509 |
| |
3510 |
| - | |
| 3510 | + | |
3511 | 3511 |
| |
3512 | 3512 |
| |
3513 | 3513 |
| |
| |||
3834 | 3834 |
| |
3835 | 3835 |
| |
3836 | 3836 |
| |
3837 |
| - | |
| 3837 | + | |
3838 | 3838 |
| |
3839 | 3839 |
| |
3840 | 3840 |
| |
| |||
4072 | 4072 |
| |
4073 | 4073 |
| |
4074 | 4074 |
| |
4075 |
| - | |
| 4075 | + | |
4076 | 4076 |
| |
4077 | 4077 |
| |
4078 | 4078 |
| |
| |||
4326 | 4326 |
| |
4327 | 4327 |
| |
4328 | 4328 |
| |
| 4329 | + | |
| 4330 | + | |
| 4331 | + | |
4329 | 4332 |
| |
4330 | 4333 |
| |
4331 | 4334 |
| |
| |||
4363 | 4366 |
| |
4364 | 4367 |
| |
4365 | 4368 |
| |
| 4369 | + | |
| 4370 | + | |
| 4371 | + | |
4366 | 4372 |
| |
4367 | 4373 |
| |
4368 | 4374 |
| |
| |||
4408 | 4414 |
| |
4409 | 4415 |
| |
4410 | 4416 |
| |
| 4417 | + | |
| 4418 | + | |
| 4419 | + | |
4411 | 4420 |
| |
4412 | 4421 |
| |
4413 | 4422 |
| |
| 4423 | + | |
| 4424 | + | |
| 4425 | + | |
| 4426 | + | |
| 4427 | + | |
| 4428 | + | |
| 4429 | + | |
| 4430 | + | |
| 4431 | + | |
| 4432 | + | |
| 4433 | + | |
| 4434 | + | |
| 4435 | + | |
| 4436 | + | |
4414 | 4437 |
| |
4415 | 4438 |
| |
4416 | 4439 |
| |
| |||
4429 | 4452 |
| |
4430 | 4453 |
| |
4431 | 4454 |
| |
4432 |
| - | |
| 4455 | + | |
4433 | 4456 |
| |
4434 | 4457 |
| |
4435 | 4458 |
| |
|
modules/imgproc/src/shapedescr.cpp
Copy file name to clipboardExpand all lines: modules/imgproc/src/shapedescr.cpp+115Lines changed: 115 additions & 0 deletions
Original file line number | Diff line number | Diff line change | |
---|---|---|---|
| |||
877 | 877 |
| |
878 | 878 |
| |
879 | 879 |
| |
| 880 | + | |
| 881 | + | |
| 882 | + | |
| 883 | + | |
| 884 | + | |
| 885 | + | |
| 886 | + | |
| 887 | + | |
| 888 | + | |
| 889 | + | |
| 890 | + | |
| 891 | + | |
| 892 | + | |
| 893 | + | |
| 894 | + | |
| 895 | + | |
| 896 | + | |
| 897 | + | |
| 898 | + | |
| 899 | + | |
| 900 | + | |
| 901 | + | |
| 902 | + | |
| 903 | + | |
| 904 | + | |
| 905 | + | |
| 906 | + | |
| 907 | + | |
| 908 | + | |
| 909 | + | |
| 910 | + | |
| 911 | + | |
| 912 | + | |
| 913 | + | |
| 914 | + | |
| 915 | + | |
| 916 | + | |
| 917 | + | |
| 918 | + | |
| 919 | + | |
| 920 | + | |
| 921 | + | |
| 922 | + | |
| 923 | + | |
| 924 | + | |
| 925 | + | |
| 926 | + | |
| 927 | + | |
| 928 | + | |
| 929 | + | |
| 930 | + | |
| 931 | + | |
| 932 | + | |
| 933 | + | |
| 934 | + | |
| 935 | + | |
| 936 | + | |
| 937 | + | |
| 938 | + | |
| 939 | + | |
| 940 | + | |
| 941 | + | |
| 942 | + | |
| 943 | + | |
| 944 | + | |
| 945 | + | |
| 946 | + | |
| 947 | + | |
| 948 | + | |
| 949 | + | |
| 950 | + | |
| 951 | + | |
| 952 | + | |
| 953 | + | |
| 954 | + | |
| 955 | + | |
| 956 | + | |
| 957 | + | |
| 958 | + | |
| 959 | + | |
| 960 | + | |
| 961 | + | |
| 962 | + | |
| 963 | + | |
| 964 | + | |
| 965 | + | |
| 966 | + | |
| 967 | + | |
| 968 | + | |
| 969 | + | |
| 970 | + | |
| 971 | + | |
| 972 | + | |
| 973 | + | |
| 974 | + | |
| 975 | + | |
| 976 | + | |
| 977 | + | |
| 978 | + | |
| 979 | + | |
| 980 | + | |
| 981 | + | |
| 982 | + | |
| 983 | + | |
| 984 | + | |
| 985 | + | |
| 986 | + | |
| 987 | + | |
| 988 | + | |
| 989 | + | |
| 990 | + | |
| 991 | + | |
| 992 | + | |
| 993 | + | |
| 994 | + | |
880 | 995 |
| |
881 | 996 |
| |
882 | 997 |
| |
|
You can’t perform that action at this time.
0 commit comments