项目流程讲解
环境搭建参考
http://www.bilibili996.com/Course?id=5987479000234
大概流程
安装好环境后,运行:
python main.py
main.py有两个demo,demo1是读取工程file文件夹里面的图片操作,demo2是读取视频的操作,最终目标将图片传给app_seg.ReadAngle(srcImage),代码如下:
from utils.general import cv2
import app_seg
import os
# 获取指定路径下的所有图片
def file_name(file_dir):
L = []
for root, dirs, files in os.walk(file_dir):
for file in files:
if os.path.splitext(file)[1] == '.jpg' or os.path.splitext(file)[1] == '.png':
L.append(file)
return L
# 按一张张图片进行检测
def demo1():
Names = file_name('file')
for ImgName in Names:
# 读取一张图片,imread方法无法读取带中文名的文件
# srcImage = cv2.imdecode(np.fromfile('file/' + ImgName, dtype=np.uint8), -1)
# srcImage = cv2.imread('file/' + ImgName)
srcImage = cv2.imread('file/000654.jpg')
if srcImage is None:
continue
app_seg.ReadAngle(srcImage)
cv2.waitKey(0)
break
# 读取视频进行检测
def demo2():
cap = cv2.VideoCapture('file\\crop1.mp4') # 读取视频
# cap.set(1, 771)
cap.set(1, 500)
# cap = cv2.VideoCapture(0, cv2.CAP_DSHOW) # 读取摄像头
while True:
ret, capImage = cap.read() # ret 返回一个布尔值 True/False
if not ret:
break
FRAME_NOW = cap.get(cv2.CAP_PROP_POS_FRAMES) # 第0帧
print('当前帧数', FRAME_NOW) # 当前帧数 0.0
app_seg.ReadAngle(capImage)
if cv2.waitKey(1) == 27:
break
if __name__ == '__main__':
demo2()
app_seg.py流程如下:
1、代码默认device='0'是调用GPU,如果要调用CPU,则改为device='cpu'即可。
# 外部调用入口,传入一张图片
def ReadAngle(capImage):
# 计算耗时
e1 = cv2.getTickCount()
# 调用检测方法
ret = run(capImage, "weights/best.pt", device='0')
# 计算耗时
e2 = cv2.getTickCount()
t = (e2 - e1) / cv2.getTickFrequency() # 时钟频率或者每秒钟的时钟数
print(f'{ret} {t:.3f}s')
return ret
2、进行目标推理,得到如下结果:app_seg.py文件大概365行位置,代码是屏蔽的,需要自行开启
# 轮廓掩膜,显示预测区域
annotator.masks(masks, colors=[colors(x, True) for x in det[:, 5]], im_gpu=im[0], alpha=0.5)
for j, (*xyxy, conf, cls) in enumerate(reversed(det[:, :6])):
c = int(cls)
label = f'{c} {conf:.2f}'
print(str(c) + " 结果:" + label)
annotator.box_label(xyxy, label, color=colors(c, True))
cv2.imshow("tempImg", srcImage)
cv2.waitKey(0)

3、调用zero = GetZero(srcImage, names, det, maskss)方法,计算仪表刻度与指针角度的比例关系,这样可以将角度数据转换成仪表的刻度值。
就是下面这段代码,可以将BindMasks方法针对仪表刻度的识别结果显示出来,并通过刻度的角度,来估算每个刻度值大概占用的角度。
这也是为什么这个算法没法处理刻度连起来的仪表,需要用其他办法来计算每个刻度所占用的角度。

预测结果如下,黄色线是起始刻度

然后以红色线为基准,计算每个刻度的角度。

ang输出如下,这些角度数据都是相对红色线条为基准的角度,不能直接使用。

我们将所有角度数据保存在PointList数组中,我们最终的目的是为了计算相邻两条绿色线条之间的夹角,然后找出出现最多的一个角度作为刻度之间的角度。而绿色线角度的误差控制在±1.5度。

角度计算如下:

结果如下:

其中“unit = 0.1 / 6.779626377240847”表示:每度有多少bar。
最终效果就是下面这样,将角度值转成对应的bar数值。
