钉子绕线画

举报
用户已注销 发表于 2022/05/21 23:20:01 2022/05/21
【摘要】 按照绕线画算法这篇博客给出的思路: 我也来尝试一下。 数据结构 struct Point2 { int x, y; bool operator< (const Point2 b) const { if (x == b.x)return y < b.y; return x < b.x; }};struc...

按照绕线画算法这篇博客给出的思路:

我也来尝试一下。

数据结构


  
  1. struct Point2 {
  2. int x, y;
  3. bool operator< (const Point2 b) const
  4. {
  5. if (x == b.x)return y < b.y;
  6. return x < b.x;
  7. }
  8. };
  9. struct PointPair {
  10. Point2 p1, p2;
  11. PointPair(Point2 a, Point2 b)
  12. {
  13. if (a < b)p1 = a, p2 = b;
  14. else p1 = b, p2 = a;
  15. }
  16. bool operator< (const PointPair b)const
  17. {
  18. if (p1 < b.p1)return true;
  19. if (b.p1 < p1)return false;
  20. return p2 < b.p2;
  21. }
  22. };

算法


  
  1. Mat imgMask;
  2. double meanPix(Mat& img, Point2 a, Point2 b)
  3. {
  4. int len = max(abs(a.x - b.x), abs(a.y - b.y));
  5. double dx = (a.x - b.x) * 1.0 / len;
  6. double dy = (a.y - b.y) * 1.0 / len;
  7. double x = b.x, y = b.y;
  8. int s = 0;
  9. for (int i = 1; i < len; i++) {
  10. x += dx, y += dy;
  11. s += int(img.at<unsigned char>(int(x), int(y))* imgMask.at<unsigned char>(int(x), int(y)));
  12. }
  13. return s * 1.0 / len;
  14. }
  15. void subPix(Mat& img, Point2 a, Point2 b, int d)
  16. {
  17. int len = max(abs(a.x - b.x), abs(a.y - b.y));
  18. double dx = (a.x - b.x) * 1.0 / len;
  19. double dy = (a.y - b.y) * 1.0 / len;
  20. double x = b.x, y = b.y;
  21. int s = 0;
  22. for (int i = 1; i < len; i++) {
  23. x += dx, y += dy;
  24. int pix = img.at<unsigned char>(int(x), int(y));
  25. img.at<unsigned char>(int(x), int(y)) = max(0, pix - d);
  26. }
  27. }
  28. void setPix(Mat& img, Point2 a, Point2 b, int d)
  29. {
  30. int len = max(abs(a.x - b.x), abs(a.y - b.y));
  31. double dx = (a.x - b.x) * 1.0 / len;
  32. double dy = (a.y - b.y) * 1.0 / len;
  33. double x = b.x, y = b.y;
  34. int s = 0;
  35. for (int i = 1; i < len; i++) {
  36. x += dx, y += dy;
  37. img.at<unsigned char>(int(x), int(y)) = d;
  38. }
  39. }
  40. int main()
  41. {
  42. const int n = 600;
  43. int lineNum = 800;
  44. Mat img = imread("D:/im.jpg", 0);
  45. resize(img, img, Size(n + 1, n+ 1));
  46. Mat src;
  47. img = 255 - img;
  48. imshow("img", img);
  49. imgMask = img.clone();
  50. blur(imgMask, imgMask, Size(19, 19));
  51. //imshow("img2", imgMask);
  52. vector<Point2>vp;
  53. for (int i = 0; i < 360; i++) {
  54. double r = i * 3.1415926 / 180;
  55. vp.push_back({ int(n / 2 * sin(r)) + 300, int(n / 2 * cos(r)) + 300 });
  56. }
  57. Point2 p = vp[0];
  58. map< Line, int>m;
  59. for (auto& pi : vp)m[Line(pi, pi)] = 1;
  60. Mat ans = img.clone();
  61. ans = 255;
  62. while (lineNum--) {
  63. Point2 next = p;
  64. double s0 = 0;
  65. for (auto& pi : vp) {
  66. if (m[Line(p, pi)])continue;
  67. double s = meanPix(img, p, pi);
  68. if (s0 < s)s0 = s, next = pi;
  69. }
  70. subPix(img, p, next, 100);
  71. setPix(ans, p, next, 100);
  72. m[Line(p, next)] = 1;
  73. p = next;
  74. }
  75. //imshow("img3", img);
  76. imshow("ans", ans);
  77. waitKey(0);
  78. return 0;
  79. }

结果:

 原图:

远处对比:

和某bao上的效果对比,还是有很大差距的。

我想了一下,上面的算法思路虽然简单,但是有效性确实有限。

比如这种情况:

要想一笔画,每一条弦都有用,就很难。

实际上应该运行一部分弦是没用的,这样就能得到这种解:

右边的2条弦没有命中目标,但是很有必要。

所以个人感觉某bao上的AI算法,应该是类似于分割算法,分割成若干直线。

 

 

文章来源: blog.csdn.net,作者:csuzhucong,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/nameofcsdn/article/details/124882214

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。