我会采用以下方法来尝试找到问题中提供的四行内容。
1. 阅读图像,并将其转换为灰度图像。
import cv2
import numpy as np
rgb_img = cv2.imread('pipe.jpg')
gray_img = cv2.cvtColor(rgb_img, cv2.COLOR_BGR2GRAY)
height, width = gray_img.shape
2. 在图片顶部添加一些白色的内边距(只是为了增加一些额外的背景)
white_padding = np.zeros((50, width, 3))
white_padding[:, :] = [255, 255, 255]
rgb_img = np.row_stack((white_padding, rgb_img))
结果图像 -
3. 反转灰度图像并在顶部应用黑色填充
gray_img = 255 - gray_img
gray_img[gray_img > 100] = 255
gray_img[gray_img <= 100] = 0
black_padding = np.zeros((50, width))
gray_img = np.row_stack((black_padding, gray_img))
4. 使用形态学闭运算来填补图像中的空洞 -
kernel = np.ones((30, 30), np.uint8)
closing = cv2.morphologyEx(gray_img, cv2.MORPH_CLOSE, kernel)
5. 使用Canny边缘检测在图像中找到边缘-
edges = cv2.Canny(closing, 100, 200)
6. 现在,我们可以使用openCV的HoughLinesP
函数在给定的图像中找到线条-
minLineLength = 500
maxLineGap = 10
lines = cv2.HoughLinesP(edges, 1, np.pi / 180, 50, None, 50, 100)
all_lines = lines[0]
for x1,y1,x2,y2 in lines[0]:
cv2.line(rgb_img,(x1,y1),(x2,y2),(0,0,255),2)
7.现在,我们需要找到最右边的两条水平线和最底部的两条垂直线。对于水平线,我们将使用(x2,x1)进行排序,按降序排列。在这个排序列表中,第一条线将是最右边的垂直线。跳过这条线,如果我们选择下面的两条线,它们将是最右边的水平线。
all_lines_x_sorted = sorted(all_lines, key=lambda k: (-k[2], -k[0]))
for x1,y1,x2,y2 in all_lines_x_sorted[1:3]:
cv2.line(rgb_img,(x1,y1),(x2,y2),(0,0,255),2)
8. 同样地,可以使用y1坐标按降序对线进行排序,排序列表中的前两条线将是最底部的垂直线。
all_lines_y_sorted = sorted(all_lines, key=lambda k: (-k[1]))
for x1,y1,x2,y2 in all_lines_y_sorted[:2]:
cv2.line(rgb_img,(x1,y1),(x2,y2),(0,0,255),2)
9. 同时包含两条线的图片 -
final_lines = all_lines_x_sorted[1:3] + all_lines_y_sorted[:2]
因此,获取这4行可以帮助您完成剩下的任务。