计算出一张图片不同区域画图的顺序,先对图像进行分割,将不同区域区分开来,然后再按照一定顺序进行绘制。
以下是一个基本的步骤:
我设想了两种思路来实现这个,第一种是:
使用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算法来实现聚类,将不同的颜色的区域进行一个分类,并且打上标记属性