opencv如何获取指定圆上所有像素点的坐标??

tiger波波 2018-08-31 05:32:18
在opencv里,根据圆心与半径,可以画出一个圆。
请问大家:如何得到这个指定圆上所有像素点的坐标???
...全文
5003 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
GK_2014 2020-04-12
  • 打赏
  • 举报
回复
根据opencv源码改写的函数,根据圆心坐标和半径,输出圆上所有点集。
vector<Point> getCirclePts(Point center, int radius)
{
vector<Point> ret;
int err = 0, dx = radius, dy = 0, plus = 1, minus = (radius << 1) - 1;
while(dx >= dy)
{
int mask;
int y11 = center.y - dy, y12 = center.y + dy, y21 = center.y - dx, y22 = center.y + dx;
int x11 = center.x - dx, x12 = center.x + dx, x21 = center.x - dy, x22 = center.x + dy;

ret.push_back(Point(x11,y11));
ret.push_back(Point(x11,y12));
ret.push_back(Point(x12,y11));
ret.push_back(Point(x12,y12));
ret.push_back(Point(x21,y21));
ret.push_back(Point(x21,y22));
ret.push_back(Point(x22,y21));
ret.push_back(Point(x22,y22));

dy++;
err += plus;
plus += 2;
mask = (err <= 0) - 1;
err -= minus & mask;
dx += mask;
minus -= mask & 2;
}
return ret;
}
GK_2014 2020-04-11
  • 打赏
  • 举报
回复
引用 8 楼 tiger波波 的回复:
采用了赵老师的办法弄了一个


void get_circle_coordinates(int width, int height, cv::Point center, int radius, std::vector<cv::Point> &coordinates)
{
cv::Scalar color;

coordinates.clear();

cv::Mat image(width, height, CV_8UC3, cv::Scalar(0, 0, 0));
circle(image, center, radius, cv::Scalar(255, 255, 255), 1);

for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
COpenCV::get_color(image, cv::Point(i, j), color);
if ((255 == color.val[0]) && (255 == color.val[1]) && (255 == color.val[2]))
coordinates.push_back(cv::Point(i, j));
}
}
}


引用 8 楼 tiger波波 的回复:
采用了赵老师的办法弄了一个


void get_circle_coordinates(int width, int height, cv::Point center, int radius, std::vector<cv::Point> &coordinates)
{
cv::Scalar color;

coordinates.clear();

cv::Mat image(width, height, CV_8UC3, cv::Scalar(0, 0, 0));
circle(image, center, radius, cv::Scalar(255, 255, 255), 1);

for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
COpenCV::get_color(image, cv::Point(i, j), color);
if ((255 == color.val[0]) && (255 == color.val[1]) && (255 == color.val[2]))
coordinates.push_back(cv::Point(i, j));
}
}
}

既然给定了圆的半径,那么要创建的图片的宽和高用2倍半径就行了,没必要从函数外再传入宽和高。另外创建的图片单通道就行了,为什么还要3通道呢?这种办法对于效率要求不高的场景还是可以用用,更高效的方法就是看opencv在调用circle函数时怎么通过中心点和半径获取圆上点的集合。
sunmeal 2019-11-14
  • 打赏
  • 举报
回复
判断一下, 优化一:一条直线与圆最多只能交与两点,做好这个计算,可以避免过多的遍历。 优化二:直接用sin计算,然后+-1个像素寻找是否存在,一般圆主要是折线时 优化三:注意四个象限的中间折线的那个点的变化规则,可以直接找到的 优化四:直接读OpenCV源码,将画圆的运算方式,找出即可
唔枣 2018-10-03
  • 打赏
  • 举报
回复
引用 8 楼 youyingbo 的回复:
采用了赵老师的办法弄了一个


void get_circle_coordinates(int width, int height, cv::Point center, int radius, std::vector<cv::Point> &coordinates)
{
cv::Scalar color;

coordinates.clear();

cv::Mat image(width, height, CV_8UC3, cv::Scalar(0, 0, 0));
circle(image, center, radius, cv::Scalar(255, 255, 255), 1);

for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
COpenCV::get_color(image, cv::Point(i, j), color);
if ((255 == color.val[0]) && (255 == color.val[1]) && (255 == color.val[2]))
coordinates.push_back(cv::Point(i, j));
}
}
}
谢谢大佬的代码,帮我解决了一个问题
唔枣 2018-10-03
  • 打赏
  • 举报
回复
引用 8 楼 youyingbo 的回复:
采用了赵老师的办法弄了一个


void get_circle_coordinates(int width, int height, cv::Point center, int radius, std::vector<cv::Point> &coordinates)
{
cv::Scalar color;

coordinates.clear();

cv::Mat image(width, height, CV_8UC3, cv::Scalar(0, 0, 0));
circle(image, center, radius, cv::Scalar(255, 255, 255), 1);

for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
COpenCV::get_color(image, cv::Point(i, j), color);
if ((255 == color.val[0]) && (255 == color.val[1]) && (255 == color.val[2]))
coordinates.push_back(cv::Point(i, j));
}
}
}


引用 8 楼 youyingbo 的回复:
采用了赵老师的办法弄了一个


void get_circle_coordinates(int width, int height, cv::Point center, int radius, std::vector<cv::Point> &coordinates)
{
cv::Scalar color;

coordinates.clear();

cv::Mat image(width, height, CV_8UC3, cv::Scalar(0, 0, 0));
circle(image, center, radius, cv::Scalar(255, 255, 255), 1);

for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
COpenCV::get_color(image, cv::Point(i, j), color);
if ((255 == color.val[0]) && (255 == color.val[1]) && (255 == color.val[2]))
coordinates.push_back(cv::Point(i, j));
}
}
}
画圆函数的最后一个参数要改成“-1”,不然画的是圆不是全白的圆,而是边缘像素为白,中间为黑
向立天 2018-09-04
  • 打赏
  • 举报
回复
引用 5 楼 youyingbo 的回复:
[quote=引用 3 楼 zgl7903 的回复:]
数学计算不就可以? x=x0 + r*cosθ; y=y0 + r*sinθ;

我觉得opencv画圆函数,在一张给定的图片上画出的圆,其圆上的像素点是确定的,算出来的和真实画出的圆有差距。另外角度不好取,同样一组角度,大圆和小圆效果就差很多。[/quote]那你就遍历所有像素点,根据颜色值来重新校对一下
tiger波波 2018-09-04
  • 打赏
  • 举报
回复
采用了赵老师的办法弄了一个


void get_circle_coordinates(int width, int height, cv::Point center, int radius, std::vector<cv::Point> &coordinates)
{
cv::Scalar color;

coordinates.clear();

cv::Mat image(width, height, CV_8UC3, cv::Scalar(0, 0, 0));
circle(image, center, radius, cv::Scalar(255, 255, 255), 1);

for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
COpenCV::get_color(image, cv::Point(i, j), color);
if ((255 == color.val[0]) && (255 == color.val[1]) && (255 == color.val[2]))
coordinates.push_back(cv::Point(i, j));
}
}
}
赵4老师 2018-09-03
  • 打赏
  • 举报
回复
算出来的值和实际像素位置难免有舍入误差。
tiger波波 2018-09-03
  • 打赏
  • 举报
回复
引用 3 楼 zgl7903 的回复:
数学计算不就可以? x=x0 + r*cosθ; y=y0 + r*sinθ;

我觉得opencv画圆函数,在一张给定的图片上画出的圆,其圆上的像素点是确定的,算出来的和真实画出的圆有差距。另外角度不好取,同样一组角度,大圆和小圆效果就差很多。
向立天 2018-09-01
  • 打赏
  • 举报
回复
你有圆心和半径的不就可以自己算了
zgl7903 2018-09-01
  • 打赏
  • 举报
回复
数学计算不就可以? x=x0 + r*cosθ; y=y0 + r*sinθ;
赵4老师 2018-09-01
  • 打赏
  • 举报
回复
或者简单点:
创建一副尺寸够大的黑色位图,在上面画一个白色圆,遍历每个白色像素对应的坐标。
赵4老师 2018-09-01
  • 打赏
  • 举报
回复
将圆用比如正90边形近似,调用GDI函数LineDDA?

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧