opencv 从噪声图像中检测直线

ukxgm1gy  于 2023-11-22  发布在  其他
关注(0)|答案(1)|浏览(180)

我试图从嘈杂的图像中检测线条,这些是我遵循的步骤:

  1. img= cv2.imread('/content/spec_un45_3900000.jpg',cv2.IMREAD_GRAYSCALE)

字符串
x1c 0d1x的数据

  1. img = 255 - cv2.medianBlur(img, 3) #Invert and blur


  1. #Remove white spots from background
  2. kernel = np.ones((1, 2), np.uint8)
  3. opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel,iterations=2)


  1. edges = cv2.Canny(opening,0,100,apertureSize = 3)
  2. cv2_imshow(edges)


  1. #Hough Line detection
  2. lines = cv2.HoughLinesP(image=edges,
  3. rho=1,
  4. theta=np.pi/180,
  5. threshold=100,
  6. lines=np.array([]),
  7. minLineLength=5,
  8. maxLineGap=200)
  9. for i in range(lines.shape[0]):
  10. cv2.line(out,
  11. (lines[i][0][0],
  12. lines[i][0][1]),
  13. (lines[i][0][2],
  14. lines[i][0][3]),
  15. (0,255, 255), 1, cv2.LINE_AA)


x1c4d 1x的
我尝试了How to detect lines in noisy line images?中提到的方法
有人能帮我调试这个/提供解决方案吗?

8aqjt8rx

8aqjt8rx1#

这不是一个非常有效的答案,但它对严重的噪声具有鲁棒性,并且内核过滤思想对于单尺度匹配(它不处理尺度变化)任务很有用。
使用原始图像(ksize = 201,thresh = 150)
x1c 0d1x的数据
最后一张图像(ksize = 51,thresh = 200)



基本的想法是创建一个与你想要的图像/形状匹配的内核。然后你可以在图像上卷积它并寻找热点。最后我对蒙版进行去重化以去除粗线(在蒙版上运行hough-lines希望只得到一条线而不是一堆线)。

  1. import cv2
  2. import math
  3. import numpy as np
  4. # rescale image
  5. def scale(img, scale_factor):
  6. h,w = img.shape[:2];
  7. h = int(h*scale_factor);
  8. w = int(w*scale_factor);
  9. return cv2.resize(img, (w,h));
  10. # chops padding
  11. def unpad(img, padsize):
  12. h,w = img.shape[:2];
  13. img = img[padsize:h-padsize, padsize:w-padsize];
  14. return img;
  15. # WARNING: be aware of the direction of the zero (positive vs negative)
  16. def zero_catch(value):
  17. zeroish = 0.00001
  18. if value <= zeroish:
  19. return zeroish
  20. return value
  21. # get line endpoints
  22. def get_coords(x, y, angle, imwidth, imheight):
  23. x1_length = (x-imwidth) / zero_catch(math.cos(math.radians(angle)));
  24. y1_length = (y-imheight) / zero_catch(math.sin(math.radians(angle)));
  25. length = max(abs(x1_length), abs(y1_length));
  26. endx1 = x + length * math.cos(math.radians(angle));
  27. endy1 = y + length * math.sin(math.radians(angle));
  28. x2_length = (x-imwidth) / zero_catch(math.cos(math.radians(angle+180)));
  29. y2_length = (y-imheight) / zero_catch(math.sin(math.radians(angle+180)));
  30. length = max(abs(x2_length), abs(y2_length));
  31. endx2 = x + length * math.cos(math.radians(angle+180));
  32. endy2 = y + length * math.sin(math.radians(angle+180));
  33. return int(endx1), int(endy1), int(endx2), int(endy2);
  34. # skinny up the image
  35. def skeletonize(img):
  36. size = np.size(img)
  37. skel = np.zeros(img.shape, np.uint8)
  38. element = cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))
  39. done = False
  40. while( not done):
  41. eroded = cv2.erode(img,element)
  42. temp = cv2.dilate(eroded,element)
  43. temp = cv2.subtract(img,temp)
  44. skel = cv2.bitwise_or(skel,temp)
  45. img = eroded;
  46. zeros = size - cv2.countNonZero(img)
  47. if zeros==size:
  48. done = True
  49. return skel;
  50. # load image
  51. filepath = "noisy_lines.png";
  52. img = cv2.imread(filepath, cv2.IMREAD_GRAYSCALE);
  53. orig_height, orig_width = img.shape[:2];
  54. # pad to avoid edge dropoff
  55. pad = int(orig_width/2);
  56. img = cv2.copyMakeBorder(img, pad, pad, pad, pad, cv2.BORDER_REFLECT, None)
  57. # get mask
  58. _, mask = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU);
  59. height,width = mask.shape;
  60. # background canvas
  61. canvas = np.zeros_like(mask);
  62. # super brute force solution
  63. ksize = 51; # tweakable scale setting
  64. center = int(ksize / 2);
  65. kernel = np.zeros((ksize, ksize), np.uint8);
  66. # draw line
  67. start_angle = -60;
  68. angle = start_angle; # start offset so that we can see the 0 degree get drawn
  69. while angle < start_angle + 180:
  70. kernel = np.zeros((ksize,ksize), np.float32);
  71. sx, sy, ex, ey = get_coords(center, center, angle, ksize, ksize);
  72. kernel = cv2.line(kernel, (sx,sy), (ex,ey), 1.0 / ksize, 1);
  73. angle += 1;
  74. # convolve
  75. conv = cv2.filter2D(mask, -1, kernel, borderType=cv2.BORDER_CONSTANT);
  76. # paint onto canvas
  77. _, linemask = cv2.threshold(conv, 200, 255, cv2.THRESH_BINARY); # tweakable sensitivity setting
  78. canvas = cv2.bitwise_or(canvas, linemask);
  79. # chop off padding
  80. display_canvas = unpad(canvas, pad);
  81. display_conv = unpad(conv, pad);
  82. # stack the images
  83. sbs = np.hstack((display_canvas, display_conv));
  84. sbs = scale(sbs, 0.5);
  85. # show
  86. cv2.imshow("side-by-side", sbs);
  87. key = cv2.waitKey(1);
  88. if key == ord('q'):
  89. break;
  90. # show image
  91. cv2.destroyAllWindows();
  92. display_canvas = unpad(canvas, pad);
  93. display_canvas = skeletonize(display_canvas);
  94. orig_img = cv2.imread(filepath);
  95. cv2.imshow("Image", orig_img);
  96. cv2.imshow("Canvas", display_canvas);
  97. cv2.waitKey(0);

字符串

展开查看全部

相关问题