OpenCV-⼏何形状颜⾊识别
⽂章⽬录
题⽬
请编写程序将图像Image中的三⾓形到,并且以接近于图像中⼼的三⾓形作为根节点,距离其最近的三⾓形作为其左节点,次近的作为其右节点,建⽴⼀个⼆叉树来表⽰和存储图中的三⾓形,其中⼆叉树中每个节点包括:三⾓形的位置、其⽗节点的位置(若为个节点,坐标为(-1,-1))、三⾓形的颜⾊、三⾓形的⾯积。
请输出⼆叉树
思路
1. 先先识别三⾓形,就先转成⼆值图像, 然后使⽤轮廓发现findContours相关函数,提取与绘制轮廓,最后⽤approxPolyDP对其进
⾏轮廓逼近,
2. 然后对三⾓形到中⼼点 ,需要⽤moments计算⼀阶⼏何距得到指定轮廓的中⼼位置
3. 然后的到的三⾓形中⼼位置坐标可以⽤来得出三⾓形的坐标和颜⾊
4. “以接近于图像中⼼的三⾓形作为根节点,距离其最近的三⾓形作为其左节点,次近的作为其右节点”在构成⼆叉树的时候(我印象
中学习机器学习的时候貌似记得有个KNN算法,实现有点⿇烦),这⾥我是直接⽤两点之间开⽅计算距离。
5. 后⾯⼆叉树的,先按照距离进⾏排序,然后插⼊节点
6. 打印节点
代码
# -*- 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.pos = pos
self.left =None
self.right =None
self.Parent =None
#添加左⼦树
def addLeft(self, l):
self.left = l
rectangle函数opencv# 添加右⼦树
def addRight(self, r):
self.right = r
# 添加⽗节点
def GetParent(self):
return self.Parent
#定义树
class Tree:
def__init__(self):
< =None
def addroot(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 \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.p os),(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)
结果
图像处理
控制台输出结果

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。