基于web的智能视频监控系统<六> -- 部署

文章目录

1. 系统的环境

需要的环境

  • python 3.6+
  • 相关的库
    • https://github.com/zk2ly/Smoke_Fire_Detection 用于火焰检测的三方库文件
    • opencv-python 3.4.4.19 这个版本不宜过高,否则可能报错
    • torch 1.8.1
    • numpy 版本无所谓
  • 数据库使用项目自带的sqlite(mysql部分使用麻烦,没使用)
  • 其他环境
    • 百度AI的人脸识别接口
    • 正版pycharm (没有也可以直接修改文件,使用命令行运行)

2. 项目的结构

使用了Django进行开发(比spring boot什么的简单多了),项目结构即经典的Django项目结构,最常用的几个文件如下:

  • view.py 相当于controller,如果没有三层结构里面可以写数据操作和逻辑代码
  • url 相当于xml的映射文件,把前端的请求url映射到view.py中的类或者方法中。
  • model 建立数据库的entity
  • settings 系统的配置文件,包括数据库的选用,一些默认路径的映射等。

基于web的智能视频监控系统<六> -- 部署

其他结构介绍

  • utils 就是自己写的方法包括人脸识别、用户验证码和火焰检测的代码
  • static和template是网页的相关内容
  • migration 是数据库迁移的内容,建表后自动生成
  • service 是自己写的文件夹,但是只作为测试使用,并未真正的前后端分离
    static 中的fire和img 是系统保存火焰图片和系统录像的文件夹

3. 部署

由于本人的懒惰,把项目放在带有中文名的文件夹中不想移动,所以使用了不少绝对路径,如果有需要可以进行修改。

接下来先说使用pycharm运行项目的过程,然后是一些路径问题

3.1 pycharm 导入项目

  1. 使用pycharm打开项目
  2. 配置项目的解释器 file -> settings ->搜索project Interpreter

基于web的智能视频监控系统<六> -- 部署

基于web的智能视频监控系统<六> -- 部署

  1. 点击设置 -> add -> 选择自己的python.exe,(new 还是 exit都可以)

基于web的智能视频监控系统<六> -- 部署
基于web的智能视频监控系统<六> -- 部署4. 如果没有自动导入Django就手动导入

基于web的智能视频监控系统<六> -- 部署
5. 手动导入时候按照以下步骤,其中4 url可以修改成http://127.0.0.1:8000/firstWEB/login直接进入登录页面,不改也可以,这个是项目默认的运行地址。
基于web的智能视频监控系统<六> -- 部署

到这pycharm 的导入就完成了。剩下说一下需要修改的绝对路径问题

3.2 路径问题

3.2.1 人脸识别登录方面

  1. 在项目中utils 中的faceRecgnize中需要百度AI的账户信息
def createCli():
    """ 你的 APPID AK SK """
    APP_ID = ''
    API_KEY = ''
    SECRET_KEY = ''

    client = AipFace(APP_ID, API_KEY, SECRET_KEY)
    return client
  1. 这个方法中需要个人头像照片,其路径为 imgpath
def faceRcn(face):
    client = createCli()
    # img = open('1.jpeg', 'rb').read()
    # bimg1 = base64.b64encode(img)
    # jimg1 = str(bimg1,'utf-8')
    # img = open('2.jpeg', 'rb').read()
    # bimg2 = base64.b64encode(img)
    # jimg2 = str(bimg2,'utf-8')

    imgpath = 'F:\\各种文件\\pythonFile\\Web\\web\\firstWEB\\utils\\1.jpg'
这种是单人登录,如果想要多人登录,可以写一个数组放入图片路径,
循环来进行调用接口,判断是否有图片与采取到的用户人脸的相似度大于某一个特定
值,如果有则登录成功。
 
这里只写想法,由于只是一个demo性的系统所以没有实现。

3.2.2 火焰检测方面

由于将第三方库直接放入项目中会编译出错,所以使用了系统调用的方法来进行火焰的识别。流程为:

  1. 先将视频提取的图片存入img_name
  2. 使用系统调用传递 img_name,之后第三方库读取、识别图片存回
    为了简单起见,此处这两个路径我都写的绝对路径

注意1

由于第三方库文件中我使用了imread读取内容,所以img_name一定不能有中文名

注意2

如果不想修改此处,需要在f盘下建立fireD文件夹

注意3

cmd  python后面是第三方库文件的绝对路径
def getSolveImg(img, name) : # 图片就是前端的图片, img_name是刚获取图片之后的保存路径(文件读取路径),新的保存路径应该放在fire里面
    # img = cv2.imread(img_name) #要么直接读取,要么经过编码,这里是直接读取
    # 想一想怎么改成相对路径
    img_name = 'F:\\fireD\\' + str(name) + '.jpg' #读取路径
    cmd = "python F:\\各种文件\\pythonFile\\Web\\Smoke_Fire_Detection-main\\smoke_file_obj.py --img_name " + img_name
    # print(cmd)
    a = os.popen(cmd)

第三方库文件 smoke_file_obj.py需要把第一行中的weight修改成绝对路径,否则有可能找不到文件,可以有中文名

default=r'F:\各种文件\pythonFile\Web\Smoke_Fire_Detection-main\weights\smoke.pt'

另外,第三方库的修改文件代码

我使用了系统调用,所以需要main和solve函数
另外电脑GPU掉用不成功修改成这个代码
det = det.to(device).data.cpu().numpy()

import argparse

import  base64
from models.experimental import *
from utils.datasets import *
from utils.general import *
from utils import torch_utils
import sys


class Smoke_File_Detector():
    def __init__(self):
        parser = argparse.ArgumentParser()
        parser.add_argument('--weights', nargs='+', type=str, default=r'F:\各种文件\pythonFile\Web\Smoke_Fire_Detection-main\weights\smoke.pt', help='model.pt path(s)')
        parser.add_argument('--source', type=str, default='inference/images', help='source')  # file/folder, 0 for webcam
        parser.add_argument('--img-size', type=int, default=640, help='inference size (pixels)')
        parser.add_argument('--conf-thres', type=float, default=0.25, help='object confidence threshold')
        parser.add_argument('--iou-thres', type=float, default=0.45, help='IOU threshold for NMS')
        parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
        parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --class 0, or --class 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('--img_name', type=str)
        self.opt = parser.parse_args()

        self.device = torch_utils.select_device(self.opt.device)

        # Initialize
        self.half = self.device.type != 'cpu'  # half precision only supported on CUDA

        # Load models
        self.model = attempt_load(self.opt.weights, map_location=self.device)
        self.imgsz = check_img_size(self.opt.img_size, s=self.model.stride.max())
        if self.half:
            self.model.half()

    # 本地调用
    def detect_test(self,test_list):
        for i,img in enumerate(test_list):
            im0 = img
            img = letterbox(img, new_shape=self.opt.img_size)[0]
            img = img[:, :, ::-1].transpose(2, 0, 1)  # BGR to RGB, to 3x416x416
            img = np.ascontiguousarray(img)  # faster

            # Run inference
            img = torch.from_numpy(img).to(self.device)
            img = img.half() if self.half else img.float()  # uint8 to fp16/32
            img /= 255.0  # 0 - 255 to 0.0 - 1.0
            if img.ndimension() == 3:
                img = img.unsqueeze(0)
            if i == 0:
                batch_img = img
            else:
                batch_img = torch.cat([batch_img,img],axis = 0)

        pred = self.model(batch_img, augment=self.opt.augment)[0]

        # Apply NMS
        pred = non_max_suppression(pred, self.opt.conf_thres, self.opt.iou_thres, classes=self.opt.classes, agnostic=self.opt.agnostic_nms)

        # Process detections
        names = self.model.module.names if hasattr(self.model, 'module') else self.model.names
        batch_results = []
        for i, det in enumerate(pred):  # detections per image
            results = []
            if det is not None and len(det):
                # Rescale boxes from img_size to im0 size
                det[:, :4] = scale_coords(batch_img.shape[2:], det[:, :4], im0.shape).round()
                device = ('cuda' if torch.cuda.is_available() else 'cpu')
                det = det.to(device).data.cpu().numpy()
                for *xyxy, conf, cls in det:
                    w = xyxy[2]-xyxy[0]
                    h = xyxy[3]-xyxy[1]
                    result = {'bbox':xyxy, 'label':names[int(cls)], 'conf':conf}
                    results.append(result)

            batch_results.append(results)

        # print(batch_results)
        return batch_results

    # server调用
    def detect(self, **kwargs):
        params = kwargs
        test_list = [params["img"]]
        for i,img in enumerate(test_list):
            im0 = img
            img = letterbox(img, new_shape=self.opt.img_size)[0]
            img = img[:, :, ::-1].transpose(2, 0, 1)  # BGR to RGB, to 3x416x416
            img = np.ascontiguousarray(img)

            # Run inference
            img = torch.from_numpy(img).to(self.device)
            img = img.half() if self.half else img.float()  # uint8 to fp16/32
            img /= 255.0  # 0 - 255 to 0.0 - 1.0
            if img.ndimension() == 3:
                img = img.unsqueeze(0)
            if i == 0:
                batch_img = img
            else:
                batch_img = torch.cat([batch_img,img],axis = 0)

        pred = self.model(batch_img, augment=self.opt.augment)[0]

        # Apply NMS
        pred = non_max_suppression(pred, self.opt.conf_thres, self.opt.iou_thres, classes=self.opt.classes, agnostic=self.opt.agnostic_nms)

        # Process detections
        names = self.model.module.names if hasattr(self.model, 'module') else self.model.names
        batch_results = []
        for i, det in enumerate(pred):  # detections per image
            results = []
            if det is not None and len(det):
                # Rescale boxes from img_size to im0 size
                det[:, :4] = scale_coords(batch_img.shape[2:], det[:, :4], im0.shape).round()
                device = ('cuda' if torch.cuda.is_available() else 'cpu')
                det = det.to(device).data.cpu().numpy()
                for *xyxy, conf, cls in det:
                    w = xyxy[2]-xyxy[0]
                    h = xyxy[3]-xyxy[1]
                    result = {'bbox':xyxy, 'label':names[int(cls)], 'conf':conf}
                    results.append(result)

            batch_results.append(results)

        # print(batch_results)
        return batch_results

    # 返回框好的图片
    def solveFireImg(self, img, img_name):
        ls = self.detect_test([img])[0]
        # print(ls)
        flag = False
        for dic in ls:
            flag = True
            if(dic['label'] == 'fire'):
                rec = dic['bbox']
                cv2.rectangle(img, (int(rec[0]), int(rec[1])), (int(rec[2]), int(rec[3])), (0, 255, 0), 3)
            if(dic['label'] == 'smoke'):
                rec = dic['bbox']
                cv2.rectangle(img, (int(rec[0]), int(rec[1])), (int(rec[2]), int(rec[3])), (0, 0, 255), 3)
        if(flag) : #有火焰,保存图片
            cv2.imwrite(img_name, img) # 使用传入的参数自动覆盖原来的图片
        return img




if __name__ == "__main__":
    import cv2
    img_name = sys.argv[2]
    img = cv2.imread(img_name)

    det = Smoke_File_Detector()
    arr = det.detect_test([img])[0]
    print(arr)
    # content = det.solveFireImg(img, img_name)
    # # cv2.imshow('test', content)
    # # cv2.waitKey(0)
    # # 保存图片
    # t = time.time()
    # # name = int(round(t * 1000))
    # # img_name='F:\\img\\'+str(name)+'.jpg'
    # img1 = cv2.imencode('.jpg', content)[1]
    # back_2 = base64.b64encode(img1)
    # back_3 = str(back_2, encoding="utf-8")
    # print(back_3, end="")



    """以下的内容一定要注释掉"""
    #测试保存的明亮航参数保存图片
    # img_name = sys.argv[2]
    # print(type(back_2))
    # print("图片")
    # print(img_name)
    # cv2.imwrite(img_name, content)

    # 测试如果直接输出会怎么样

另外火焰图片存储在了static/fire文件夹中,如果修改此处,需要修改许多地方,不建议修改,同时使用了相对路径,也无需修改。

3.3.3 视频回放的存储路径

由于此处使用了相对路径,所以不进行过多的叙述,同火焰图片存放有相同的道理,不建议修改。

上一篇:学习记录 python_opencv的人脸识别


下一篇:格基础知识