让阿豪来帮你解答,本回答参考chatgpt3.5编写提供,如果还有疑问可以评论或留言
问题分析:
- 如何对图片进行轮廓细化处理?
- 如何提取出骨架线?
- 如何去除骨架线上的毛刺?
- 如何将骨架线绘制到原图内部? 解决方案:
- 对于二值图像,可以使用opencv中的函数cv2.ximgproc.thinning()进行轮廓细化处理。代码示例:
import cv2
img = cv2.imread("image.png", 0)
thinned_img = cv2.ximgproc.thinning(img, None, cv2.ximgproc.THINNING_ZHANGSUEN)
- 提取出骨架线,可以使用opencv中的函数cv2.connectedComponents()。可以通过遍历像素的方式,判断其是否为端点或交叉点,然后在骨架线上将其标记为白色像素。
import numpy as np
# 寻找端点和交叉点的函数
def find_junctions(endpoint_img, kernel=None):
if kernel is None:
kernel = np.ones((3, 3), np.uint8)
junctions = np.zeros_like(endpoint_img)
connected = cv2.connectedComponents(endpoint_img)
labels = connected[1]
junction_values = []
for i in range(1, connected[0]):
g = (labels == i)
num = np.sum(g)
if num == 1:
junctions[g] = 1
junction_values.append((np.argmax(g) // labels.shape[1], np.argmax(g) % labels.shape[1]))
elif num > 2:
junctions[g] = 1
junction_values.append((np.argmax(g) // labels.shape[1], np.argmax(g) % labels.shape[1]))
junctions = cv2.dilate(junctions, kernel, iterations=1)
junctions = junctions - endpoint_img
return junctions, junction_values
# 提取骨架线的函数
def get_skeleton(img):
skel = np.zeros_like(img)
img = img.copy()
while True:
endpoint_img = cv2.morphologyEx(img, cv2.MORPH_HITMISS, np.array([[0, 0, 0], [0, 1, 0], [1, 1, 1]]))
if np.sum(endpoint_img) == 0:
break
junctions_img, _ = find_junctions(endpoint_img)
skel = skel + endpoint_img
img = cv2.subtract(img, endpoint_img)
img = cv2.subtract(img, junctions_img)
return skel
img = cv2.imread("image.png", 0)
thinned_img = cv2.ximgproc.thinning(img, None, cv2.ximgproc.THINNING_ZHANGSUEN)
skeleton = get_skeleton(thinned_img)
- 对于骨架线上的毛刺,可以通过以下代码进行处理:
def clean_skeleton(skeleton):
kernel1 = np.array([[-1, -1, -1], [0, 1, 0], [1, 1, 1]], dtype=np.uint8)
kernel2 = np.array([[1, 1, 1], [0, 1, 0], [-1, -1, -1]], dtype=np.uint8)
skeleton = cv2.morphologyEx(skeleton, cv2.MORPH_OPEN, kernel1)
skeleton = cv2.morphologyEx(skeleton, cv2.MORPH_OPEN, kernel2)
return skeleton
skeleton = clean_skeleton(skeleton)
- 将骨架线绘制到原图内部,则可以使用opencv中的函数cv2.drawContours(),示例代码:
edged = cv2.Canny(img, 50, 150)
thresh = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 21, 1)
cv2.drawContours(thresh, [skeleton], 0, (255, 255, 255), -1)
cv2.imshow("Final Result", thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()