计算出一张图片不同区域画图的顺序,先对图像进行分割,将不同区域区分开来,然后再按照一定顺序进行绘制。
以下是一个基本的步骤:
- 加载图片并将其转换为适合处理的格式。
- 对图像进行预处理,例如调整亮度和对比度、去除噪声等。
- 使用图像分割算法将图像划分为不同的区域。可以选择自动分割或手动分割,自动分割可以使用算法如K均值聚类、区域生长等,手动分割可以手动标记区域。
- 对分割后的区域进行排序,可以使用类似于广度优先搜索或深度优先搜索的算法,从左到右或从上到下逐个绘制区域。
- 根据需要调整绘制参数,例如线条颜色、粗细、填充方式等。
- 按照排序好的顺序逐个绘制区域。
- 完成绘制后,可以保存图像或将其显示在界面上。
我设想了两种思路来实现这个,第一种是:
使用opencv通过常用的灰度变换,canny算子,对图片进行简单的处理,寻找到轮廓,然后就根据cv2.findcontour来对找到的轮廓进行分级,对不同的轮廓进行边缘绘制。
但是后面发现有很多问题,首先是分级不太均匀,其次是轮廓的边缘绘制很容易受到一些细节的影响,从而影响到最后成品的质量。
import cv2
import numpy as np
img = cv2.imread('pi.png')
height = img.shape[0]
width = img.shape[1]
newImg = np.zeros((height, width, 3), dtype=np.uint8)
newImg[:] = [255, 255, 255]
# 将图片转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 对图像进行二值化处理
_, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY)
# 查找轮廓
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
area = [cv2.contourArea(c) for c in contours]
print(range(len(hierarchy[0])))
# cv2.drawContours(img, contours, -1, (0, 0, 255), 1)
# 根据hierarchy信息,绘制不同层级的轮廓
for i in range(len(hierarchy[0])):
if hierarchy[0][i][3] == -1: # 只绘制顶级轮廓
cv2.drawContours(newImg, contours, i, (0, 0, 255), 1)
elif hierarchy[0][i][3] == 16: # 绘制非顶级轮廓
cv2.drawContours(newImg, contours, i, (0, 255, 0), 1)
elif hierarchy[0][i][3] == 0: # 绘制非顶级轮廓
cv2.drawContours(newImg, contours, i, (255, 0, 0), 1)
elif hierarchy[0][i][3] != -1 and hierarchy[0][i][3] != 0 and hierarchy[0][i][3] != 16: # 绘制非顶级轮廓
cv2.drawContours(newImg, contours, i, (15, 255, 100), 1)
# 显示绘制结果
cv2.imshow('Image', newImg)
cv2.imshow('binary', binary)
cv2.waitKey(0)
cv2.destroyAllWindows()
第二种方法是:
利用K-means算法来实现聚类,将不同的颜色的区域进行一个分类,并且打上标记属性