将此代码全部转换成python-opencv的形式,并且不删减任何部分,通俗易懂。
时间: 2024-10-22 16:28:32 浏览: 33
将 C++ 代码转换为 Python 代码涉及一些语法和库函数的调整。以下是完整的 Python 版本的代码,保留了原有的逻辑和功能:
```python
import cv2
import numpy as np
import math
# 定义常量
jifen = 5
daodianju = 3
feichezhanbi = 0.73
yuanhuanyuzhi = 40
yuanhuanjingdu = 10
kuanzeng = 90
kuanzeng2 = 70
CAMERA_H = 60
CAMERA_W = 94
OUT_H = 60
OUT_W = 94
# 全局变量
shiziji = 0
banmasign = 0
imgSour = None
class Up:
def __init__(self):
self.dian = cv2.Point()
self.que = 0
# 图片或视频二值化(动态阈值)
def er_zhi(imgxiu):
imgCvt = cv2.cvtColor(imgxiu, cv2.COLOR_BGR2GRAY)
imgTemp = cv2.GaussianBlur(imgCvt, (5, 5), 0)
_, imgThr = cv2.threshold(imgTemp, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
cv2.imshow("二值化", imgThr)
return imgThr
# 画出赛道两侧线和中线
def che_dao_xian(imgEr):
global shiziji, banmasign, imgSour
imgCan = imgDil = None
shizipan = 0
yuanhuanzuosign = 0
yuanhuanyousign = 0
yuanhuan = []
banmapan = 0
banmasign = 0
banmadi = [0, 0, 0]
banmashang = [0, 0, 0]
high = int(imgEr.shape[0] * feichezhanbi)
# 获取每一列白色点数据
lieBais = [0] * imgEr.shape[1]
for x in range(imgEr.shape[1]):
for y in range(high - 1, -1, -1):
if imgEr[y, x] != 0:
lieBais[x] += 1
else:
break
if x > 0 and abs(lieBais[x] - lieBais[x - 1]) >= 60:
banmasign += 1
if banmasign >= 6:
banmapan = 1
# 左右寻最长白条
maxzuo = [0, 0]
maxyou = [0, 0]
for a in range(len(lieBais)):
if lieBais[a] > maxzuo[1]:
maxzuo[0] = a
maxzuo[1] = lieBais[a]
for a in range(len(lieBais) - 1, -1, -1):
if lieBais[a] > maxyou[1]:
maxyou[0] = a
maxyou[1] = lieBais[a]
# 找车道线
chushi = 0
chuju = 0
shiziZuox = 0
shiziZuoy = 0
shiziYoux = 0
zuoDao = []
youDao = []
zhongXian = []
for y in range(high - 1, high - maxzuo[1], -1):
zuox = maxzuo[0]
for x in range(maxzuo[0], -1, -1):
if imgEr[y, x] != 0 and imgEr[y, x - 1] == 0:
if len(zuoDao) >= 1:
if abs(x - zuoDao[-1].dian.x) <= daodianju and abs(y - zuoDao[-1].dian.y) <= daodianju:
zuoDao.append(Up())
zuoDao[-1].dian = cv2.Point(x, y)
zuoDao[-1].que = 0
zuox = x
if banmapan == 1:
banmapan = 2
break
else:
zuox = x
zuoDao.append(Up())
zuoDao[-1].dian = cv2.Point(x, y)
zuoDao[-1].que = 0
break
elif imgEr[y, x] != 0 and imgEr[y, x - 1] != 0 and imgEr[y, x - 2] != 0:
shiziZuox += 1
if x - 3 == 0:
break
tempx = maxyou[0] - 4
for x in range(maxyou[0] - 4, imgEr.shape[1]):
if imgEr[y, x] != 0 and imgEr[y, x + 1] == 0:
if len(youDao) >= 1:
if abs(x - youDao[-1].dian.x) <= daodianju and abs(y - youDao[-1].dian.y) <= daodianju:
youDao.append(Up())
youDao[-1].dian = cv2.Point(x, y)
youDao[-1].que = 0
tempx = x
break
else:
tempx = x
youDao.append(Up())
youDao[-1].dian = cv2.Point(x, y)
youDao[-1].que = 0
break
elif imgEr[y, x] != 0 and imgEr[y, x + 1] != 0 and imgEr[y, x + 2] != 0:
shiziYoux += 1
if x + 3 == imgEr.shape[1] - 1:
break
if imgEr.shape[1] - tempx >= 80:
if banmapan == 2 and imgEr[y, tempx + 62] != 0 and imgEr[y, tempx + 63] != 0 and imgEr.shape[0] - maxzuo[1] <= 80:
banmadi[0] = zuox
banmadi[1] = tempx
banmadi[2] = y
banmapan = 3
if chuju == 0:
chuju = tempx - zuox
if abs(shiziZuox - maxzuo[0]) <= 5 and abs(imgEr.shape[1] - maxyou[0] + 4 - shiziYoux) <= 5:
shizipan = 1
# 判断圆环存在否,及其位置
if abs(len(zuoDao) - len(youDao)) >= yuanhuanyuzhi:
ji1 = 0
ji2 = 0
signs = 0
# 左圆环
if len(zuoDao) < len(youDao):
zuominx = 999999
for n in range(len(zuoDao)):
if zuominx > zuoDao[n].dian.x:
zuominx = zuoDao[n].dian.x
for n in range(len(youDao)):
signs = 0
for x in range(youDao[n].dian.x, max(zuominx - 5, 1), -1):
if imgEr[youDao[n].dian.y, x] != 0 and imgEr[youDao[n].dian.y, x - 1] == 0:
if yuanhuanyousign == 1 and ji1 >= 5:
yuanhuanyousign = 2
yuanhuanweidian[1].x = youDao[n - 5].dian.x - kuanzeng
yuanhuanweidian[1].y = youDao[n - 5].dian.y
ji1 = 0
elif yuanhuanyousign == 3 and ji1 >= 5:
yuanhuanyousign = 4
ji1 = 0
break
signs = 1
ji1 += 1
ji2 = 0
if signs == 0:
if yuanhuanyousign == 0 and ji2 >= 5:
yuanhuanyousign = 1
yuanhuanweidian[0].x = youDao[n - 5].dian.x - kuanzeng
yuanhuanweidian[0].y = youDao[n - 5].dian.y
ji2 = 0
elif yuanhuanyousign == 2 and ji2 >= 5:
yuanhuanyousign = 3
ji2 = 0
ji2 += 1
ji1 = 0
# 右圆环
else:
youmaxx = 0
for n in range(len(youDao)):
if youmaxx < youDao[n].dian.x:
youmaxx = youDao[n].dian.x
for n in range(len(zuoDao)):
signs = 0
for x in range(zuoDao[n].dian.x, youmaxx):
if imgEr[zuoDao[n].dian.y, x] != 0 and imgEr[zuoDao[n].dian.y, x + 1] == 0:
if yuanhuanzuosign == 1 and ji1 >= yuanhuanjingdu:
yuanhuanzuosign = 2
yuanhuanweidian[1].x = zuoDao[n - 5].dian.x + kuanzeng2
yuanhuanweidian[1].y = zuoDao[n - 5].dian.y
ji1 = 0
elif yuanhuanzuosign == 3 and ji1 >= yuanhuanjingdu:
yuanhuanzuosign = 4
ji1 = 0
break
signs = 1
ji1 += 1
ji2 = 0
if signs == 0:
if yuanhuanzuosign == 0 and ji2 >= yuanhuanjingdu:
yuanhuanzuosign = 1
yuanhuanweidian[0].x = zuoDao[n - 5].dian.x + kuanzeng2 + 10
yuanhuanweidian[0].y = zuoDao[n - 5].dian.y
ji2 = 0
elif yuanhuanzuosign == 2 and ji2 >= yuanhuanjingdu:
yuanhuanzuosign = 3
ji2 = 0
ji2 += 1
ji1 = 0
# 十字判断
if shizipan:
shiziji += 1
if shiziji >= 3:
shiziji = 0
cv2.putText(imgSour, "CROSS", (10, 40), cv2.FONT_HERSHEY_COMPLEX, 0.7, (0, 0, 255), 2)
# 斑马线判断
if banmapan == 3:
cv2.putText(imgSour, "BANMA_WIRES", (10, 40), cv2.FONT_HERSHEY_COMPLEX, 0.7, (0, 0, 255), 2)
cv2.line(imgSour, (banmadi[0], banmadi[2]), (banmadi[1], banmadi[2]), (255, 0, 255), 3.5)
# 圆环判断
if yuanhuanzuosign == 4:
cv2.putText(imgSour, "right circular", (10, 40), cv2.FONT_HERSHEY_COMPLEX, 0.7, (0, 0, 255), 2)
for n in range(2):
cv2.line(imgSour, (imgEr.shape[1] - 1, yuanhuanweidian[n].y), (yuanhuanweidian[n].x, yuanhuanweidian[n].y), (255, 0, 255), 3.5)
elif yuanhuanyousign == 4:
cv2.putText(imgSour, "left circular", (10, 40), cv2.FONT_HERSHEY_COMPLEX, 0.7, (0, 0, 255), 2)
for n in range(2):
cv2.line(imgSour, (0, yuanhuanweidian[n].y), (yuanhuanweidian[n].x, yuanhuanweidian[n].y), (255, 0, 255), 3.5)
# 找中线
sizes = min(len(zuoDao), len(youDao))
bestZhongxian = []
niheZhongxian = []
kai = 0
zhongx = 0
zhongy = 0
for n in range(sizes):
if zuoDao[n].que == 0 and youDao[n].que == 0:
zhongx = (zuoDao[n].dian.x + youDao[n].dian.x) // 2
zhongy = (zuoDao[n].dian.y + youDao[n].dian.y) // 2
if kai == 0:
zhongXian.append(Up())
zhongXian[-1].dian = cv2.Point(zhongx, zhongy)
zhongXian[-1].que = 0
kai = 1
elif abs(zhongx - zhongXian[-1].dian.x) <= daodianju and abs(zhongy - zhongXian[-1].dian.y) >= 2:
zhongXian.append(Up())
zhongXian[-1].dian = cv2.Point(zhongx, zhongy)
zhongXian[-1].que = 0
# 最小二乘法拟合中线
for c in range(0, len(zhongXian), jifen):
if c + jifen >= len(zhongXian):
break
aa = bb = xx = yy = xy = xfangs = 0
for n in range(c, c + jifen):
xy += zhongXian[n].dian.x * zhongXian[n].dian.y
xfangs += zhongXian[n].dian.x ** 2
xx += zhongXian[n].dian.x
yy += zhongXian[n].dian.y
xx /= jifen
yy /= jifen
bb = (xy - jifen * xx * yy) / (xfangs - jifen * xx ** 2)
aa = yy - bb * xx
zuomin = 999999
zuomax = 0
youmin = 999999
youmax = 0
for n in range(c, c + jifen):
if zuomin > zuoDao[n].dian.x:
zuomin = zuoDao[n].dian.x
if zuomax < zuoDao[n].dian.x:
zuomax = zuoDao[n].dian.x
for n in range(c, c + jifen):
if youmin > youDao[n].dian.x:
youmin = youDao[n].dian.x
if youmax < youDao[n].dian.x:
youmax = youDao[n].dian.x
for x in range(zuomin, youmax + 1):
y = int(bb * x + aa)
if y <= zhongXian[c].dian.y and y >= zhongXian[c + jifen].dian.y and abs(x - (zuomin + youmax) / 2) <= 3:
niheZhongxian.append(cv2.Point(x, y))
# 拟合中线
for n in range(len(niheZhongxian) - 1):
cv2.line(imgSour, niheZhongxian[n], niheZhongxian[n + 1], (0, 255, 0), 4)
# 原始中线
for n in range(len(zhongXian) - 1):
cv2.circle(imgSour, zhongXian[n].dian, 2, (0, 255, 0), -1)
cv2.line(imgSour, zhongXian[n].dian, zhongXian[n + 1].dian, (0, 255, 0), 4)
# 画出车道线
for n in range(len(zuoDao)):
cv2.circle(imgSour, zuoDao[n].dian, 2, (255, 0, 0), -1)
for n in range(len(youDao)):
cv2.circle(imgSour, youDao[n].dian, 2, (0, 0, 255), -1)
return imgSour
# 逆透视
def ni_tou():
angle = 0.8
dep = 3.8
prop_j = 1
prop_i = 0
j_large = 1.6
i_abodon = 7
hight = 50
sin_a = math.sin(angle)
cos_a = math.cos(angle)
# 初始化摄像头坐标系
map_square = np.zeros((CAMERA_H, CAMERA_W, 2), dtype=np.float32)
for i in range(CAMERA_H):
for j in range(CAMERA_W):
map_square[i, j, 0] = (CAMERA_H / 2 - i + 0.5) / 10
map_square[i, j, 1] = (j - CAMERA_W / 2 + 0.5) / 10
# 横向拉伸
for i in range(CAMERA_H):
for j in range(CAMERA_W):
map_square[i, j, 1] = map_square[i, j, 1] * (1 * (CAMERA_H - 1 - i) + (1 / prop_j) * i) / (CAMERA_H - 1)
# 逆透视变换
for i in range(CAMERA_H):
for j in range(CAMERA_W):
xg = map_square[i, j, 1]
yg = map_square[i, j, 0]
y0 = (yg * dep + hight * cos_a * yg + hight * dep * sin_a) / (dep * cos_a - yg * sin_a)
zt = -y0 * sin_a - hight * cos_a
x0 = xg * (dep - zt) / dep
map_square[i, j, 1] = x0
map_square[i, j, 0] = y0
# 横坐标缩放
prop_x = (OUT_W - 1) / (map_square[i_abodon, CAMERA_W - 1, 1] - map_square[i_abodon, 0, 1])
for i in range(CAMERA_H):
阅读全文