钉子绕线画
        【摘要】 
                     
按照绕线画算法这篇博客给出的思路: 
 
我也来尝试一下。 
数据结构 
struct Point2 {	int x, y;	bool operator< (const Point2 b) const	{		if (x == b.x)return y < b.y;		return x < b.x;	}};struc...
    
    
    
    按照绕线画算法这篇博客给出的思路:

我也来尝试一下。
数据结构
  
   - 
    
     
    
    
     
      struct Point2 {
     
    
 
   - 
    
     
    
    
     	int x, y;
     
    
 
   - 
    
     
    
    
     	bool operator< (const Point2 b) const
     
    
 
   - 
    
     
    
    
     
      	{
     
    
 
   - 
    
     
    
    
     		if (x == b.x)return y < b.y;
     
    
 
   - 
    
     
    
    
     		return x < b.x;
     
    
 
   - 
    
     
    
    
     
      	}
     
    
 
   - 
    
     
    
    
     
      };
     
    
 
   - 
    
     
    
    
     
      struct PointPair {
     
    
 
   - 
    
     
    
    
     
      	Point2 p1, p2;
     
    
 
   - 
    
     
    
    
     	PointPair(Point2 a, Point2 b)
     
    
 
   - 
    
     
    
    
     
      	{
     
    
 
   - 
    
     
    
    
     		if (a < b)p1 = a, p2 = b;
     
    
 
   - 
    
     
    
    
     		else p1 = b, p2 = a;
     
    
 
   - 
    
     
    
    
     
      	}
     
    
 
   - 
    
     
    
    
     	bool operator< (const PointPair b)const
     
    
 
   - 
    
     
    
    
     
      	{
     
    
 
   - 
    
     
    
    
     		if (p1 < b.p1)return true;
     
    
 
   - 
    
     
    
    
     		if (b.p1 < p1)return false;
     
    
 
   - 
    
     
    
    
     		return p2 < b.p2;
     
    
 
   - 
    
     
    
    
     
      	}
     
    
 
   - 
    
     
    
    
     
      };
     
    
 
  
 
算法
  
   - 
    
     
    
    
     
      Mat imgMask;
     
    
 
   - 
    
     
    
    
     
      double meanPix(Mat& img, Point2 a, Point2 b)
     
    
 
   - 
    
     
    
    
     
      {
     
    
 
   - 
    
     
    
    
     	int len = max(abs(a.x - b.x), abs(a.y - b.y));
     
    
 
   - 
    
     
    
    
     	double dx = (a.x - b.x) * 1.0 / len;
     
    
 
   - 
    
     
    
    
     	double dy = (a.y - b.y) * 1.0 / len;
     
    
 
   - 
    
     
    
    
     	double x = b.x, y = b.y;
     
    
 
   - 
    
     
    
    
     	int s = 0;
     
    
 
   - 
    
     
    
    
     	for (int i = 1; i < len; i++) {
     
    
 
   - 
    
     
    
    
     
      		x += dx, y += dy;
     
    
 
   - 
    
     
    
    
     
      		s += int(img.at<unsigned char>(int(x), int(y))* imgMask.at<unsigned char>(int(x), int(y)));
     
    
 
   - 
    
     
    
    
     
      	}
     
    
 
   - 
    
     
    
    
     	return s * 1.0 / len;
     
    
 
   - 
    
     
    
    
     
      }
     
    
 
   - 
    
     
    
    
     
      void subPix(Mat& img, Point2 a, Point2 b, int d)
     
    
 
   - 
    
     
    
    
     
      {
     
    
 
   - 
    
     
    
    
     	int len = max(abs(a.x - b.x), abs(a.y - b.y));
     
    
 
   - 
    
     
    
    
     	double dx = (a.x - b.x) * 1.0 / len;
     
    
 
   - 
    
     
    
    
     	double dy = (a.y - b.y) * 1.0 / len;
     
    
 
   - 
    
     
    
    
     	double x = b.x, y = b.y;
     
    
 
   - 
    
     
    
    
     	int s = 0;
     
    
 
   - 
    
     
    
    
     	for (int i = 1; i < len; i++) {
     
    
 
   - 
    
     
    
    
     
      		x += dx, y += dy;
     
    
 
   - 
    
     
    
    
     		int pix = img.at<unsigned char>(int(x), int(y));
     
    
 
   - 
    
     
    
    
     
      		img.at<unsigned char>(int(x), int(y)) = max(0, pix - d);
     
    
 
   - 
    
     
    
    
     
      	}
     
    
 
   - 
    
     
    
    
     
      }
     
    
 
   - 
    
     
    
    
     
      void setPix(Mat& img, Point2 a, Point2 b, int d)
     
    
 
   - 
    
     
    
    
     
      {
     
    
 
   - 
    
     
    
    
     	int len = max(abs(a.x - b.x), abs(a.y - b.y));
     
    
 
   - 
    
     
    
    
     	double dx = (a.x - b.x) * 1.0 / len;
     
    
 
   - 
    
     
    
    
     	double dy = (a.y - b.y) * 1.0 / len;
     
    
 
   - 
    
     
    
    
     	double x = b.x, y = b.y;
     
    
 
   - 
    
     
    
    
     	int s = 0;
     
    
 
   - 
    
     
    
    
     	for (int i = 1; i < len; i++) {
     
    
 
   - 
    
     
    
    
     
      		x += dx, y += dy;
     
    
 
   - 
    
     
    
    
     
      		img.at<unsigned char>(int(x), int(y)) = d;
     
    
 
   - 
    
     
    
    
     
      	}
     
    
 
   - 
    
     
    
    
     
      }
     
    
 
   - 
    
     
    
    
      
     
    
 
   - 
    
     
    
    
     
      int main()
     
    
 
   - 
    
     
    
    
     
      {
     
    
 
   - 
    
     
    
    
     	const int n = 600;
     
    
 
   - 
    
     
    
    
     	int lineNum = 800;
     
    
 
   - 
    
     
    
    
     
      	Mat img = imread("D:/im.jpg", 0);
     
    
 
   - 
    
     
    
    
     	resize(img, img, Size(n + 1, n+ 1));
     
    
 
   - 
    
     
    
    
     
      	Mat src;
     
    
 
   - 
    
     
    
    
     
      	img = 255 - img;
     
    
 
   - 
    
     
    
    
     	imshow("img", img);
     
    
 
   - 
    
     
    
    
     
      	imgMask = img.clone();
     
    
 
   - 
    
     
    
    
     	blur(imgMask, imgMask, Size(19, 19));
     
    
 
   - 
    
     
    
    
     	//imshow("img2", imgMask);
     
    
 
   - 
    
     
    
    
     
      	vector<Point2>vp;
     
    
 
   - 
    
     
    
    
     	for (int i = 0; i < 360; i++) {
     
    
 
   - 
    
     
    
    
     		double r = i * 3.1415926 / 180;
     
    
 
   - 
    
     
    
    
     
      		vp.push_back({ int(n / 2 * sin(r)) + 300, int(n / 2 * cos(r)) + 300 });
     
    
 
   - 
    
     
    
    
     
      	}
     
    
 
   - 
    
     
    
    
     
      	Point2 p = vp[0];
     
    
 
   - 
    
     
    
    
     
      	map< Line, int>m;
     
    
 
   - 
    
     
    
    
     	for (auto& pi : vp)m[Line(pi, pi)] = 1;
     
    
 
   - 
    
     
    
    
     
      	Mat ans = img.clone();
     
    
 
   - 
    
     
    
    
     
      	ans = 255;
     
    
 
   - 
    
     
    
    
     	while (lineNum--) {
     
    
 
   - 
    
     
    
    
     
      		Point2 next = p;
     
    
 
   - 
    
     
    
    
     		double s0 = 0;
     
    
 
   - 
    
     
    
    
     		for (auto& pi : vp) {
     
    
 
   - 
    
     
    
    
     			if (m[Line(p, pi)])continue;
     
    
 
   - 
    
     
    
    
     			double s = meanPix(img, p, pi);
     
    
 
   - 
    
     
    
    
     			if (s0 < s)s0 = s, next = pi;
     
    
 
   - 
    
     
    
    
     
      		}
     
    
 
   - 
    
     
    
    
     		subPix(img, p, next, 100);
     
    
 
   - 
    
     
    
    
     		setPix(ans, p, next, 100);
     
    
 
   - 
    
     
    
    
     
      		m[Line(p, next)] = 1;
     
    
 
   - 
    
     
    
    
     
      		p = next;
     
    
 
   - 
    
     
    
    
     
      	}
     
    
 
   - 
    
     
    
    
     	//imshow("img3", img);
     
    
 
   - 
    
     
    
    
     	imshow("ans", ans);
     
    
 
   - 
    
     
    
    
     	waitKey(0);
     
    
 
   - 
    
     
    
    
     	return 0;
     
    
 
   - 
    
     
    
    
     
      }
     
    
 
  
 
结果:

原图:

远处对比:

和某bao上的效果对比,还是有很大差距的。
我想了一下,上面的算法思路虽然简单,但是有效性确实有限。
比如这种情况:

要想一笔画,每一条弦都有用,就很难。
实际上应该运行一部分弦是没用的,这样就能得到这种解:

右边的2条弦没有命中目标,但是很有必要。
所以个人感觉某bao上的AI算法,应该是类似于分割算法,分割成若干直线。
文章来源: blog.csdn.net,作者:csuzhucong,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/nameofcsdn/article/details/124882214
        【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
            cloudbbs@huaweicloud.com
        
        
        
        
        - 点赞
 - 收藏
 - 关注作者
 
            
           
评论(0)