本节可以说是本专栏最核心的内容之一,将dalsa相机、yolo、qt相结合,实现一个基于dalsa相机彩图的缺陷检测系统
目录
引言
如果你看了上一节的内容,那么这一节你只需要在上节的基础上添加相应的检测代码即可,注意本节以调用多个dalsa相机为基础,接下来我将详细介绍更改的流程
STEP 1添加初始化模型的代码
yolo之所以能够检测就是因为有以下初始化模型这段代码,我建议你加到下图这个位置
以下是def init_models(self)函数的代码:请按照上述位置添加
def init_models(self):
# 添加你的模型初始化代码,保留原有的model_init函数或将其整合到这里
# ...
parser = argparse.ArgumentParser()
parser.add_argument('--weights', nargs='+', type=str,
default='D:/Python/1.Python/Pycharm2021/yolov5-master/video_check/ruanjian/ruanjian/best(2).pt',
help='model path(s)')
parser.add_argument('--source', type=str, default='data/images', help='file/dir/URL/glob, 0 for webcam')
parser.add_argument('--data', type=str, default='data/coco128.yaml', help='(optional) dataset.yaml path')
parser.add_argument('--img-size', nargs='+', type=int, default=640,
help='inference size h,w')
parser.add_argument('--conf-thres', type=float, default=0.25, help='confidence threshold')
parser.add_argument('--iou-thres', type=float, default=0.45, help='NMS IoU threshold')
parser.add_argument('--max-det', type=int, default=1000, help='maximum detections per image')
parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
parser.add_argument('--view-img', action='store_true', help='show results')
parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')
parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels')
parser.add_argument('--save-crop', action='store_true', help='save cropped prediction boxes')
parser.add_argument('--nosave', action='store_true', help='do not save images/videos')
parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --classes 0, or --classes 0 2 3')
parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')
parser.add_argument('--augment', action='store_true', help='augmented inference')
parser.add_argument('--visualize', action='store_true', help='visualize features')
parser.add_argument('--update', action='store_true', help='update all models')
parser.add_argument('--project', default='runs/detect', help='save results to project/name')
parser.add_argument('--name', default='exp', help='save results to project/name')
parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')
parser.add_argument('--line-thickness', default=3, type=int, help='bounding box thickness (pixels)')
parser.add_argument('--hide-labels', default=False, action='store_true', help='hide labels')
parser.add_argument('--hide-conf', default=False, action='store_true', help='hide confidences')
# 解析命令行参数,并将结果存储在 self.opt 中。打印解析后的参数。
self.opt = parser.parse_args()
print(self.opt)
# 默认使用’--weights‘中的权重来进行初始化
source, weights, view_img, save_txt, imgsz = self.opt.source, self.opt.weights, self.opt.view_img, self.opt.save_txt, self.opt.img_size
# 如果openfile_name_model不为空,则使用openfile_name_model权重进行初始化
# weights = self.model
self.device = select_device(self.opt.device)
self.half = self.device.type != 'cpu'
# 提高模型的运行效率。
cudnn.benchmark = True
# lode model
# 这将载入模型的权重,这些权重将用于后续的操作。
self.model = attempt_load(weights, device=self.device)
# 获取模型中卷积层的最大步幅
stride = int(self.model.stride.max())
# 这行代码使用 check_img_size 函数检查图像的大小(imgsz 变量),并根据步幅 stride 进行调整。这可能是确保输入图像的尺寸与模型的步幅兼容。
self.imgsz = check_img_size(imgsz, s=stride)
# 根据需要将模型的精度设置为半精度。
if self.half:
self.model.half()
# get names and colors
self.names = self.model.module.names if hasattr(
self.model, 'module') else self.model.names
self.colors = [[random.randint(0, 255)
for _ in range(3)] for _ in self.names]
print("model initaial done")
这里需要注意一个细节
parser.add_argument('--weights', nargs='+', type=str,
default='D:/Python/1.Python/Pycharm2021/yolov5-master/video_check/ruanjian/ruanjian/best(2).pt',
help='model path(s)')
这段代码需要更改为你自己的权重路径
STEP 2添加检测部分代码
此部分需要在def show_video_frame(self)函数中更改,之前的代码只是有显示功能,而并没有检测,你可以把下列代码直接替换掉之前的def show_video_frame(self)部分
def show_video_frame(self):
name_list = []
for i, camera in enumerate(self.cameras):
if camera.raw_image is not None:
numpy_image = camera.raw_image.get_numpy_array()
if numpy_image is not None:
cur_frame = np.array(numpy_image, dtype=np.uint8)
img = cv2.cvtColor(cur_frame, cv2.COLOR_GRAY2RGB)
showimg = img
with torch.no_grad():
img = letterbox(img, new_shape=self.opt.img_size)[0]
img = img[:, :, ::-1].transpose(2, 0, 1)
img = np.ascontiguousarray(img)
img = torch.from_numpy(img).to(self.device)
img = img.half() if self.half else img.float()
img /= 255.0
if img.ndimension() == 3:
img = img.unsqueeze(0)
pred = self.model(img, augment=self.opt.augment)[0]
pred = non_max_suppression(pred, self.opt.conf_thres, self.opt.iou_thres,
classes=self.opt.classes, agnostic=self.opt.agnostic_nms)
count1 = 0
accumulated_counts = 0
for j, det in enumerate(pred):
if det is not None and len(det):
det[:, :4] = scale_coords(
img.shape[2:], det[:, :4], showimg.shape).round()
for *xyxy, conf, cls in reversed(det):
count1 += 1
accumulated_counts += count1
label = '%s %.2f' % (self.names[int(cls)], conf)
name_list.append(self.names[int(cls)])
plot_one_box(
xyxy, showimg, label=label, color=self.colors[int(cls)], line_thickness=2)
show = cv2.resize(showimg, (640, 480))
result = cv2.cvtColor(show, cv2.COLOR_BGR2RGB)
show_image = QImage(result.data, result.shape[1], result.shape[0], QImage.Format_RGB888)
if i == 0:
self.label_2.setPixmap(QPixmap.fromImage(show_image))
elif i == 1:
self.label.setPixmap(QPixmap.fromImage(show_image))
elif i == 2:
self.label_3.setPixmap(QPixmap.fromImage(show_image))
STEP 3添加标框代码
当实现上一步你的代码已经可以实现检测了,但是如果没有打框操作你根本不知道他是否已经可以检测了,为此添加标框的代码,找到yolov5中的utils文件夹下的plots.py文件的最后添加以下代码
def plot_one_box(x, img, color=None, label=None, line_thickness=3):
tl = line_thickness or round(0.002 * (img.shape[0] + img.shape[1]) / 2) + 1 # line/font thickness
color = color or [random.randint(0, 255) for _ in range(3)]
# c1 = (x1, y1) = 矩形框的左上角 c2 = (x2, y2) = 矩形框的右下角
c1, c2 = (int(x[0]), int(x[1])), (int(x[2]), int(x[3]))
# cv2.rectangle: 在im上画出框框 c1: start_point(x1, y1) c2: end_point(x2, y2)
cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)
if label:
tf = max(tl - 1, 1) # label字体的线宽 font thickness
t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0]
c2 = c1[0] + t_size[0], c1[1] - t_size[1] -
cv2.rectangle(img, c1, c2, color, -1, cv2.LINE_AA)
cv2.putText(img, label, (c1[0], c1[1] - 2), 0, tl / 3, [225, 255, 255], thickness=tf, lineType=cv2.LINE_AA)
添加完成后就会出检测框但是还有一个问题就是这样的框可能并没有按照实物的大小,所以还需要一个对框进行缩放的代码
STEP 4添加缩放框代码
找到yolov5中utils文件夹中的general.py文件的最后添加以下代码
def scale_coords(img1_shape, coords, img0_shape, ratio_pad=None):
if ratio_pad is None: # calculate from img0_shape
gain = min(img1_shape[0] / img0_shape[0], img1_shape[1] / img0_shape[1])
pad = (img1_shape[1] - img0_shape[1] * gain) / 2, (img1_shape[0] - img0_shape[0] * gain) / 2
else:
gain = ratio_pad[0][0] # 指定比例
pad = ratio_pad[1] # 指定pad值
coords[:, [0, 2]] -= pad[0] # x padding
coords[:, [1, 3]] -= pad[1] # y padding
# 缩放scale
coords[:, :4] /= gain
clip_coords(coords, img0_shape)
return coords
由此,所有的步骤也就都完成了接下来让我们看一下效果
效果展示
如下图可以看出已经显示出了检测框,这里面有我连接了两个相机,由于设备早已发给项目甲方,实验室设备有限,导致第一个相机没有连接光源,所以是黑屏的状态
下面是演示视频B站链接,我是用手晃动,同时随便加了个权重,你们可以自己加入自己的权重检测
标签:parser,help,img,--,self,yolo,argument,相机,dalsa From: https://blog.csdn.net/A1983Z/article/details/136838616由于上述显示界面确实有有些太简陋,所以我打算出一节窗口优化的内容,并打算将打印类别、置信度、个数等信息,将其导入到excel表格中保存起来,尽情期待