<repo_name>jinzhu6/Realtime_Flaw_Object<file_sep>/Database.py
import sqlite3 as lite
from enum import Enum

from PyQt5.QtGui import QPixmap

class Database():
    __instance = None

    @staticmethod
    def getInstance():
        if Database.__instance is None:
            Database()
        return Database.__instance

    def __init__(self):
        if Database.__instance is not None:
            raise Exception("This class is a singleton!")
        else:
            Database.__instance = self
            self.con = lite.connect("database/Mainbase.db")
    def getCaminfo(self,ID):
        if ID is not None:
            command = "select camid, coordinate_x, coordinate_y,rate,camip,camport,username,userpassword from camera where camid = '{}'".format(str(ID))
        else:
            command = "select camid, coordinate_x, coordinate_y,rate,camip,camport,username,userpassword from camera where camid = 'cam_01'"
        cur = self.con.cursor()
        cur.execute(command)
        rows = cur.fetchall()
        ret = [(row[4], row[5], row[6], row[7],row[0], row[3], row[1], row[2]) for row in rows]
        cur.close()
        return ret

    def getCamurl(self,ID):
        if ID is not None:
            command = "select camurl from camera where camid = '{}'".format(str(ID))
        else:
            command = "select camurl from camera where camid = 'cam_01'"
        cur = self.con.cursor()
        cur.execute(command)
        rows = cur.fetchall()
        ret = [(row[0]) for row in rows]
        cur.close()
        return ret

    def getOpenflag(self,ID):
        if ID is not None:
            command = "select isopen from camera where camid = '{}'".format(str(ID))
        else:
            command = "select isopen from camera where camid = 'cam_01'"
        cur = self.con.cursor()
        cur.execute(command)
        rows = cur.fetchall()
        ret = [(row[0]) for row in rows]
        cur.close()
        return ret

    def updataCaminfo(self,camid='cam_01',coordinate_x=0.0,coordinate_y=0.0,rate=1,camip='',camport='',username='',userpassword=''):
        sql= "update camera set coordinate_x=?,coordinate_y=?,rate=?,camurl=?,camip=?,camport=?,username=?,userpassword=? where camid='{}'".format(str(camid))
        cur = self.con.cursor()
        if camip=='':
            camurl=''
        else:
            camurl="rtsp://" + str(username) + ":" + str(userpassword) + "@" + str(camip) + ":" + str(
                    camport) + "/h264/ch33/main/av_stream"
        cur.execute(sql, (coordinate_x,coordinate_y,rate,camurl,camip,camport,username,userpassword))
        cur.close()
        self.con.commit() 

    def updataOpenflag(self,camid='cam_01',isopen = 0):
        sql= "update camera set isopen= ? where camid='{}' ".format(str(camid))
        cur = self.con.cursor()
        cur.execute(sql, [(isopen)])
        cur.close()
        self.con.commit() 

    def insertIntoCamera(self,camid='cam_01',coordinate_x=0.0,coordinate_y=0.0,rate=1,camip='',camport='',username='',userpassword='',isopen=0):
        sql = "INSERT INTO camera(camid,coordinate_x,coordinate_y,rate,camurl,camip,camport,username,userpassword,isopen) VALUES(?,?,?,?,?,?,?,?,?,?)"
        cur = self.con.cursor()
        camurl = ''
        cur.execute(sql, (camid,coordinate_x,coordinate_y,rate,camurl,camip,camport,username,userpassword,isopen))
        cur.close()
        self.con.commit()
    
    #对瑕疵表的操作
    def insertIntoFlaw(self,flaw_id=1000,flaw_type='',camera_id='',coordinate_x=0.0,coordinate_y=0.0,width=0.0,highth=0.0,flaw_time='0000-00-00 00:00:00',cloth_type=''):
        sql = "INSERT INTO Flaw(flaw_id,flaw_type,camera_id,coordinate_x,coordinate_y,width,highth,flaw_time,cloth_type) VALUES(?,?,?,?,?,?,?,?,?)"
        cur = self.con.cursor()
        cur.execute(sql,(flaw_id,flaw_type,camera_id,coordinate_x,coordinate_y,width,highth,flaw_time,cloth_type))
        cur.close()
        self.con.commit()
    
    def getFlawCount(self):
        command = 'SELECT flaw_id FROM Flaw'
        cur = self.con.cursor()
        cur.execute(command)
        rows = cur.fetchall()
        ret = [(row[0]) for row in rows]
        cur.close()
        return len(ret)
        
    def getDataFromFlaw(self,flaw_type=""):
        command = "select flaw_id,flaw_type,camera_id,coordinate_x,coordinate_y,width,highth,flaw_time from Flaw where flaw_type='{}'".format(str(flaw_type))
        cur = self.con.cursor()
        cur.execute(command)
        rows = cur.fetchall()
        ret = [(row[0],row[1],row[2],row[3],row[4],row[5],row[6],row[7]) for row in rows]
        cur.close()
        return ret

    def insertIntoFlawStatistic(self,flaw_type='',flaw_cont=0):
        sql = "INSERT INTO FlawStatistic(flaw_type,flaw_cont) VALUES(?,?)"
        cur = self.con.cursor()
        cur.execute(sql,(flaw_type,flaw_cont))
        cur.close()
        self.con.commit()
    
    def updateFlawStatistic(self,flaw_type='',flaw_cont=0):
        sql = "UPDATE FlawStatistic SET flaw_cont= ? where flaw_type='{}'".format(str(flaw_type))
        cur = self.con.cursor()
        cur.execute(sql,[(flaw_cont)])
        cur.close()
        self.con.commit()
    
    def getcntFromFlawStatistic(self,flaw_type=""):
        command = "select flaw_cont from FlawStatistic where flaw_type = '{}'".format(str(flaw_type))
        cur = self.con.cursor()
        cur.execute(command)
        rows = cur.fetchall()
        ret = [(row[0]) for row in rows]
        cur.close()
        return ret[0]
    
    def getallFromFlawStatistic(self):
        command = "select flaw_type,flaw_cont from FlawStatistic"
        cur = self.con.cursor()
        cur.execute(command)
        rows = cur.fetchall()
        ret = [(row[0],row[1]) for row in rows]
        cur.close()
        return ret


    #对瑕疵统计表的操作
    # def insertIntoFlawStatistic(self,flaw_label=1,flaw_type=''):
    #     sql = "INSERT INTO FlawStatistic(flaw_label,flaw_type) VALUES(?,?)"
    #     cur = self.con.cursor()
    #     cur.execute(sql,(flaw_label,flaw_type))
    #     cur.close()
    #     self.con.commit()
    # def getFlawCount(self):
    #     command = 'SELECT flaw_type,count(flaw_label) AS flaw_count FROM FlawStatistic GROUP BY flaw_label'
    #     cur = self.con.cursor()
    #     coursor =cur.execute(command)
    #     cur.close()
    #     return coursor
    #     #使用方法
    #     #for row in coursor:
    #     #   row[0]  瑕疵类型
    #     #   row[1]  瑕疵数量
    # #对设置表的操作
    def insertIntoSetting(self,model='yolo',width=0.0,highth=0.0,rate=1.0):
        sql = "INSERT INTO Setting(model,width,highth,rate) VALUES(?,?,?,?)"
        cur = self.con.cursor()
        cur.execute(sql,(model,width,highth,rate))
        cur.close()
        self.con.commit()
    def updateSetting(self,model='yolo',width=0.0,higth=0.0,rate=1.0):
        sql = "UPDATE Setting SET width=?,highth=?,rate=? where model='{}'".format(model)
        cur = self.con.cursor()
        cur.execute(sql, (width,higth,rate))
        cur.close()
        self.con.commit()
    
    def getSetting(self,model='yolo'):
        command = "select width,highth,rate from Setting where model = '{}'".format(model)
        cur = self.con.cursor()
        cur.execute(command)
        rows = cur.fetchall()
        ret = [(row[0],row[1],row[2]) for row in rows]
        cur.close()
        return ret[0]

    
    def deleteAllFlaw(self):
        commad = "delete from Flaw"
        cur = self.con.cursor()
        cur.execute(commad)
        cur.close()
        self.con.commit()
    
    def deleteAllFlawStatistic(self):
        commad = "delete from FlawStatistic"
        cur = self.con.cursor()
        cur.execute(commad)
        cur.close()
        self.con.commit()
<file_sep>/add_window/Statistics.py
from PyQt5.QtWidgets import QFileDialog
from PyQt5.QtWidgets import QMainWindow
from PyQt5.uic import loadUi
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtCore import QTimer
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QMainWindow, QStatusBar, QListWidget, QAction, qApp, QMenu,QMessageBox
from PyQt5.uic import loadUi
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import QSizePolicy
import openpyxl
from Database import Database
class_name = {
'1':'停车痕紧',
'2':'停车痕松',
'3':'断经',
'4':'错花',
'5':'并纬',
'6':'缩纬',
'7':'缺纬',
'8':'糙纬',
'9':'折返',
'10':'断纬',
'11':'油污',
'12':'起机',
'13':'尽机',
'14':'经条',
'15':'擦白',
'16':'擦伤',
'17':'浆斑',
'18':'空织'
}



class AddstatisForm(QMainWindow):
    def __init__(self, parent=None, ui=None):
        super(AddstatisForm, self).__init__(parent)
        loadUi("UI/Statistics.ui", self)
        self.tablemodel = QStandardItemModel(10,2)
        self.tablemodel.setHorizontalHeaderLabels(['瑕疵种类', '总数'])
        self.tablemodel_2 = QStandardItemModel(10, 8)
        self.tablemodel_2.setHorizontalHeaderLabels(['编号', '瑕疵种类', '相机', 'X坐标', 'Y坐标', 'W', 'H', '时间'])
        self.s1 = 'all'
        self.s2 = 'all'
        self.comboBox.addItem('all')
        self.comboBox.addItem('cam_01')
        self.comboBox.addItem('cam_02')
        self.comboBox.addItem('cam_03')
        self.comboBox_2.addItems(['all', '停车痕紧', '停车痕松','断经','错花','并纬','缩纬','缺纬','糙纬','折返','断纬','油污','起机','尽机','经条','擦白','擦伤','浆斑','空织'])
        self.pushButton_2.clicked.connect(self.getFile)
        self.pushButton.clicked.connect(self.sta_work_all)
        self.pushButton_3.clicked.connect(self.GetSeclectFile)
        self.pushButton_4.clicked.connect(self.select_work_all)
        self.comboBox.currentIndexChanged.connect(self.selectionchange)
        self.comboBox_2.currentIndexChanged.connect(self.selectionchange_2)
        self.cnt = -1
        self.cnt_select=-1

    def write_excel_xlsx(self,workbook,path, sheet, value):
        try:
            index = len(value)
            # workbook = openpyxl.Workbook()
            # sheet = workbook.active
            # sheet = workbook.create_sheet(str(sheet_name))
            # sheet.title = sheet_name
            for i in range(0, index):
                for j in range(0, len(value[i])):
                    sheet.cell(row=i+1, column=j+1, value=str(value[i][j]))
            workbook.save(path)
        except:
            res = QMessageBox.question(self,'警告','路径冲突，请更换路径或关闭已打开的文件')
        
    def identify_work(self, ID = 0, label = "0", camera_id = "cam_01", X = 1.0, Y = 1.0, W = 1.0, H = 1.0, flaw_time = 0):
        ID = str(ID)
        label = str(label)
        camera_id = str(camera_id)
        X = str(X)
        Y = str(Y)
        W = str(W)
        H = str(H)
        flaw_time = str(flaw_time)
        self.cnt_select += 1
        self.sm=self.tablemodel_2
        self.sm.setItem(self.cnt_select, 0, QStandardItem(ID))         
        self.sm.setItem(self.cnt_select, 1, QStandardItem(label))
        self.sm.setItem(self.cnt_select, 2, QStandardItem(camera_id))
        self.sm.setItem(self.cnt_select, 3, QStandardItem(X))
        self.sm.setItem(self.cnt_select, 4, QStandardItem(Y))
        self.sm.setItem(self.cnt_select, 5, QStandardItem(W))
        self.sm.setItem(self.cnt_select, 6, QStandardItem(H))
        self.sm.setItem(self.cnt_select, 7, QStandardItem(flaw_time))
        self.st_info.setModel(self.sm)
        #QTableView
        self.st_info.setColumnWidth(0,100)
        self.st_info.setColumnWidth(1,200)

    def downallinfo(self):
        print(book_name_xlsx)
        workbook = openpyxl.Workbook()
        sheet1 = workbook.active
        sheet1.title = '停车痕紧'
        if(len(book_name_xlsx)>=6 and book_name_xlsx[-5:] == '.xlsx'):
            for i in range(19)[1:]:
                li = [['编号', '类型', '相机ID', 'X轴坐标', 'Y轴坐标', '宽度', '高度', '时间戳']]
                value3 = Database.getInstance().getDataFromFlaw(flaw_type=class_name[str(i)])
                for j in value3:
                    li.append(j)
                sheet_name_xlsx = class_name[str(i)]
                if (i == 1):
                    self.write_excel_xlsx(workbook,book_name_xlsx, sheet1, li)
                else:
                    sheet = workbook.create_sheet(str(sheet_name_xlsx))
                    self.write_excel_xlsx(workbook,book_name_xlsx, sheet, li)
                li = []

    def getFile(self):
        book_name_xlsx = QFileDialog.getSaveFileName(self,
                                    "另存为",
                                    "",
                                    "Excel工作簿(*.xlsx)")[0]
        print(book_name_xlsx)
        workbook = openpyxl.Workbook()
        sheet1 = workbook.active
        sheet1.title = '停车痕紧'
        if(len(book_name_xlsx)>=6 and book_name_xlsx[-5:] == '.xlsx'):
            for i in range(19)[1:]:
                li = [['编号', '类型', '相机ID', 'X轴坐标', 'Y轴坐标', '宽度', '高度', '时间戳']]
                
                value3 = Database.getInstance().getDataFromFlaw(flaw_type=class_name[str(i)])
                for j in value3:
                    li.append(j)
                sheet_name_xlsx = class_name[str(i)]
                if (i == 1):
                    self.write_excel_xlsx(workbook,book_name_xlsx, sheet1, li)
                else:
                    sheet = workbook.create_sheet(str(sheet_name_xlsx))
                    self.write_excel_xlsx(workbook,book_name_xlsx, sheet, li)
                li = []
    
    def sta_work_all(self):                         #界面显示
        self.st_info.setModel(self.tablemodel)
        value = Database.getInstance().getallFromFlawStatistic()
        self.cnt = -1
        for i in range(len(value)):
            label = value[i][0]
            num = value[i][1]
            self.show_work(label=label, num=num)

    def show_work(self, label = "0", num=0):     
        label = str(label)
        num=str(num)
        self.cnt += 1
        self.sm=self.tablemodel
        self.sm.setItem(self.cnt, 0, QStandardItem(label))
        self.sm.setItem(self.cnt, 1, QStandardItem(num))
        self.st_info.setModel(self.sm)
        #QTableView
        self.st_info.setColumnWidth(0,100)
        self.st_info.setColumnWidth(1, 200)

    def select_work_all(self):  #界面显示
        self.st_info.setModel(self.tablemodel_2)
        str1 = self.s1
        str2 = self.s2
        li_select=[]
        if (str2 == 'all'):
            for i in range(19)[1:]:
                value3_select = Database.getInstance().getDataFromFlaw(flaw_type=class_name[str(i)])
                for j in value3_select:
                    if (j[2] == str1 or str1=='all'):
                        li_select.append(j)
        else:
            value3_select = Database.getInstance().getDataFromFlaw(flaw_type=str2)
            for j in value3_select:
                if (j[2] == str1 or str1=='all'):
                    li_select.append(j)
        # self.cnt_select = -1
        while (self.cnt_select != -1):
            self.tablemodel_2.removeRow(self.cnt_select)
            self.cnt_select -= 1
        for i in range(len(li_select)):
            ID = li_select[i][0]
            label = li_select[i][1]
            camer_id = li_select[i][2]
            X = li_select[i][3]
            Y = li_select[i][4]
            W = li_select[i][5]
            H = li_select[i][6]
            flaw_time = li_select[i][7]
            self.identify_work(ID=ID, label=label, camera_id=camer_id, X=X, Y=Y, W=W, H=H, flaw_time=flaw_time)
        
    def selectionchange(self):
        self.s1 = self.comboBox.currentText()
        print(self.s1)

    def selectionchange_2(self):
        self.s2 = self.comboBox_2.currentText()
        print(self.s2)

    def GetSeclectFile(self):
        book_name_xlsx = QFileDialog.getSaveFileName(self,
                                    "另存为",
                                    "",
                                    "Excel工作簿(*.xlsx)")[0]
        print(book_name_xlsx)
        str1 = self.s1
        str2 = self.s2
        print(str1)
        print(str2)
        if (str2 == 'all'):
            workbook = openpyxl.Workbook()
            sheet1 = workbook.active
            sheet1.title = '停车痕紧'
            if(len(book_name_xlsx)>=6 and book_name_xlsx[-5:] == '.xlsx'):
                for i in range(19)[1:]:
                    li = [['编号', '类型', '相机ID', 'X轴坐标', 'Y轴坐标', '宽度', '高度', '时间戳']]
                
                    value3 = Database.getInstance().getDataFromFlaw(flaw_type=class_name[str(i)])
                    for j in value3:
                        if (j[2] == str1 or str1=='all'):
                            li.append(j)
                    sheet_name_xlsx = class_name[str(i)]
                    if (i == 1):
                        self.write_excel_xlsx(workbook,book_name_xlsx, sheet1, li)
                    else:
                        sheet = workbook.create_sheet(str(sheet_name_xlsx))
                        self.write_excel_xlsx(workbook,book_name_xlsx, sheet, li)
                    li = []
        else:
            workbook = openpyxl.Workbook()
            sheet1 = workbook.active
            sheet1.title = str2
            if (len(book_name_xlsx) >= 6 and book_name_xlsx[-5:] == '.xlsx'):
                li = [['编号', '类型', '相机ID', 'X轴坐标', 'Y轴坐标', '宽度', '高度', '时间戳']]  
                value3 = Database.getInstance().getDataFromFlaw(flaw_type=str2)
                for j in value3:
                    if (j[2] == str1 or str1=='all'):
                        li.append(j)
                self.write_excel_xlsx(workbook,book_name_xlsx, sheet1, li)
                
        <file_sep>/database/test.py
from PyQt5.QtWidgets import QMainWindow
from PyQt5.uic import loadUi
from PyQt5.QtWidgets import QFileDialog
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
class AddMainWindow(QMainWindow):
    def __init__(self, parent=None, ui=None):
        super(AddMainWindow, self).__init__(parent)
        loadUi(ui, self)

        self.tablemodel = QStandardItemModel(10,6)
        self.tablemodel.setHorizontalHeaderLabels(['ID','瑕疵种类','X坐标','Y坐标','时间'])
        self.TV_info.setModel(self.tablemodel)
        
        # self.add.clicked.connect(self.addToDatabase)
        self.cancel.clicked.connect(self.close)
        self.file_browse.clicked.connect(lambda: self.getFile(self.file))
        self.PB_work.clicked.connect(self.identify_work)
    def close(self):
        self.destroy(True)

    def addToDatabase(self):
        pass
    def getFile(self, lineEdit):
        pic_map = QFileDialog.getOpenFileName()[0]
        lineEdit.setText(pic_map)
        # print(pic_map)
        pixmap = QPixmap (pic_map)
        self.LB_Pic.setPixmap(pixmap)
        self.LB_Pic.setScaledContents(True)
        self.LB_Pic.show()
    
    def identify_work(self):
        # def __init__(self, parent=None):
        #     super(MainWindow, self).__init__(parent)
        #     loadUi('qtdesigner.ui', self)
        #     self.pushButton.clicked.connect(self.say)
        #     self.showData()
        # def showData(self):
        #     # 准备数据模型
        self.sm=self.tablemodel           
        #设置数据头栏名称
        # self.sm.setHorizontalHeaderItem(0, QtGui.QStandardItem("Name"))
        # self.sm.setHorizontalHeaderItem(1, QtGui.QStandardItem("NO."))
        
        #设置数据条目
        self.sm.setItem(0, 0, QStandardItem("刘董"))
        self.sm.setItem(0, 1, QStandardItem("123"))
        
        self.sm.setItem(1, 0, QStandardItem("杜阳阳"))
        self.sm.setItem(1, 1, QStandardItem("456"))
        
        self.sm.setItem(2, 0, QStandardItem("常家鑫"))
        self.sm.setItem(2, 1, QStandardItem("789"))
        
        #设置条目颜色和字体
        # self.sm.item(0, 0).setForeground(QBrush(QColor(255, 0, 0)))		
        # self.sm.item(0, 0).setFont(QFont("Times", 10, QFont.Black))
        
        # self.sm.item(3, 1).setBackground(QBrush(QColor(255, 255, 0)))
        
        #按照编号排序
        # self.sm.sort(1,Qt.DescendingOrder)
        
        #将数据模型绑定到QTableView
        self.TV_info.setModel(self.sm)
        
        #QTableView
        self.TV_info.setColumnWidth(0,100)
        self.TV_info.setColumnWidth(1,200)
        <file_sep>/add_window/SetCamera.py
from PyQt5.QtWidgets import QFileDialog
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QMessageBox
from Database import Database
from add_window.AddMainWindow import AddMainWindow


class SetCamera(AddMainWindow):
    def __init__(self, parent=None,camid='cam_01'):
        self.clear = True
        super().__init__(parent, "UI/SetCamera.ui")
        #self.file_browse.clicked.connect(lambda: self.getFile(self.file))
        self.ID.setText(camid)
        self.set.clicked.connect(self.updataCaminfoToDatabase)
        self.clear.clicked.connect(self.clearCaminfoToDatabase)
        caminfo = Database.getInstance().getCaminfo(ID=camid)[0]
        self.X.setText(str(caminfo[6]))
        self.Y.setText(str(caminfo[7]))
        self.rate.setText(str(caminfo[5]))
        self.IP.setText(str(caminfo[0]))
        self.Port.setText(str(caminfo[1]))
        self.Username.setText(str(caminfo[2]))
        self.Password.setText(str(caminfo[3]))

    @QtCore.pyqtSlot()
    def clearCaminfoToDatabase(self):
        self.clear = True
        camid=str(self.ID.text())
        Database.getInstance().updataCaminfo(camid=camid)
        Database.getInstance().updataOpenflag(camid,0)
        caminfo = Database.getInstance().getCaminfo(ID=camid)[0]
        self.X.setText(str(caminfo[6]))
        self.Y.setText(str(caminfo[7]))
        self.rate.setText(str(caminfo[5]))
        self.IP.setText(str(caminfo[0]))
        self.Port.setText(str(caminfo[1]))
        self.Username.setText(str(caminfo[2]))
        self.Password.setText(str(caminfo[3]))

    
    @QtCore.pyqtSlot()
    def updataCaminfoToDatabase(self):
        self.clear = False
        camid=str(self.ID.text())
        coordinate_x=str(self.X.text())
        coordinate_y=str(self.Y.text())
        rate=str(self.rate.text())
        camip=str(self.IP.text())
        camport=str(self.Port.text())
        username=str(self.Username.text())
        userpassword=str(self.Password.text())
        Database.getInstance().updataCaminfo(camid=camid,
                                             coordinate_x=float(coordinate_x),
                                             coordinate_y=float(coordinate_y),
                                             rate=float(rate),
                                             camip=camip,
                                             camport=camport,
                                             username=username,
                                             userpassword=<PASSWORD>)
        Database.getInstance().updataOpenflag(camid,1)
    
    # def closeEvent(self,QCloseEvent):
    #     res = QMessageBox.question(self,'提示','是否保存设置？',QMessageBox.Yes|QMessageBox.No,QMessageBox.No)
    #     if res == QMessageBox.Yes:
    #         camid=str(self.ID.text())
    #         coordinate_x=str(self.X.text())
    #         coordinate_y=str(self.Y.text())
    #         rate=str(self.rate.text())
    #         camip=str(self.IP.text())
    #         camport=str(self.Port.text())
    #         username=str(self.Username.text())
    #         userpassword=str(self.Password.text())
    #         Database.getInstance().updataCaminfo(camid=camid,
    #                                             coordinate_x=float(coordinate_x),
    #                                             coordinate_y=float(coordinate_y),
    #                                             rate=float(rate),
    #                                             camip=camip,
    #                                             camport=camport,
    #                                             username=username,
    #                                             userpassword=<PASSWORD>)
    #         Database.getInstance().updataOpenflag(camid,1)
    #         QCloseEvent.accept()
    #     else:
    #         QCloseEvent.accept()

    # def addToDatabase(self):
    #     id = str(self.id.text())
    #     group = str(self.group.text())
    #     location = str(self.location.text())
    #     x = str(self.x_coord.text())
    #     y = str(self.y_coord.text())
    #     file = str(self.file.text())
    #     Database.getInstance().insertIntoCamera(id, location, x, y, group, file)
    #     self.destroy()

<file_sep>/src/requirements-cpu.txt
numpy
scipy
Pillow
cython
matplotlib
scikit-image
tensorflow
keras==2.2.4
opencv-python
imageio
h5py
imgaug
argparse>=1.1
dill==0.2.7.1
fire >= 0.1.3
psutil >= 5.4.5
requests >= 2.18.4
slidingwindow >= 0.0.13
tqdm >= 4.23.4
tensorpack >= 0.8.5
pillow
h2o==3.18.0.8
PyQt5

<file_sep>/add_window/help.py
from PyQt5.QtWidgets import QFileDialog
from PyQt5.QtWidgets import QMainWindow
from PyQt5.uic import loadUi
#from Database import Database


class HelpForm(QMainWindow):
    def __init__(self, parent=None, ui=None):
        super(HelpForm, self).__init__(parent)
        loadUi("UI/help.ui", self)
    # def addToDatabase(self):
    #     id = str(self.id.text())
    #     group = str(self.group.text())
    #     location = str(self.location.text())
    #     x = str(self.x_coord.text())
    #     y = str(self.y_coord.text())
    #     file = str(self.file.text())
    #     Database.getInstance().insertIntoCamera(id, location, x, y, group, file)
    #     self.destroy()
<file_sep>/MainWindow.py
import time
import numpy as np
import cv2.cv2 as cv2
import qdarkstyle
from PyQt5 import QtCore, QtWidgets,QtGui
from PyQt5.QtCore import QTimer
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QApplication,QSplashScreen
from PyQt5.QtWidgets import QMainWindow, QStatusBar, QListWidget, QAction, qApp, QMenu,QMessageBox
from PyQt5.uic import loadUi
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import QSizePolicy
from Database import Database
from add_window.SetCamera import SetCamera
from add_window.AddPicworkForm import AddPicworkForm
from add_window.Setsetting import SetSetting
from processor.MainProcessor import MainProcessor
from yolo3.yolo import YOLO
from yolo3.yolo_online import YOLO_ONLINE
from add_window.Statistics import AddstatisForm
from add_window.help import HelpForm
class_name = {
'1':'停车痕紧',
'2':'停车痕松',
'3':'断经',
'4':'错花',
'5':'并纬',
'6':'缩纬',
'7':'缺纬',
'8':'糙纬',
'9':'折返',
'10':'断纬',
'11':'油污',
'12':'起机',
'13':'尽机',
'14':'经条',
'15':'擦白',
'16':'擦伤',
'17':'浆斑',
'18':'空织'
}
class MainWindow(QMainWindow):
    def __init__(self,model_flag='local'):
        self.model_flag = model_flag
        super(MainWindow, self).__init__()
        loadUi("./UI/MainForm.ui", self)
        self.cam_01 = False
        self.cam_02 = False
        self.cam_03 = False
        self.run_flag = False
        self.vs1 = None
        self.feed1 = None
        self.vs2 = None
        self.feed2 = None
        self.vs3 = None
        self.feed3 = None
        self.cnt = -1
        res = QMessageBox.question(self,'提示','是否使用在线识别模式？',QMessageBox.Yes|QMessageBox.No,QMessageBox.No)
        if res == QMessageBox.Yes:
            self.model_flag = 'online'
        else:
            self.model_flag = 'local'
        if (self.model_flag=='local'):
            self.yolo = YOLO()
        elif (self.model_flag == 'online'):
            self.yolo = YOLO_ONLINE()
        self.st = time.time()
        self.coco = False
        self.first = True

        self.CameraA.setScaledContents(True)
        self.CameraA.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
        self.CameraB.setScaledContents(True)
        self.CameraB.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
        self.CameraC.setScaledContents(True)
        self.CameraC.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
        self.cam_clear_gaurd = False

        self.processor = MainProcessor(['cam_01','cam_02','cam_03'])


        self.database = Database.getInstance()

        #----------数据库初始化-------------------------------------#
        # self.database.insertIntoCamera('cam_01')
        # self.database.insertIntoCamera('cam_02')
        # self.database.insertIntoCamera('cam_03')
        # self.database.insertIntoSetting()
        # for i in range(19)[1:]:
        #     flow_type=class_name[str(i)]
        #     self.database.insertIntoFlawStatistic(flaw_type=flow_type,flaw_cont=0)
        # self.database.deleteAllFlaw()
        #----------------------------------------------------------#

        #----------测试数据-----------------------------------------#
        # for i in range(19)[1:]:
        #     self.database.insertIntoFlaw(flaw_id=i-1,flaw_type=class_name[str(i)])
        # for i in range(19)[1:]:
        #     self.database.updateFlawStatistic(flaw_type=class_name[str(i)],flaw_cont=1)
        #----------------------------------------------------------#

        self.statistic_cnt = {}
        for i in range(19)[1:]:
            self.statistic_cnt[class_name[str(i)]]=self.database.getcntFromFlawStatistic(flaw_type=class_name[str(i)])
        self.database.updataCaminfo('cam_01')
        self.database.updataCaminfo('cam_02')
        self.database.updataCaminfo('cam_03')
        self.database.updataOpenflag('cam_01',0)
        self.database.updataOpenflag('cam_02',0)
        self.database.updataOpenflag('cam_03',0)
        self.ID = self.database.getFlawCount() #获取最大的标号

        self.updateCamInfo()

        self.PB_CamAsettings.clicked.connect(self.setCameraA)
        self.PB_CamBsettings.clicked.connect(self.setCameraB)
        self.PB_CamCsettings.clicked.connect(self.setCameraC)
        self.PB_picture.clicked.connect(self.picworkForm)
        self.PB_start.clicked.connect(self.start)
        self.PB_end.clicked.connect(self.stop)
        self.User.triggered.connect(self.helpform)
        self.PB_statistics.clicked.connect(self.statisForm)
        self.PB_settings.clicked.connect(self.setting)

        self.tablemodel = QStandardItemModel(10, 8)
        self.tablemodel.setHorizontalHeaderLabels(['编号','瑕疵种类','相机','X坐标','Y坐标','瑕疵宽度','瑕疵高度','时间戳'])
        self.tV_info.setModel(self.tablemodel)

        self.timer = QTimer(self)
        self.timer.timeout.connect(self.update_image)
        self.timer.start(50)
        
    def setCameraA(self):
        if self.run_flag == False:
            addWin = SetCamera(parent=self,camid='cam_01')
            addWin.show()
        else:
            res = QMessageBox.question(self,'警告','请先停止实时识别')

    def setCameraB(self):
        if self.run_flag == False:
            addWin = SetCamera(parent=self,camid='cam_02')
            addWin.show()
        else:
            res = QMessageBox.question(self,'警告','请先停止实时识别')
    def setCameraC(self):
        if self.run_flag == False:
            addWin = SetCamera(parent=self,camid='cam_03')
            addWin.show()
        else:
            res = QMessageBox.question(self,'警告','请先停止实时识别')
    def picworkForm(self):
        #self.yolo.close_session()
        if (self.model_flag=='local'):
            addWin = AddPicworkForm(parent=self,yolo=self.yolo,model_flag=self.model_flag)
        else:
            addWin = AddPicworkForm(parent=self,yolo=self.yolo,model_flag=self.model_flag)
        addWin.show()
    def helpform(self):
        addWin = HelpForm(parent=self)
        addWin.show()
    def statisForm(self):
        for i in range(19)[1:]:
            self.database.updateFlawStatistic(flaw_type=class_name[str(i)],flaw_cont=self.statistic_cnt[class_name[str(i)]])
        addWin = AddstatisForm(parent=self)
        addWin.show()
    def setting(self):
        addWin = SetSetting(parent=self)
        addWin.show()
    def update_image(self):
        try:
            if self.run_flag == True:
                frames = {}
                frames[0]=None
                frames[1]=None
                frames[2]=None
                if self.cam_01 == False and self.cam_02 == False and self.cam_03 == False:
                    return
                if self.cam_01 == True:
                    ret1, frame1 = self.vs1.read()
                    if ret1 == True:
                        frames[0]=frame1
                if self.cam_02 == True:
                    ret2, frame2 = self.vs2.read()
                    if ret2 == True:
                        frames[1]=frame2
                if self.cam_03 == True:
                    ret3, frame3 = self.vs3.read()
                    if ret3 == True:
                        frames[2]=frame3
                packet = self.processor.getProcessedImage(yolo = self.yolo,frames = frames)
                boxes1 = packet['boxes1']
                boxes2 = packet['boxes2']
                boxes3 = packet['boxes3']
                if self.cam_01 and isinstance(packet['frame01'],np.ndarray):
                    qimg = self.toQImage(packet['frame01'])
                    self.CameraA.setPixmap(QPixmap.fromImage(qimg))
                if self.cam_02 and isinstance(packet['frame02'],np.ndarray):
                    qimg = self.toQImage(packet['frame02'])
                    self.CameraB.setPixmap(QPixmap.fromImage(qimg))
                if self.cam_03 and isinstance(packet['frame03'],np.ndarray):
                    qimg = self.toQImage(packet['frame03'])
                    self.CameraC.setPixmap(QPixmap.fromImage(qimg))
                if self.cam_01:
                    for i in range(len(boxes1['label'])):
                        ID = self.ID
                        self.ID += 1
                        label = class_name[boxes1['label'][i]]
                        if self.coco:
                            label = boxes1['label'][i]
                        X = boxes1['X'][i]
                        Y = boxes1['Y'][i]
                        W = boxes1['W'][i]
                        H = boxes1['H'][i]
                        camer_id = 'cam_01'
                        timeStamp = int(time.time())
                        timeArray = time.localtime(timeStamp)
                        flaw_time = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
                        rate = Database.getInstance().getSetting()
                        wid_value = rate[0]
                        hight_value = rate[1]
                        rate_value = rate[2]
                        ft_time = time.time()
                        Y = (ft_time-self.st)*rate_value + Y
                        if(W>=wid_value and H>=hight_value):
                            self.identify_work(ID=ID, label=label, camera_id=camer_id, X=X, Y=Y, W=W, H=H, flaw_time=flaw_time)
                            self.database.insertIntoFlaw(flaw_id=int(ID),
                                                        flaw_type=label,
                                                        camera_id=camer_id,
                                                        coordinate_x=X,
                                                        coordinate_y=Y,
                                                        width=W,
                                                        highth=H,
                                                        flaw_time=flaw_time)
                            self.statistic_cnt[label]+=1
                            print('ID: '+str(ID))
                if self.cam_02:
                    for i in range(len(boxes2['label'])):
                        ID = self.ID
                        self.ID += 1
                        label = class_name[boxes2['label'][i]]
                        if self.coco:
                            label = boxes2['label'][i]
                        X = boxes2['X'][i]
                        Y = boxes2['Y'][i]
                        W = boxes2['W'][i]
                        H = boxes2['H'][i]
                        camer_id = 'cam_02'
                        timeStamp = int(time.time())
                        timeArray = time.localtime(timeStamp)
                        flaw_time = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
                        rate = Database.getInstance().getSetting()
                        wid_value = rate[0]
                        hight_value = rate[1]
                        rate_value = rate[2]
                        ft_time = time.time()
                        Y = (ft_time-self.st)*rate_value + Y
                        if(W>=wid_value and H>=hight_value):
                            self.identify_work(ID=ID, label=label, camera_id=camer_id, X=X, Y=Y, W=W, H=H, flaw_time=flaw_time)
                            self.database.insertIntoFlaw(flaw_id=int(ID),
                                                        flaw_type=label,
                                                        camera_id=camer_id,
                                                        coordinate_x=X,
                                                        coordinate_y=Y,
                                                        width=W,
                                                        highth=H,
                                                        flaw_time=flaw_time)
                            self.statistic_cnt[label]+=1
                            print('ID: '+str(ID))
                if self.cam_03:
                    for i in range(len(boxes3['label'])):
                        ID = self.ID
                        self.ID += 1
                        label = class_name[boxes3['label'][i]]
                        if self.coco:
                            label = boxes3[label][i]
                        X = boxes3['X'][i]
                        Y = boxes3['Y'][i]
                        W = boxes3['W'][i]
                        H = boxes3['H'][i]
                        camer_id = 'cam_03'
                        timeStamp = int(time.time())
                        timeArray = time.localtime(timeStamp)
                        flaw_time = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
                        rate = Database.getInstance().getSetting()
                        wid_value = rate[0]
                        hight_value = rate[1]
                        rate_value = rate[2]
                        ft_time = time.time()
                        Y = (ft_time-self.st)*rate_value + Y
                        if(W>=wid_value and H>=hight_value):
                            self.identify_work(ID=ID, label=label, camera_id=camer_id, X=X, Y=Y, W=W, H=H, flaw_time=flaw_time)
                            self.database.insertIntoFlaw(flaw_id=int(ID),
                                                        flaw_type=label,
                                                        camera_id=camer_id,
                                                        coordinate_x=X,
                                                        coordinate_y=Y,
                                                        width=W,
                                                        highth=H,
                                                        flaw_time=flaw_time)
                            self.statistic_cnt[label]+=1
                            print('ID: '+str(ID))
        
        except:
            res = QMessageBox.question(self,'警告','链接网络摄像头失败,请核对摄像头参数')
            self.run_flag=False
            

    def identify_work(self, ID = 0, label = "0", camera_id = "cam_01", X = 1.0, Y = 1.0, W = 1.0, H = 1.0, flaw_time = 0):
        ID = str(ID)
        label = str(label)
        camera_id = str(camera_id)
        X = str(X)
        Y = str(Y)
        W = str(W)
        H = str(H)
        flaw_time = str(flaw_time)
        self.cnt += 1
        self.sm=self.tablemodel
        self.sm.setItem(self.cnt, 0, QStandardItem(ID))         
        self.sm.setItem(self.cnt, 1, QStandardItem(label))
        self.sm.setItem(self.cnt, 2, QStandardItem(camera_id))
        self.sm.setItem(self.cnt, 3, QStandardItem(X))
        self.sm.setItem(self.cnt, 4, QStandardItem(Y))
        self.sm.setItem(self.cnt, 5, QStandardItem(W))
        self.sm.setItem(self.cnt, 6, QStandardItem(H))
        self.sm.setItem(self.cnt, 7, QStandardItem(flaw_time))
        self.tV_info.setModel(self.sm)
        #QTableView
        self.tV_info.setColumnWidth(0,100)
        self.tV_info.setColumnWidth(1,200)        
            
          

    def updateCamInfo(self):
        self.feed1 = self.database.getCamurl('cam_01')[0]
        self.feed2 = self.database.getCamurl('cam_02')[0]
        self.feed3 = self.database.getCamurl('cam_03')[0]
        self.cam_01 = self.database.getOpenflag('cam_01')[0]
        self.cam_02 = self.database.getOpenflag('cam_02')[0]
        self.cam_03 = self.database.getOpenflag('cam_03')[0]
        if self.feed1 == "":
            self.feed1 = 0
        if self.feed2 == "":
            self.feed2 = 0
        if self.feed3 == "":
            self.feed3 = 0
        #self.processor = MainProcessor(self.cam_selector.currentText())
        if self.first==False:
            self.vs1 = cv2.VideoCapture(self.feed1)
            self.vs2 = cv2.VideoCapture(self.feed2)
            self.vs3 = cv2.VideoCapture(self.feed3)
        else:
            self.first = False

    #def updateLog(self):
    def updateCamFlagInfo(self):
        self.cam_01 = self.database.getOpenflag('cam_01')[0]
        self.cam_02 = self.database.getOpenflag('cam_02')[0]
        self.cam_03 = self.database.getOpenflag('cam_03')[0]



    def toQImage(self, raw_img):
        from numpy import copy
        img = copy(raw_img)
        qformat = QImage.Format_Indexed8
        if len(img.shape) == 3:
            if img.shape[2] == 4:
                qformat = QImage.Format_RGBA8888
            else:
                qformat = QImage.Format_RGB888

        outImg = QImage(img.tobytes(), img.shape[1], img.shape[0], img.strides[0], qformat)
        outImg = outImg.rgbSwapped()
        return outImg
    
    @QtCore.pyqtSlot()
    def start(self):
        if self.run_flag == True :
            return
        self.updateCamFlagInfo()
        #self.database.updataOpenflag('cam_01',1)
        #self.database.updataOpenflag('cam_02',1)
        #self.database.updataOpenflag('cam_03',1)
        if(self.cam_01 or self.cam_02 or self.cam_03):
            ash = QSplashScreen(QtGui.QPixmap("UI/NUI.png"))
            ash.setFont(QtGui.QFont('Microsoft YaHei UI',20))
            ash.show()
            ash.showMessage("摄像头链接中,请稍候",QtCore.Qt.AlignLeft | QtCore.Qt.AlignBottom, QtCore.Qt.green)
            self.updateCamInfo()
            self.run_flag = True
            if (self.cam_01 == True and self.vs1.isOpened() == False) or (self.cam_02 == True and self.vs2.isOpened() == False) or (self.cam_03 == True and self.vs3.isOpened() == False):
                self.run_flag = False
                ash.close()
                res = QMessageBox.question(self,'警告','摄像头链接失败,请核对摄像头参数')
            else:
                ash.close()
               
        else:
            res = QMessageBox.question(self,'警告','请先设置摄像头参数')

    
    


    @QtCore.pyqtSlot()
    def stop(self):
        if self.run_flag == False:
            return
        self.run_flag = False
        if (self.vs1 != None):
            self.vs1.release()
            self.CameraA.setText("已停止")
        if (self.vs2 != None):
            self.vs2.release()
            self.CameraB.setText("已停止")
        if (self.vs3 != None):
            self.vs3.release()
            self.CameraC.setText("已停止")
        self.vs1 = None
        self.vs2 = None
        self.vs3 = None
        res = QMessageBox.question(self,'提示','是否保留摄像头设置？',QMessageBox.Yes|QMessageBox.No,QMessageBox.No)
        if res == QMessageBox.Yes:
            return
        else:
            self.database.updataOpenflag('cam_01',0)
            self.database.updataOpenflag('cam_02',0)
            self.database.updataOpenflag('cam_03',0)
            #self.updateCamInfo()
            self.cam_01 = False
            self.cam_02 = False
            self.cam_03 = False

    def closeEvent(self,QCloseEvent):
        res = QMessageBox.question(self,'提示','是否退出系统？',QMessageBox.Yes|QMessageBox.No,QMessageBox.No)
        if res == QMessageBox.Yes:
            QCloseEvent.accept()
        else:
            QCloseEvent.ignore()


        <file_sep>/app.py
import sys
# import qdarkstyle
from PyQt5.QtWidgets import QApplication,QSplashScreen
from MainWindow import MainWindow
from PyQt5 import QtGui,QtCore

def main():
    app = QApplication(sys.argv)
    ash = QSplashScreen(QtGui.QPixmap("UI/NUI.png"))
    ash.setFont(QtGui.QFont('Microsoft YaHei UI',20))
    ash.show()
    ash.showMessage("系统启动中,请稍候",QtCore.Qt.AlignLeft | QtCore.Qt.AlignBottom, QtCore.Qt.green)
    main_window = MainWindow()
    # app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
    main_window.show()
    ash.finish(main_window)
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()
<file_sep>/yolo3/yolo_online.py
# -*- coding: utf-8 -*-
"""
Class definition of YOLO_v3 style detection model on image and video
"""

import colorsys
import os
from timeit import default_timer as timer
import numpy as np
from keras import backend as K
from keras.models import load_model
from keras.layers import Input
from PIL import Image, ImageFont, ImageDraw
import tensorflow as tf
import requests
import json
from yolo3.yolo3.model import yolo_eval, yolo_body, tiny_yolo_body
from yolo3.yolo3.utils import letterbox_image
import os
from keras.utils import multi_gpu_model
class_name = {
'1':'停车痕紧',
'2':'停车痕松',
'3':'断经',
'4':'错花',
'5':'并纬',
'6':'缩纬',
'7':'缺纬',
'8':'糙纬',
'9':'折返',
'10':'断纬',
'11':'油污',
'12':'起机',
'13':'尽机',
'14':'经条',
'15':'擦白',
'16':'擦伤',
'17':'浆斑',
'18':'空织'
}

class YOLO_ONLINE(object):
    _defaults = {
        "model_path": 'yolo3/model_data/yolov3forflaw.h5',
        "anchors_path": 'yolo3/model_data/yolo_anchors.txt',
        "classes_path": 'yolo3/model_data/classes.txt',
        "score" : 0.3,
        "iou" : 0.45,
        "model_image_size" : (416, 416),
        "gpu_num" : 1,
    }
    # _defaults = {
    #     "model_path": 'yolo3/model_data/yolov3.h5',
    #     "anchors_path": 'yolo3/model_data/yolo_anchors.txt',
    #     "classes_path": 'yolo3/model_data/coco_classes.txt',
    #     "score" : 0.3,
    #     "iou" : 0.45,
    #     "model_image_size" : (416, 416),
    #     "gpu_num" : 1,
    # }

    @classmethod
    def get_defaults(cls, n):
        if n in cls._defaults:
            return cls._defaults[n]
        else:
            return "Unrecognized attribute name '" + n + "'"

    def __init__(self, **kwargs):
        self.__dict__.update(self._defaults) # set up default values
        self.__dict__.update(kwargs) # and update with user overrides
        self.class_names = self._get_class()
        self.anchors = self._get_anchors()
        self._t1 = 0.3
        self._t2 = 0.45
        #self.generate()
        self.sess = K.get_session()
        self.depth = (5+len(self.class_names))*3
        self.input1 = tf.placeholder(tf.float32,shape=(None,13,13,self.depth))
        self.input2 = tf.placeholder(tf.float32,shape=(None,26,26,self.depth))
        self.input3 = tf.placeholder(tf.float32,shape=(None,52,52,self.depth))
        self.boxes, self.scores, self.classes = self.generate()
    def _get_class(self):
        classes_path = os.path.expanduser(self.classes_path)
        with open(classes_path) as f:
            class_names = f.readlines()
        class_names = [c.strip() for c in class_names]
        return class_names

    def _get_anchors(self):
        anchors_path = os.path.expanduser(self.anchors_path)
        with open(anchors_path) as f:
            anchors = f.readline()
        anchors = [float(x) for x in anchors.split(',')]
        return np.array(anchors).reshape(-1, 2)

    def generate(self):
        # Generate colors for drawing bounding boxes.
        hsv_tuples = [(x / len(self.class_names), 1., 1.)
                      for x in range(len(self.class_names))]
        self.colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples))
        self.colors = list(
            map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)),
                self.colors))
        np.random.seed(10101)  # Fixed seed for consistent colors across runs.
        np.random.shuffle(self.colors)  # Shuffle colors to decorrelate adjacent classes.
        np.random.seed(None)  # Reset seed to default.
        self.input_image_shape = K.placeholder(shape=(2, ))
        boxes, scores, classes = yolo_eval([self.input1,self.input2,self.input3], self.anchors,
                len(self.class_names), self.input_image_shape,
                score_threshold=self.score, iou_threshold=self.iou)
        return boxes,scores, classes

    #"http://192.168.3.3:8500"
    def detect_image(self, image=None,endpoint = "http://127.0.0.1:8500"):
        start = timer()
        ans = {}
        ans['label']=[]
        ans['X']=[]
        ans['Y']=[]
        ans['W']=[]
        ans['H']=[]

        if self.model_image_size != (None, None):
            assert self.model_image_size[0]%32 == 0, 'Multiples of 32 required'
            assert self.model_image_size[1]%32 == 0, 'Multiples of 32 required'
            boxed_image = letterbox_image(image, tuple(reversed(self.model_image_size)))
        else:
            new_image_size = (image.width - (image.width % 32),
                              image.height - (image.height % 32))
            boxed_image = letterbox_image(image, new_image_size)
        image_data = np.array(boxed_image, dtype='float32')

        print(image_data.shape)
        image_data /= 255.
        image_data = np.expand_dims(image_data, 0)  # Add batch dimension.
        print(image_data.shape)
        inputda = np.array(image_data).tolist()
        input_data = {
            "model_name": "default",
            "model_version": 1,
            "data": {
                "images": inputda}
        }
        result = requests.post(endpoint, json=input_data)
        #print(result.elapsed.total_seconds())
        end1 = timer()
        print(end1-start)
        new_dict = json.loads(result.text)
        out_boxes = np.array(new_dict['out_boxes'])
        out_scores = np.array(new_dict['out_scores'])
        out_classes = np.array(new_dict['out_classes'])
        output = [out_boxes,out_scores,out_classes]

        out_boxes, out_scores, out_classes = self.sess.run(
            [self.boxes, self.scores, self.classes],
            feed_dict={
                self.input1: out_boxes,
                self.input2: out_scores,
                self.input3: out_classes,
                self.input_image_shape: [image.size[1], image.size[0]],
                K.learning_phase(): 0
            })
        
        end2 = timer()
        print(end2-end1)

        print('Found {} boxes for {}'.format(len(out_boxes), 'img'))

        font = ImageFont.truetype(font='yolo3/font/FiraMono-Medium.otf',
                    size=np.floor(3e-2 * image.size[1] + 0.5).astype('int32'))
        thickness = (image.size[0] + image.size[1]) // 300

        for i, c in reversed(list(enumerate(out_classes))):
            predicted_class = self.class_names[c]
            box = out_boxes[i]
            score = out_scores[i]

            label = '{} {:.2f}'.format(predicted_class, score)
            draw = ImageDraw.Draw(image)
            label_size = draw.textsize(label, font)

            top, left, bottom, right = box
            top = max(0, np.floor(top + 0.5).astype('int32'))
            left = max(0, np.floor(left + 0.5).astype('int32'))
            bottom = min(image.size[1], np.floor(bottom + 0.5).astype('int32'))
            right = min(image.size[0], np.floor(right + 0.5).astype('int32'))
            print(label, (left, top), (right, bottom))
            ans['label'].append(str(predicted_class))
            ans['X'].append((left+right)/2)
            ans['Y'].append((top+bottom)/2)
            ans['W'].append(right-left)
            ans['H'].append(bottom-top)

            if top - label_size[1] >= 0:
                text_origin = np.array([left, top - label_size[1]])
            else:
                text_origin = np.array([left, top + 1])

            # My kingdom for a good redistributable image drawing library.
            for i in range(thickness):
                draw.rectangle(
                    [left + i, top + i, right - i, bottom - i],
                    outline=self.colors[c])
            draw.rectangle(
                [tuple(text_origin), tuple(text_origin + label_size)],
                fill=self.colors[c])
            draw.text(text_origin, label, fill=(0, 0, 0), font=font)
            del draw

        end = timer()
        print(end - start)
        return image,ans


<file_sep>/add_window/old/Statistics.py
from PyQt5.QtWidgets import QFileDialog
from PyQt5.QtWidgets import QMainWindow
from PyQt5.uic import loadUi
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtCore import QTimer
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QMainWindow, QStatusBar, QListWidget, QAction, qApp, QMenu
from PyQt5.uic import loadUi
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import QSizePolicy
import openpyxl
from Database import Database
book_name_xlsx = 'xlsx格式测试工作簿.xlsx'
class_name = {
'1':'停车痕紧',
'2':'停车痕松',
'3':'断经',
'4':'错花',
'5':'并纬',
'6':'缩纬',
'7':'缺纬',
'8':'糙纬',
'9':'折返',
'10':'断纬',
'11':'油污',
'12':'起机',
'13':'尽机',
'14':'经条',
'15':'擦白',
'16':'擦伤',
'17':'浆斑',
'18':'空织'
}
sheet_name_xlsx = 'xlsx格式测试表'

def write_excel_xlsx(workbook,path, sheet, value):
        index = len(value)
        # workbook = openpyxl.Workbook()
        # sheet = workbook.active
        # sheet = workbook.create_sheet(str(sheet_name))
        # sheet.title = sheet_name
        for i in range(0, index):
            for j in range(0, len(value[i])):
                sheet.cell(row=i+1, column=j+1, value=str(value[i][j]))
        workbook.save(path)

class AddstatisForm(QMainWindow):
    def __init__(self, parent=None, ui=None):
        super(AddstatisForm, self).__init__(parent)
        loadUi("UI/Statistics.ui", self)
        self.tablemodel = QStandardItemModel(10,2)
        self.tablemodel.setHorizontalHeaderLabels(['瑕疵种类','总数'])
        self.st_info.setModel(self.tablemodel)
        self.s1 = 'all'
        self.s2 = 'all'
        # self.cb = QComboBox()
        self.comboBox.addItem('all')
        self.comboBox.addItem('cam_01')
        self.comboBox.addItem('cam_02')
        self.comboBox.addItem('cam_03')
        self.comboBox_2.addItems(['all', '停车痕紧', '停车痕松','断经','错花','并纬','缩纬','缺纬','糙纬','折返','断纬','油污','起机','尽机','经条','擦白','擦伤','浆斑','空织'])
        # self.pushButton_2.clicked.connect(self.writoexc)
        self.pushButton_2.clicked.connect(self.getFile)
        self.pushButton.clicked.connect(self.sta_work_all)
        self.pushButton_3.clicked.connect(self.GetSeclectFile)
        self.comboBox.currentIndexChanged.connect(self.selectionchange)
        self.comboBox_2.currentIndexChanged.connect(self.selectionchange_2)
        self.cnt = -1
        

    # def writoexc(self):
        
    #     write_excel_xlsx(book_name_xlsx, sheet_name_xlsx, value3)
    
    def downallinfo(self):
        print(book_name_xlsx)
        workbook = openpyxl.Workbook()
        sheet1 = workbook.active
        sheet1.title = '停车痕紧'
        if(len(book_name_xlsx)>=6 and book_name_xlsx[-5:] == '.xlsx'):
            for i in range(19)[1:]:
                li = [['编号', '类型', '相机ID', 'X轴坐标', 'Y轴坐标', '宽度', '高度', '时间戳']]
                
                value3 = Database.getInstance().getDataFromFlaw(flaw_type=class_name[str(i)])
                for j in value3:
                    li.append(j)
                sheet_name_xlsx = class_name[str(i)]
                if (i == 1):
                    write_excel_xlsx(workbook,book_name_xlsx, sheet1, li)
                else:
                    sheet = workbook.create_sheet(str(sheet_name_xlsx))
                    write_excel_xlsx(workbook,book_name_xlsx, sheet, li)
                li = []

    def getFile(self):
        book_name_xlsx = QFileDialog.getSaveFileName(self,
                                    "另存为",
                                    "",
                                    "Excel工作簿(*.xlsx)")[0]
        print(book_name_xlsx)
        workbook = openpyxl.Workbook()
        sheet1 = workbook.active
        sheet1.title = '停车痕紧'
        if(len(book_name_xlsx)>=6 and book_name_xlsx[-5:] == '.xlsx'):
            for i in range(19)[1:]:
                li = [['编号', '类型', '相机ID', 'X轴坐标', 'Y轴坐标', '宽度', '高度', '时间戳']]
                
                value3 = Database.getInstance().getDataFromFlaw(flaw_type=class_name[str(i)])
                for j in value3:
                    li.append(j)
                sheet_name_xlsx = class_name[str(i)]
                if (i == 1):
                    write_excel_xlsx(workbook,book_name_xlsx, sheet1, li)
                else:
                    sheet = workbook.create_sheet(str(sheet_name_xlsx))
                    write_excel_xlsx(workbook,book_name_xlsx, sheet, li)
                li = []
    
    def sta_work_all(self):                         #界面显示
        value = Database.getInstance().getallFromFlawStatistic()
        self.cnt = -1
        for i in range(len(value)):
            label = value[i][0]
            num = value[i][1]
            self.show_work(label=label, num=num)

    def show_work(self, label = "0", num=0):     
        label = str(label)
        num=str(num)
        self.cnt += 1
        self.sm=self.tablemodel
        self.sm.setItem(self.cnt, 0, QStandardItem(label))
        self.sm.setItem(self.cnt, 1, QStandardItem(num))
        self.st_info.setModel(self.sm)
        #QTableView
        self.st_info.setColumnWidth(0,100)
        self.st_info.setColumnWidth(1,200)

    def selectionchange(self):
        self.s1 = self.comboBox.currentText()
        print(self.s1)

    def selectionchange_2(self):
        self.s2 = self.comboBox_2.currentText()
        print(self.s2)

    def GetSeclectFile(self):
        book_name_xlsx = QFileDialog.getSaveFileName(self,
                                    "另存为",
                                    "",
                                    "Excel工作簿(*.xlsx)")[0]
        print(book_name_xlsx)
        str1 = self.s1
        str2 = self.s2
        print(str1)
        print(str2)
        if (str2 == 'all'):
            workbook = openpyxl.Workbook()
            sheet1 = workbook.active
            sheet1.title = '停车痕紧'
            if(len(book_name_xlsx)>=6 and book_name_xlsx[-5:] == '.xlsx'):
                for i in range(19)[1:]:
                    li = [['编号', '类型', '相机ID', 'X轴坐标', 'Y轴坐标', '宽度', '高度', '时间戳']]
                
                    value3 = Database.getInstance().getDataFromFlaw(flaw_type=class_name[str(i)])
                    for j in value3:
                        if (j[2] == str1 or str1=='all'):
                            li.append(j)
                    sheet_name_xlsx = class_name[str(i)]
                    if (i == 1):
                        write_excel_xlsx(workbook,book_name_xlsx, sheet1, li)
                    else:
                        sheet = workbook.create_sheet(str(sheet_name_xlsx))
                        write_excel_xlsx(workbook,book_name_xlsx, sheet, li)
                    li = []
            
        else:
            workbook = openpyxl.Workbook()
            sheet1 = workbook.active
            sheet1.title = str2
            if (len(book_name_xlsx) >= 6 and book_name_xlsx[-5:] == '.xlsx'):
                li = [['编号', '类型', '相机ID', 'X轴坐标', 'Y轴坐标', '宽度', '高度', '时间戳']]  
                value3 = Database.getInstance().getDataFromFlaw(flaw_type=str2)
                for j in value3:
                    if (j[2] == str1 or str1=='all'):
                        li.append(j)
                write_excel_xlsx(workbook,book_name_xlsx, sheet1, li)
                
        <file_sep>/add_window/AddPicworkForm.py
from PyQt5.QtWidgets import QFileDialog
from PyQt5.uic import loadUi
from PyQt5.QtWidgets import QFileDialog
from PyQt5.QtGui import QPixmap
from PyQt5.QtGui import QImage
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5 import QtCore, QtWidgets
#from Database import Database
from add_window.AddMainWindow import AddMainWindow
import imghdr
import os.path
import cv2.cv2 as cv2
import numpy as np
from PIL import Image, ImageFont, ImageDraw
from yolo3.yolo import YOLO
class_name = {
'1':'停车痕紧',
'2':'停车痕松',
'3':'断经',
'4':'错花',
'5':'并纬',
'6':'缩纬',
'7':'缺纬',
'8':'糙纬',
'9':'折返',
'10':'断纬',
'11':'油污',
'12':'起机',
'13':'尽机',
'14':'经条',
'15':'擦白',
'16':'擦伤',
'17':'浆斑',
'18':'空织',
'19':'缺纬'
}
def file_extension(path):
    return os.path.splitext(path)[1]

class AddPicworkForm(AddMainWindow):
    def __init__(self, parent=None,yolo=None,model_flag='local'):
        super().__init__(parent, "UI/PicworkForm.ui")
        self.YOLO = yolo
        self.model_flag=model_flag
        self.shape = (640,480)
        self.path = ''
        self.cnt = -1
        self.type = 'error'

        self.tablemodel = QStandardItemModel(10,5)
        self.tablemodel.setHorizontalHeaderLabels(['瑕疵种类','X坐标','Y坐标','宽度W','高度H'])
        #self.tablemodels = QStandardItemModel(10,5)
        #self.tablemodels.setHorizontalHeaderLabels(['瑕疵种类','X坐标','Y坐标','宽度W','高度H'])
        self.TV_info.setModel(self.tablemodel)
        
        # self.add.clicked.connect(self.addToDatabase)
        self.cancel.clicked.connect(self.close)
        self.file_browse.clicked.connect(lambda: self.getFile(self.file))
        self.PB_work.clicked.connect(self.work)
    def close(self):
        #self.YOLO.close_session()
        self.destroy(True)

    def addToDatabase(self):
        pass
    def getFile(self, lineEdit):
        pic_map = QFileDialog.getOpenFileName()[0]
        self.path = pic_map
        lineEdit.setText(pic_map)
        # print(pic_map)
        if pic_map!="":
            if imghdr.what(pic_map)!=None:
                pixmap = QPixmap (pic_map)
                self.LB_Pic.setPixmap(pixmap)
                self.LB_Pic.setScaledContents(True)
                self.LB_Pic.show()
                self.type = 'pic'
            elif file_extension(pic_map) in ['.AVI','.avi','.MP4','.mp4','.mov','.MOV','.rmvb','.RMVB','.wmv','.WMV']:
                vid = cv2.VideoCapture(pic_map)
                if not vid.isOpened():
                    raise IOError("Couldn't open webcam or video")
                return_value, frame = vid.read()
                frame = cv2.resize(frame,(480,640))
                qimg = self.toQImage(frame)
                self.LB_Pic.setPixmap(QPixmap.fromImage(qimg))
                self.type = 'mov'
                vid.release()
            else:
                self.type = 'error'




    
    def identify_work(self, label = "0", X = 1.0, Y = 1.0, W = 1.0, H = 1.0):
        label = str(label)
        X = str(X)
        Y = str(Y)
        W = str(W)
        H = str(H)
        self.cnt += 1
        self.sm=self.tablemodel         
        self.sm.setItem(self.cnt, 0, QStandardItem(label))
        self.sm.setItem(self.cnt, 1, QStandardItem(X))
        self.sm.setItem(self.cnt, 2, QStandardItem(Y))
        self.sm.setItem(self.cnt, 3, QStandardItem(W))
        self.sm.setItem(self.cnt, 4, QStandardItem(H))
        self.TV_info.setModel(self.sm)
        #QTableView
        self.TV_info.setColumnWidth(0,100)
        self.TV_info.setColumnWidth(1,200)

    
    def toQImage(self, raw_img):
        from numpy import copy
        img = copy(raw_img)
        qformat = QImage.Format_Indexed8
        if len(img.shape) == 3:
            if img.shape[2] == 4:
                qformat = QImage.Format_RGBA8888
            else:
                qformat = QImage.Format_RGB888

        outImg = QImage(img.tobytes(), img.shape[1], img.shape[0], img.strides[0], qformat)
        outImg = outImg.rgbSwapped()
        return outImg

    @QtCore.pyqtSlot()
    def work(self):
        if self.type == 'pic':
            frame = cv2.imread(self.path)
            self.cnt = -1
            self.tablemodel = QStandardItemModel(10,5)
            self.tablemodel.setHorizontalHeaderLabels(['瑕疵种类','X坐标','Y坐标','宽度W','高度H'])
            self.TV_info.setModel(self.tablemodel)
            try:
                frame = cv2.resize(frame,(480,640))
                pack = self.object_detecation_pic(frame)
                frame = pack['frame']
                box = pack['box']
                for i in range(len(box['label'])):
                    self.identify_work(class_name[box['label'][i]], box['X'][i], box['Y'][i], box['W'][i], box['H'][i])
                qimg = self.toQImage(frame)
                self.LB_Pic.setPixmap(QPixmap.fromImage(qimg))
            except:
                print("image error")
        elif self.type == 'mov':
            vid = cv2.VideoCapture(self.path)
            self.cnt = -1
            self.tablemodel = QStandardItemModel(10,5)
            self.tablemodel.setHorizontalHeaderLabels(['瑕疵种类','X坐标','Y坐标','宽度W','高度H'])
            self.TV_info.setModel(self.tablemodel)
            while True:
                return_value, frame = vid.read()
                if return_value:
                    try:
                        frame = cv2.resize(frame,(480,640))
                        pack = self.object_detecation_pic(frame)
                        frame = pack['frame']
                        box = pack['box']
                        for i in range(len(box['label'])):
                            self.identify_work(class_name[box['label'][i]], box['X'][i], box['Y'][i], box['W'][i], box['H'][i])
                        qimg = self.toQImage(frame)
                        self.LB_Pic.setPixmap(QPixmap.fromImage(qimg))
                    except:
                        print("image error")
                if cv2.waitKey(1) & 0xFF == ord('q'):
                    break
            vid.release()
        else:
            self.LB_Pic.setText("请选择图片或视频")





    
    def object_detecation_pic(self,frame):
        ans={}
        if (isinstance(frame,np.ndarray)):        
            #image = cv2.resize(frame,self.shape)
            image = Image.fromarray(frame)
            image,ans = self.YOLO.detect_image(image)
            #image,ans = yolo.detect_image(image)
            frame = np.asarray(image)
        else:
            frame = None
        pack = {'frame': frame,'box':ans}
        return pack

    def closeEvent(self,QCloseEvent):
        res = QMessageBox.question(self,'提示','是否退出？',QMessageBox.Yes|QMessageBox.No,QMessageBox.No)
        if res == QMessageBox.Yes:
            QCloseEvent.accept()
        else:
            QCloseEvent.ignore()  

    # def addToDatabase(self):
    #     id = str(self.id.text())
    #     group = str(self.group.text())
    #     location = str(self.location.text())
    #     x = str(self.x_coord.text())
    #     y = str(self.y_coord.text())
    #     file = str(self.file.text())
    #     Database.getInstance().insertIntoCamera(id, location, x, y, group, file)
    #     self.destroy()
<file_sep>/processor/MainProcessor.py
from Database import Database
from processor.DetectionProcessor import DetectionProcessor


class MainProcessor:

    def __init__(self, camera_id):
        self.cam_ids = camera_id
        #CamAinfo = Database.getInstance().getCaminfo(camera_id[0])
        #CamBinfo = Database.getInstance().getCaminfo(camera_id[1])
        #CamCinfo = Database.getInstance().getCaminfo(camera_id[2])

        self.processor = DetectionProcessor()


    def getProcessedImage(self,yolo,frames=None):
        dicti = self.processor.object_detection(frames,yolo)
        return dicti<file_sep>/processor/DetectionProcessor.py
import sys
sys.path.append("..")
import cv2.cv2 as cv2
import numpy as np
#import datatime
from yolo3.yolo import YOLO
from PIL import Image, ImageFont, ImageDraw
class DetectionProcessor:
    def __init__(self):
        self.shape = (320,640)
        self.cnt = 0
    def object_detection(self,frames,yolo):
        ans={}
        ans1={}
        ans2={}
        if (isinstance(frames[0],np.ndarray)):        
            image = cv2.resize(frames[0],self.shape)
            image = Image.fromarray(image)
            image,ans = yolo.detect_image(image)
            self.frame01 = np.asarray(image)
        else:
            self.frame01 = None
        if (isinstance(frames[1],np.ndarray)):        
            #self.frame02 = cv2.resize(frames[1],self.shape)
            image1 = cv2.resize(frames[1],self.shape)
            image1 = Image.fromarray(image1)
            image1,ans1 = yolo.detect_image(image1)
            self.frame02 = np.asarray(image1)
        else:
            self.frame02 = None
        if (isinstance(frames[2],np.ndarray)):        
            #self.frame03 = cv2.resize(frames[2],self.shape)
            image2 = cv2.resize(frames[2],self.shape)
            image2 = Image.fromarray(image2)
            image2,ans2 = yolo.detect_image(image2)
            self.frame03 = np.asarray(image2)
        else:
            self.frame03 = None

        pack = {'frame01': self.frame01,'frame02': self.frame02,'frame03':self.frame03,'boxes1':ans,'boxes2':ans1,'boxes3':ans2}
        return pack

    
<file_sep>/add_window/Setsetting.py
from PyQt5.QtWidgets import QFileDialog
from PyQt5.QtWidgets import QMessageBox
from PyQt5 import QtCore, QtWidgets
from Database import Database
from add_window.AddMainWindow import AddMainWindow


class SetSetting(AddMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent, "UI/Setting.ui")
        #self.file_browse.clicked.connect(lambda: self.getFile(self.file))
        self.setok.clicked.connect(self.updataSetToDatabase)
        self.clearall.clicked.connect(self.clearSetToDatabase)
        # caminfo = Database.getInstance().getCaminfo(ID=camid)[0]
        self.hight.setText('')
        self.wid.setText('')
        self.rate_video.setText('')
        self.model.setText('yolo')
        model_name = str(self.model.text())
        rate = Database.getInstance().getSetting(model=model_name)
        wid_value = rate[0]
        hight_value = rate[1]
        rate_value = rate[2] 
        self.hight.setText(str(hight_value))
        self.wid.setText(str(wid_value))
        self.rate_video.setText(str(rate_value))

    @QtCore.pyqtSlot()
    def clearSetToDatabase(self):
        model_name = str(self.model.text())
        Database.getInstance().updateSetting(model_name)
        rate = Database.getInstance().getSetting(model=model_name)
        wid_value = rate[0]
        hight_value = rate[1]
        rate_value = rate[2] 
        self.hight.setText(str(hight_value))
        self.wid.setText(str(wid_value))
        self.rate_video.setText(str(rate_value))
        #self.model.setText('')

    @QtCore.pyqtSlot()
    def updataSetToDatabase(self):
        model_name = str(self.model.text())
        hight_value = str(self.hight.text())
        wid_value = str(self.wid.text())
        rate_value = str(self.rate_video.text())
        Database.getInstance().updateSetting(model_name,wid_value,hight_value,rate_value)
    
    def closeEvent(self,QCloseEvent):
        res = QMessageBox.question(self,'提示','是否保存设置？',QMessageBox.Yes|QMessageBox.No,QMessageBox.No)
        if res == QMessageBox.Yes:
            model_name = str(self.model.text())
            hight_value = str(self.hight.text())
            wid_value = str(self.wid.text())
            rate_value = str(self.rate_video.text())
            Database.getInstance().updateSetting(model_name,wid_value,hight_value,rate_value)
            QCloseEvent.accept()
        else:
            QCloseEvent.accept()
        

<file_sep>/yolo3/yolo.py
# -*- coding: utf-8 -*-
"""
Class definition of YOLO_v3 style detection model on image and video
"""

import colorsys
import os
from timeit import default_timer as timer
import numpy as np
from keras import backend as K
from keras.models import load_model
from keras.layers import Input
from PIL import Image, ImageFont, ImageDraw
import requests
import json
from yolo3.yolo3.model import yolo_eval, yolo_body, tiny_yolo_body
from yolo3.yolo3.utils import letterbox_image
import os
from keras.utils import multi_gpu_model
class_name = {
'1':'停车痕紧',
'2':'停车痕松',
'3':'断经',
'4':'错花',
'5':'并纬',
'6':'缩纬',
'7':'缺纬',
'8':'糙纬',
'9':'折返',
'10':'断纬',
'11':'油污',
'12':'起机',
'13':'尽机',
'14':'经条',
'15':'擦白',
'16':'擦伤',
'17':'浆斑',
'18':'空织'
}

class YOLO(object):
    _defaults = {
        "model_path": 'yolo3/model_data/yolov3forflaw.h5',
        "anchors_path": 'yolo3/model_data/yolo_anchors.txt',
        "classes_path": 'yolo3/model_data/classes.txt',
        "score" : 0.3,
        "iou" : 0.45,
        "model_image_size" : (416, 416),
        "gpu_num" : 1,
    }
    # _defaults = {
    #     "model_path": 'yolo3/model_data/yolov3.h5',
    #     "anchors_path": 'yolo3/model_data/yolo_anchors.txt',
    #     "classes_path": 'yolo3/model_data/coco_classes.txt',
    #     "score" : 0.3,
    #     "iou" : 0.45,
    #     "model_image_size" : (416, 416),
    #     "gpu_num" : 1,
    # }

    @classmethod
    def get_defaults(cls, n):
        if n in cls._defaults:
            return cls._defaults[n]
        else:
            return "Unrecognized attribute name '" + n + "'"

    def __init__(self, **kwargs):
        self.__dict__.update(self._defaults) # set up default values
        self.__dict__.update(kwargs) # and update with user overrides
        self.class_names = self._get_class()
        self.anchors = self._get_anchors()
        self.sess = K.get_session()
        self._t1 = 0.3
        self._t2 = 0.45
        self.boxes, self.scores, self.classes = self.generate()

    def _get_class(self):
        classes_path = os.path.expanduser(self.classes_path)
        with open(classes_path) as f:
            class_names = f.readlines()
        class_names = [c.strip() for c in class_names]
        return class_names

    def _get_anchors(self):
        anchors_path = os.path.expanduser(self.anchors_path)
        with open(anchors_path) as f:
            anchors = f.readline()
        anchors = [float(x) for x in anchors.split(',')]
        return np.array(anchors).reshape(-1, 2)

    def generate(self):
        model_path = os.path.expanduser(self.model_path)
        assert model_path.endswith('.h5'), 'Keras model or weights must be a .h5 file.'

        # Load model, or construct model and load weights.
        num_anchors = len(self.anchors)
        num_classes = len(self.class_names)
        is_tiny_version = num_anchors==6 # default setting
        try:
            self.yolo_model = load_model(model_path, compile=False)
        except:
            self.yolo_model = tiny_yolo_body(Input(shape=(None,None,3)), num_anchors//2, num_classes) \
                if is_tiny_version else yolo_body(Input(shape=(None,None,3)), num_anchors//3, num_classes)
            self.yolo_model.load_weights(self.model_path) # make sure model, anchors and classes match
        else:
            assert self.yolo_model.layers[-1].output_shape[-1] == \
                num_anchors/len(self.yolo_model.output) * (num_classes + 5), \
                'Mismatch between model and given anchor and class sizes'

        print('{} model, anchors, and classes loaded.'.format(model_path))

        # Generate colors for drawing bounding boxes.
        hsv_tuples = [(x / len(self.class_names), 1., 1.)
                      for x in range(len(self.class_names))]
        self.colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples))
        self.colors = list(
            map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)),
                self.colors))
        np.random.seed(10101)  # Fixed seed for consistent colors across runs.
        np.random.shuffle(self.colors)  # Shuffle colors to decorrelate adjacent classes.
        np.random.seed(None)  # Reset seed to default.

        # Generate output tensor targets for filtered bounding boxes.
        self.input_image_shape = K.placeholder(shape=(2, ))
        if self.gpu_num>=2:
            self.yolo_model = multi_gpu_model(self.yolo_model, gpus=self.gpu_num)
        boxes, scores, classes = yolo_eval(self.yolo_model.output, self.anchors,
                len(self.class_names), self.input_image_shape,
                score_threshold=self.score, iou_threshold=self.iou)
        return boxes, scores, classes

    def detect_image(self, image):
        start = timer()
        ans = {}
        ans['label']=[]
        ans['X']=[]
        ans['Y']=[]
        ans['W']=[]
        ans['H']=[]

        if self.model_image_size != (None, None):
            assert self.model_image_size[0]%32 == 0, 'Multiples of 32 required'
            assert self.model_image_size[1]%32 == 0, 'Multiples of 32 required'
            boxed_image = letterbox_image(image, tuple(reversed(self.model_image_size)))
        else:
            new_image_size = (image.width - (image.width % 32),
                              image.height - (image.height % 32))
            boxed_image = letterbox_image(image, new_image_size)
        image_data = np.array(boxed_image, dtype='float32')

        print(image_data.shape)
        image_data /= 255.
        image_data = np.expand_dims(image_data, 0)  # Add batch dimension.
        print(image_data.shape)
        out_boxes, out_scores, out_classes = self.sess.run(
            [self.boxes, self.scores, self.classes],
            feed_dict={
                self.yolo_model.input: image_data,
                self.input_image_shape: [image.size[1], image.size[0]],
                K.learning_phase(): 0
            })

        print('Found {} boxes for {}'.format(len(out_boxes), 'img'))

        font = ImageFont.truetype(font='yolo3/font/FiraMono-Medium.otf',
                    size=np.floor(3e-2 * image.size[1] + 0.5).astype('int32'))
        thickness = (image.size[0] + image.size[1]) // 300

        for i, c in reversed(list(enumerate(out_classes))):
            predicted_class = self.class_names[c]
            box = out_boxes[i]
            score = out_scores[i]

            label = '{} {:.2f}'.format(predicted_class, score)
            draw = ImageDraw.Draw(image)
            label_size = draw.textsize(label, font)

            top, left, bottom, right = box
            top = max(0, np.floor(top + 0.5).astype('int32'))
            left = max(0, np.floor(left + 0.5).astype('int32'))
            bottom = min(image.size[1], np.floor(bottom + 0.5).astype('int32'))
            right = min(image.size[0], np.floor(right + 0.5).astype('int32'))
            print(label, (left, top), (right, bottom))
            ans['label'].append(str(predicted_class))
            ans['X'].append((left+right)/2)
            ans['Y'].append((top+bottom)/2)
            ans['W'].append(right-left)
            ans['H'].append(bottom-top)

            if top - label_size[1] >= 0:
                text_origin = np.array([left, top - label_size[1]])
            else:
                text_origin = np.array([left, top + 1])

            # My kingdom for a good redistributable image drawing library.
            for i in range(thickness):
                draw.rectangle(
                    [left + i, top + i, right - i, bottom - i],
                    outline=self.colors[c])
            draw.rectangle(
                [tuple(text_origin), tuple(text_origin + label_size)],
                fill=self.colors[c])
            draw.text(text_origin, label, fill=(0, 0, 0), font=font)
            del draw

        end = timer()
        print(end - start)
        return image,ans

    def online_detect_image(self, image=None,endpoint = "http://192.168.3.3:8500"):
        start = timer()
        ans = {}
        ans['label']=[]
        ans['X']=[]
        ans['Y']=[]
        ans['W']=[]
        ans['H']=[]

        if self.model_image_size != (None, None):
            assert self.model_image_size[0]%32 == 0, 'Multiples of 32 required'
            assert self.model_image_size[1]%32 == 0, 'Multiples of 32 required'
            boxed_image = letterbox_image(image, tuple(reversed(self.model_image_size)))
        else:
            new_image_size = (image.width - (image.width % 32),
                              image.height - (image.height % 32))
            boxed_image = letterbox_image(image, new_image_size)
        image_data = np.array(boxed_image, dtype='float32')

        print(image_data.shape)
        image_data /= 255.
        image_data = np.expand_dims(image_data, 0)  # Add batch dimension.
        print(image_data.shape)
        inputda = np.array(image_data).tolist()
        input_data = {
            "model_name": "default",
            "model_version": 1,
            "data": {
                "images": inputda}
        }
        
        result = requests.post(endpoint, json=input_data)
        new_dict = json.loads(result.text)
        out_boxes = np.array(new_dict['out_boxes'])
        out_scores = np.array(new_dict['out_scores'])
        out_classes = np.array(new_dict['out_classes'])
        output = [out_boxes,out_classes,out_scores]
        out_boxes, out_classes , out_scores= self._yolo_out(output,[image.size[1], image.size[0]])

        print('Found {} boxes for {}'.format(len(out_boxes), 'img'))

        font = ImageFont.truetype(font='yolo3/font/FiraMono-Medium.otf',
                    size=np.floor(3e-2 * image.size[1] + 0.5).astype('int32'))
        thickness = (image.size[0] + image.size[1]) // 300

        for i, c in reversed(list(enumerate(out_classes))):
            predicted_class = self.class_names[c]
            box = out_boxes[i]
            score = out_scores[i]

            label = '{} {:.2f}'.format(predicted_class, score)
            draw = ImageDraw.Draw(image)
            label_size = draw.textsize(label, font)

            top, left, bottom, right = box
            top = max(0, np.floor(top + 0.5).astype('int32'))
            left = max(0, np.floor(left + 0.5).astype('int32'))
            bottom = min(image.size[1], np.floor(bottom + 0.5).astype('int32'))
            right = min(image.size[0], np.floor(right + 0.5).astype('int32'))
            print(label, (left, top), (right, bottom))
            ans['label'].append(str(predicted_class))
            ans['X'].append((left+right)/2)
            ans['Y'].append((top+bottom)/2)
            ans['W'].append(right-left)
            ans['H'].append(bottom-top)

            if top - label_size[1] >= 0:
                text_origin = np.array([left, top - label_size[1]])
            else:
                text_origin = np.array([left, top + 1])

            # My kingdom for a good redistributable image drawing library.
            for i in range(thickness):
                draw.rectangle(
                    [left + i, top + i, right - i, bottom - i],
                    outline=self.colors[c])
            draw.rectangle(
                [tuple(text_origin), tuple(text_origin + label_size)],
                fill=self.colors[c])
            draw.text(text_origin, label, fill=(0, 0, 0), font=font)
            del draw

        end = timer()
        print(end - start)
        return image,ans

    def close_session(self):
        self.sess.close()
    
    def _yolo_out(self, outs, shape):
        """Process output of yolo base net.
        # Argument:
            outs: output of yolo base net.
            shape: shape of original image.
        # Returns:
            boxes: ndarray, boxes of objects.
            classes: ndarray, classes of objects.
            scores: ndarray, scores of objects.
        """
        masks = [[6, 7, 8], [3, 4, 5], [0, 1, 2]]
        anchors = [[10, 13], [16, 30], [33, 23], [30, 61], [62, 45],
                   [59, 119], [116, 90], [156, 198], [373, 326]]

        boxes, classes, scores = [], [], []

        for out, mask in zip(outs, masks):
            b, c, s = self._process_feats(out, anchors, mask)
            b, c, s = self._filter_boxes(b, c, s)
            boxes.append(b)
            classes.append(c)
            scores.append(s)

        boxes = np.concatenate(boxes)
        classes = np.concatenate(classes)
        scores = np.concatenate(scores)

        # Scale boxes back to original image shape.
        width, height = shape[1], shape[0]
        image_dims = [width, height, width, height]
        boxes = boxes * image_dims

        nboxes, nclasses, nscores = [], [], []
        for c in set(classes):
            inds = np.where(classes == c)
            b = boxes[inds]
            c = classes[inds]
            s = scores[inds]

            keep = self._nms_boxes(b, s)

            nboxes.append(b[keep])
            nclasses.append(c[keep])
            nscores.append(s[keep])

        if not nclasses and not nscores:
            return None, None, None

        boxes = np.concatenate(nboxes)
        classes = np.concatenate(nclasses)
        scores = np.concatenate(nscores)

        return boxes, classes, scores

    def _nms_boxes(self, boxes, scores):
        """Suppress non-maximal boxes.
        # Arguments
            boxes: ndarray, boxes of objects.
            scores: ndarray, scores of objects.
        # Returns
            keep: ndarray, index of effective boxes.
        """
        x = boxes[:, 0]
        y = boxes[:, 1]
        w = boxes[:, 2]
        h = boxes[:, 3]

        areas = w * h
        order = scores.argsort()[::-1]

        keep = []
        while order.size > 0:
            i = order[0]
            keep.append(i)

            xx1 = np.maximum(x[i], x[order[1:]])
            yy1 = np.maximum(y[i], y[order[1:]])
            xx2 = np.minimum(x[i] + w[i], x[order[1:]] + w[order[1:]])
            yy2 = np.minimum(y[i] + h[i], y[order[1:]] + h[order[1:]])

            w1 = np.maximum(0.0, xx2 - xx1 + 1)
            h1 = np.maximum(0.0, yy2 - yy1 + 1)
            inter = w1 * h1

            ovr = inter / (areas[i] + areas[order[1:]] - inter)
            inds = np.where(ovr <= self._t2)[0]
            order = order[inds + 1]

        keep = np.array(keep)

        return keep

    def _sigmoid(self, x):
        """sigmoid.
        # Arguments
            x: Tensor.
        # Returns
            numpy ndarray.
        """
        return 1 / (1 + np.exp(-x))

    def _process_feats(self, out, anchors, mask):
        """process output features.
        # Arguments
            out: Tensor (N, N, 3, 4 + 1 +80), output feature map of yolo.
            anchors: List, anchors for box.
            mask: List, mask for anchors.
        # Returns
            boxes: ndarray (N, N, 3, 4), x,y,w,h for per box.
            box_confidence: ndarray (N, N, 3, 1), confidence for per box.
            box_class_probs: ndarray (N, N, 3, 80), class probs for per box.
        """
        grid_h, grid_w, num_boxes = map(int, out.shape[1: 4])

        anchors = [anchors[i] for i in mask]
        anchors_tensor = np.array(anchors).reshape(1, 1, len(anchors), 2)

        # Reshape to batch, height, width, num_anchors, box_params.
        out = out[0]
        box_xy = self._sigmoid(out[..., :2])
        box_wh = np.exp(out[..., 2:4])
        box_wh = box_wh * anchors_tensor

        box_confidence = self._sigmoid(out[..., 4])
        box_confidence = np.expand_dims(box_confidence, axis=-1)
        box_class_probs = self._sigmoid(out[..., 5:])

        col = np.tile(np.arange(0, grid_w), grid_w).reshape(-1, grid_w)
        row = np.tile(np.arange(0, grid_h).reshape(-1, 1), grid_h)

        col = col.reshape(grid_h, grid_w, 1, 1).repeat(3, axis=-2)
        row = row.reshape(grid_h, grid_w, 1, 1).repeat(3, axis=-2)
        grid = np.concatenate((col, row), axis=-1)

        box_xy += grid
        box_xy /= (grid_w, grid_h)
        box_wh /= (416, 416)
        box_xy -= (box_wh / 2.)
        boxes = np.concatenate((box_xy, box_wh), axis=-1)

        return boxes, box_confidence, box_class_probs

    def _filter_boxes(self, boxes, box_confidences, box_class_probs):
        """Filter boxes with object threshold.
        # Arguments
            boxes: ndarray, boxes of objects.
            box_confidences: ndarray, confidences of objects.
            box_class_probs: ndarray, class_probs of objects.
        # Returns
            boxes: ndarray, filtered boxes.
            classes: ndarray, classes for boxes.
            scores: ndarray, scores for boxes.
        """
        box_scores = box_confidences * box_class_probs
        box_classes = np.argmax(box_scores, axis=-1)
        box_class_scores = np.max(box_scores, axis=-1)
        pos = np.where(box_class_scores >= self._t1)

        boxes = boxes[pos]
        classes = box_classes[pos]
        scores = box_class_scores[pos]

        return boxes, classes, scores

