车辆工程 智能驾驶
3 人赞同了该文章
图形识别也可以理解为轮廓识别。轮廓可以简单认为成将连续的点(连着边界)连在一起的曲线,具有相同的颜色或者灰度。
(1)为了更加准确,要使用二值化图像。
(2)在寻找轮廓之前,要进行阈值化处理或者 Canny 边界检测。
(3)绘制轮廓
(4)轮廓的近似
(5)查找轮廓的不同特征 ①角点数 ②面积
通过检测角点来判定是什么形状,当角点无数多时认为为圆形。
当然此思路不适合做复杂环境下的图像检测容易误判,在识别特殊规则的图形比较准确,还有待改进。如有不足,感谢指出。
import cv2 as cv
import numpy as np
global a
class ShapeAnalysis:
def __init__(self):
self.shapes = {'three': 0, 'four': 0, 'five':0, 'six': 0, 'circles': 0}
def analysis(self, frame):
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, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
cv.imshow("input image", frame)
#函数cv.findContours有三个参数,第一个是输入图像,第二个是轮廓检索模式,第三个是轮廓近似方法
out_binary, contours, hierarchy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
#shape数组为面积范围
areas = np.zeros(shape=[1, 7000])
areaj = np.zeros(shape=[1, 7000])
aread = np.zeros(shape=[1, 7000])
areaw = np.zeros(shape=[1, 7000])
areal = np.zeros(shape=[1, 7000])
areayuan = np.zeros(shape=[1, 7000])
i = 1
global a
for cnt in range(len(contours)):
# 提取与绘制轮廓
cv.drawContours(result, contours, cnt, (0, 255, 0), 2)
# 轮廓逼近
#epsilon,它是从原始轮廓到近似轮廓的最大距离。它是一个准确度参数
epsilon = 0.01 * cv.arcLength(contours[cnt], True)
#角点计算
approx = cv.approxPolyDP(contours[cnt], epsilon, True)
# 分析几何形状
corners = len(approx)
shape_type = ""
if corners == 3:
count = self.shapes['three']
count = count+1
self.shapes['three'] = count
#shape_type = "三角形"
area_3 = cv.contourArea(contours[cnt])
areas[0, i] = area_3
if corners == 4:
count = self.shapes['four']
count = count + 1
self.shapes['four'] = count
#shape_type = "four形"
area_4 = cv.contourArea(contours[cnt])
areaj[0, i] = area_4
if corners == 5:
count = self.shapes['five']
count = count + 1
self.shapes['five'] = count
#shape_type = "five形"
area_5 = cv.contourArea(contours[cnt])
areaw[0, i] = area_5
#if corners == 6:
# count = self.shapes['six']
# count = count + 1
# self.shapes['six'] = count
# #shape_type = "six形"
# area_6 = cv.contourArea(contours[cnt])
# areal[0, i] = area_6
if corners >= 50:
count = self.shapes['circles']
count = count + 1
self.shapes['circles'] = count
#shape_type = "圆形"
area_y = cv.contourArea(contours[cnt])
areayuan[0, i] = area_y
i = i + 1
area_S = areas.max()
area_J = areaj.max()
area_Y = areayuan.max()
area_D = aread.max()
area_W = areaw.max()
area_L = areal.max()
shape_types = "T" #三角形
shape_typej = "F" #矩形
shape_typey = "Y" #圆形
shape_typew = "F" #five形
shape_typel = "S" #six形
if area_S >5000:
a = shape_types
if area_J >5000:
a = shape_typej
if area_Y >5000:
a = shape_typey
if area_W>5000:
a = shape_typew
if area_L >5000:
a = shape_typel
return self.shapes
if __name__ == "__main__":
cap = cv.VideoCapture(0)
success, img = cap.read()
cv.imshow('frame',img)
cv.imwrite("/home/car/AI_match/4.jpg", img)
src = cv.imread("/home/car/AI_match/4.jpg")
ld = ShapeAnalysis()
ld.analysis(src)
print(a)
# cv.waitKey(0)
# cv.destroyAllWindows()