@[toc]python
請編寫程序將圖像Image中的三角形找到,而且以接近於圖像中心的三角形做爲根節點,距離其最近的三角形做爲其左節點,次近的做爲其右節點,創建一個二叉樹來表示和存儲圖中的三角形,其中二叉樹中每一個節點包括:三角形的位置、其父節點的位置(若爲個節點,座標爲(-1,-1))、三角形的顏色、三角形的面積。
請輸出二叉樹算法
先先識別三角形,就先轉成二值圖像, 而後使用輪廓發現findContours相關函數,提取與繪製輪廓,最後用approxPolyDP對其進行輪廓逼近,微信
而後對三角形找到中心點 ,須要用moments計算一階幾何距獲得指定輪廓的中心位置markdown
而後的到的三角形中心位置座標能夠用來得出三角形的座標和顏色app
「以接近於圖像中心的三角形做爲根節點,距離其最近的三角形做爲其左節點,次近的做爲其右節點」在構成二叉樹的時候(我印象中學習機器學習的時候貌似記得有個KNN算法,實現有點麻煩),這裏我是直接用兩點之間開方計算距離。機器學習
後面二叉樹的,先按照距離進行排序,而後插入節點ide
# -*- coding: utf-8 -*- #引入必要工具 import cv2 as cv import numpy as np import math #計算距離 def caculateDistance(a, b): return math.sqrt(math.pow(a[0] - b[0], 2) + math.pow(a[1] - b[1], 2)) class Node: def __init__(self, pos, area, color): # 節點內容:面積,顏色,座標,左子樹,右子樹,父節點 self.area = area self.color = color self.pos = pos self.left = None self.right = None self.Parent = None #添加左子樹 def addLeft(self, l): self.left = l # 添加右子樹 def addRight(self, r): self.right = r # 添加父節點 def GetParent(self): return self.Parent #定義樹 class Tree: def __init__(self): self.root = None def addroot(self, root): self.root = root class ShapeAnalysis: def __init__(self): self.shapes = {'triangle': 0, 'rectangle': 0, 'polygons': 0, 'circles': 0} self.i = 0 def analysis(self, frame, tree): h, w, ch = frame.shape result = np.zeros((h, w, ch), dtype=np.uint8) # 二值化圖像 print("start to detect lines...\n") gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY) ret, binary = cv.threshold(gray, 230, 255, cv.THRESH_BINARY_INV) triangles = {} cv.imshow("Binary Image", binary) out_binary, contours, hierarchy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE) for cnt in range(len(contours)): # 提取與繪製輪廓 cv.drawContours(result, contours, cnt, (0, 255, 0), 2) # 輪廓逼近 epsilon = 0.012 * cv.arcLength(contours[cnt], True) approx = cv.approxPolyDP(contours[cnt], epsilon, True) # 分析幾何形狀 corners = len(approx) shape_type = [] if corners == 3: count = self.shapes['triangle'] count = count + 1 self.shapes['triangle'] = count shape_type = "三角形" # 求中心位置 mm = cv.moments(contours[cnt]) cx = int(mm['m10'] / mm['m00']) cy = int(mm['m01'] / mm['m00']) if shape_type == "三角形": cv.circle(result, (cx, cy), 3, (0, 0, 255), -1) # 計算顏色 color = frame[cy][cx] color_str = "(" + str(color[0]) + ", " + str(color[1]) + ", " + str(color[2]) + ")" # 計算面積 area = cv.contourArea(contours[cnt]) # 判斷三角形 if shape_type == "三角形": n = Node([cx, cy], area, color) triangles[self.i] = n self.i = self.i + 1 print("-------------------------------------") print("第%d個三角形:"%self.i) print(" 座標 %s 面積: %.3f 顏色: %s " % ((cx, cy), area, color_str)) print("-------------------------------------") cv.imshow("Analysis Result", self.draw_text_info(result)) center = [frame.shape[0] / 2, frame.shape[1] / 2] print("圖片中心位置:%s"%center) print("-------------------------------------") dis = {} # 以接近於圖像中心的三角形做爲根節點, # 距離其最近的三角形做爲其左節點,次近的做爲其右節點 for j in range(4): dis[j] = caculateDistance(center, triangles[j].pos) for j in range(4): for k in range(4): if (dis[j] < dis[k]): temp = dis[k] dis[k] = dis[j] dis[j] = temp temp1 = triangles[k] triangles[k] = triangles[j] triangles[j] = temp1 for j in range(len(triangles)): print(dis[j]) print(triangles[j].pos) tree.addroot(triangles[0]) x = Node([-1, -1], 0, [-1, -1, -1]) triangles[0].Parent = x triangles[0].addLeft(triangles[1]) triangles[1].Parent = triangles[0] triangles[0].addRight(triangles[2]) triangles[2].Parent = triangles[0] triangles[1].addLeft(triangles[3]) triangles[3].Parent = triangles[1] # 3和2號沒有子樹,1號沒有右子樹 y = Node([0, 0], 0, [-1, -1, -1]) triangles[3].addLeft(y) triangles[3].addRight(y) triangles[2].addLeft(y) triangles[2].addRight(y) triangles[1].addRight(y) for k in range(4): print("-------------------------------------") print("第%d節點 面積%.3f 顏色%s 父節點%s 本身節點%s 左子樹%s 右子樹%s "% (k,(triangles[k].area),(triangles[k].color),(triangles[k].Parent.pos),(triangles[k].pos),(triangles[k].left.pos),(triangles[k].right.pos))) return self.shapes def draw_text_info(self, image): c1 = self.shapes['triangle'] cv.putText(image, "triangle: " + str(c1), (10, 20), cv.FONT_HERSHEY_PLAIN, 1.2, (255, 255, 255), 1) return image if __name__ == "__main__": src = cv.imread("D:/picture/11.png") tree = Tree() ld = ShapeAnalysis() ld.analysis(src, tree) cv.waitKey(-1)
圖像處理函數
控制檯輸出結果工具
Python 3.6.4 |Anaconda, Inc.| (default, Jan 16 2018, 10:22:32) [MSC v.1900 64 bit (AMD64)] on win32 runfile('C:/Users/Jackinsun/Desktop/untitled0.py', wdir='C:/Users/Jackinsun/Desktop') start to detect lines... ------------------------------------- 第1個三角形: 座標 (436, 330) 面積: 1447.500 顏色: (195, 195, 195) ------------------------------------- 第2個三角形: 座標 (99, 215) 面積: 1393.500 顏色: (76, 177, 34) ------------------------------------- 第3個三角形: 座標 (315, 208) 面積: 965.500 顏色: (0, 243, 255) ------------------------------------- 第4個三角形: 座標 (241, 101) 面積: 4813.500 顏色: (36, 28, 237) ------------------------------------- 圖片中心位置:[208.0, 277.0] ------------------------------------- 125.39936203984452 [99, 215] 127.3184982632139 [315, 208] 179.06702655709677 [241, 101] 234.07904647789388 [436, 330] ------------------------------------- 第0節點 面積1393.500 顏色[ 76 177 34] 父節點[-1, -1] 本身節點[99, 215] 左子樹[315, 208] 右子樹[241, 101] ------------------------------------- 第1節點 面積965.500 顏色[ 0 243 255] 父節點[99, 215] 本身節點[315, 208] 左子樹[436, 330] 右子樹[0, 0] ------------------------------------- 第2節點 面積4813.500 顏色[ 36 28 237] 父節點[99, 215] 本身節點[241, 101] 左子樹[0, 0] 右子樹[0, 0] ------------------------------------- 第3節點 面積1447.500 顏色[195 195 195] 父節點[315, 208] 本身節點[436, 330] 左子樹[0, 0] 右子樹[0, 0]
Python OpenCV Color Detection Example
Simple shape detection – Opencv with Python 3
OpenCV Python Tutorial For Beginners 25 - Detect Simple Geometric Shapes using OpenCV in Python