コード例 #1
0
    class Main(QMainWindow):
        def __init__(self):
            super(Main, self).__init__()
            tf.import_graph_def(graph_def, name='')
            # Start the webserver first
            self.initializeWebServer()
            # This gives the server time start before actually trying to connect to it.
            time.sleep(2)
            # Then start the socketio client to send realtime updates
            self.net = Net()
            # Load GUI
            uic.loadUi('user_interface/main.ui', self)
            # Initialize UI elements
            self.initUI()
            self.traffic_light = None
            self.traffic_camera = None

            # Initialize Timers
            self.initializeTimers()

            # State and Static Variables
            self.cameraSelected = True
            self.numOfCarsDetected = 0
            self.numOfVehiclesViolated = 0
            self.carsDetected.setText(str(self.numOfCarsDetected))
            self.H = None
            self.W = None
            self.clockTimer.start()
            self.frame = 0
            self.objectsToCount = []
            self.timeTracker = []
            self.objectsToDetectViolation = []
            self.timeTracker2 = []
            # self.alpr = Alpr("us", "/etc/openalpr/openalpr.conf", )
            # Load config before starting camera
            config.loadConfig()

            # Start camera
            self.start_camera()
            self.stopButton.clicked.connect(self.stop)
            self.changeCameraButton.clicked.connect(self.changeCamera)
            self.configButton.clicked.connect(self.showConfig)
            self.camera1_frame = None
            self.camera2_frame = None

            self.contours = np.array(
                [[200, 20], [700, 20], [1280, 300], [1280, 720], [300, 720]],
                np.int32)
            self.yellow_box = np.array(
                [[230, 86], [550, 86], [850, 210], [280, 210]], np.int32)
            self.plate_number_process = Process(
                target=self.plateDetectionAndOcr)
            self.trafficLightState = ""

        def plateDetectionAndOcr(self, image):
            plate = run(image)
            # cv.imshow('plate', plate)
            # cv.waitKey(1000)
            return plate

        def initializeTimers(self):
            # This is responseible for the frame timing
            self.frameTimer = QtCore.QTimer(self, interval=1)
            # This updates the clock
            self.clockTimer = QtCore.QTimer(self, interval=60000)
            # This sets the http requests every 5 seconds
            # self.networkTimer = QtCore.QTimer(self, interval=5000)
            # Connect the function dependent on the timers
            self.frameTimer.timeout.connect(self.updateTrafficLightFrame)
            self.frameTimer.timeout.connect(self.updateTrafficFrame)
            self.clockTimer.timeout.connect(self.updateClock)
            # self.networkTimer.timeout.connect(self.sendUpdates)
            # self.networkTimer.start()

        @QtCore.pyqtSlot()
        def sendUpdates(self):
            self.net.sendRoutineUpdate(self.numOfCarsDetected,
                                       self.numOfVehiclesViolated)

        @QtCore.pyqtSlot()
        def initializeWebServer(self):
            print('starting server')
            web.runServerOnThread()

        def initUI(self):
            self.imageLabel.setScaledContents(True)
            self.trafficLight.setScaledContents(True)
            self.config = Config()
            self.config.setWindowModality(QtCore.Qt.ApplicationModal)
            self.config.setFixedSize(QSize(630, 470))
            self.setWindowTitle('Detection Window')

        def stop(self):
            # Release the source first (ip cam or footage)
            self.traffic_light.release()
            self.traffic_camera.release()
            # Close the tf session
            sess.close()

            # Close the http client connection
            self.net.closeConnection()

            # Shutdown thewebserver
            web.shutdownServerOnThread()

            # Exit Gracefully
            sys.exit()

            try:
                sys.exit()
            except:
                print(sys.exc_info()[0])

        @QtCore.pyqtSlot()
        def updateClock(self):
            now = datetime.datetime.now()
            self.day.setText(now.strftime("%A"))
            self.date.setText(now.strftime("%B %d, %Y"))
            # self.time.setText(time.strftime("%H:%M:%S", time.localtime()))

        @QtCore.pyqtSlot()
        def start_camera(self):

            if self.traffic_light is None:
                self.traffic_light = cv.VideoCapture(
                    State.config_dict['CAMERA_1'], 0)
                self.traffic_light.set(cv.CAP_PROP_FRAME_HEIGHT, 1920)
                self.traffic_light.set(cv.CAP_PROP_FRAME_WIDTH, 1080)

            if self.traffic_camera is None:
                self.traffic_camera = cv.VideoCapture(
                    State.config_dict['CAMERA_2'], 0)
                self.traffic_camera.set(cv.CAP_PROP_FRAME_WIDTH, 1920)
                self.traffic_camera.set(cv.CAP_PROP_FRAME_HEIGHT, 1080)

            self.frameTimer.start()

        @QtCore.pyqtSlot()
        def updateTrafficLightFrame(self):
            ret, frame = self.traffic_light.read()

            if not ret:
                frame = cv.imread('standby.jpg', 0)
                displayImage(frame, True, self.imageLabel)
            else:

                resized = cv.resize(self.camera2_frame, (1280, 720))
                self.camera1_frame = cv.resize(frame, (1280, 720))

                x = 300 * 2
                y = 177 * 2
                w = 7 * 2
                h = 16 * 2
                roi = self.camera1_frame[y:y + h, x:x + w]

                displayImage(self.camera1_frame, True, self.imageLabel)
                self.trafficLightState = getTrafficLightStatus(roi)
                if self.trafficLightState == "GREEN":
                    self.trafficLightStatus.setText(self.trafficLightState)
                    self.trafficLightStatus.setStyleSheet('color: green')
                elif self.trafficLightState == "AMBER":
                    self.trafficLightStatus.setText(self.trafficLightState)
                    self.trafficLightStatus.setStyleSheet('color: yellow')
                elif self.trafficLightState == "RED":
                    self.trafficLightStatus.setText(self.trafficLightState)
                    self.trafficLightStatus.setStyleSheet('color: red')

                image_ = cv.resize(roi, (64, 28))
                displayTraffic(image_, True, self.trafficLight)

        @QtCore.pyqtSlot()
        def updateTrafficFrame(self):
            self.frame += 1
            flag, self.camera2_frame = self.traffic_camera.read()

            if not flag:
                self.camera2_frame = cv.imread('standby.jpg', 0)
                displayImage(self.camera2_frame, True, self.imageLabel)
            else:
                resized = cv.resize(self.camera2_frame, (1280, 720))

                # if self.frame < 130:
                #     return
                # else:
                #     self.frameTimer.setInterval(250)

                roi = None

                if self.cameraSelected and sess:

                    img = cv.resize(resized, (1280, 720))
                    # Add the roi to the image
                    rows = img.shape[0]
                    cols = img.shape[1]

                    # cv.fillPoly(img, pts=[self.contours], color=(255, 255, 255, 125))
                    # alpha = 0.4
                    # img = cv.addWeighted(overlay, alpha, img, 1 - alpha, 0)
                    # cv.imshow('img', img)

                    # 1
                    # bounding = cv.boundingRect(self.contours)
                    # x, y, w, h = bounding
                    # cropped = img[y:y+h, x:x+h].copy()

                    img_copy = img.copy()

                    # Make mask
                    # pts = self.contours - self.contours.min(axis=0)

                    mask = np.zeros(img_copy.shape[:2], np.uint8)
                    cv.drawContours(mask, [self.contours], -1, (255, 255, 255),
                                    -1, cv.LINE_AA)
                    # do bit op
                    dst = cv.bitwise_and(img_copy, img_copy, mask=mask)
                    inp = cv.resize(dst, (300, 300))
                    inp = inp[:, :, [2, 1, 0]]  # BGR2RGB
                    overlay = img.copy()

                    if self.W is None or self.H is None:
                        (self.H, self.W) = img.shape[:2]

                    # Run the model
                    out = sess.run(
                        [
                            sess.graph.get_tensor_by_name('num_detections:0'),
                            sess.graph.get_tensor_by_name(
                                'detection_scores:0'),
                            sess.graph.get_tensor_by_name('detection_boxes:0'),
                            sess.graph.get_tensor_by_name(
                                'detection_classes:0')
                        ],
                        feed_dict={
                            'image_tensor:0':
                            inp.reshape(1, inp.shape[0], inp.shape[1], 3)
                        })

                    # plate_number = sess.run([sess.pn_graph.get_tensor_by_name('num_detections:0'),
                    #                 sess.graph.get_tensor_by_name('detection_scores:0'),
                    #                 sess.graph.get_tensor_by_name('detection_boxes:0'),
                    #                 sess.graph.get_tensor_by_name('detection_classes:0')],
                    #                 feed_dict={'image_tensor:0': inp.reshape(1, inp.shape[0], inp.shape[1], 3)})

                    # Visualize detected bounding boxes.
                    num_detections = int(out[0][0])
                    rois = []
                    rects = []

                    # Loop over the detections
                    for i in range(num_detections):
                        classId = int(out[3][0][i])
                        score = float(out[1][0][i])

                        bbox = [float(v) for v in out[2][0][i]]
                        if score > 0.2:
                            x = bbox[1] * cols
                            y = bbox[0] * rows
                            right = bbox[3] * cols
                            bottom = bbox[2] * rows

                            new_x = int(x * 1.5)
                            new_y = int(y * 1.5)
                            new_right = int(right * 1.5)
                            new_bottom = int(bottom * 1.5)
                            # Set width threshold
                            if (int(right) - int(x) <= 450):

                                if (int((y + bottom) / 2) >= 201):
                                    cv.rectangle(img, (int(x), int(y)),
                                                 (int(right), int(bottom)),
                                                 (0, 255, 0), 2)
                                else:
                                    cv.rectangle(img, (int(x), int(y)),
                                                 (int(right), int(bottom)),
                                                 (0, 0, 255), 2)

                                roi = self.camera2_frame[new_y:new_y +
                                                         (new_bottom - new_y),
                                                         new_x:new_x +
                                                         (new_right - new_x)]
                                rois.append(roi)
                                rect = np.array([x, y, right, bottom])
                                rects.append(rect.astype("int"))

                    # Run the plate number detection in the rois of the frame
                    # for x in range(len(rois)):
                    #     cv.imshow('roi', rois[x])
                    #     cv.waitKey(0)

                    objects = ct.update(rects)

                    for (objectID, centroid) in objects.items():
                        # object on the output frame
                        text = "ID {}".format(objectID)
                        cv.putText(img, text,
                                   (centroid[0] - 10, centroid[1] - 10),
                                   cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0),
                                   2)
                        cv.circle(img, (centroid[0], centroid[1]), 4,
                                  (0, 255, 0), -1)
                        # check if the car is already counted if not append to array
                        # print(centroid[1])
                        if centroid[1] >= 200:
                            if len(self.objectsToCount) > 0:
                                for x in range(len(self.objectsToCount)):
                                    # print('[x]: ' + str(x))
                                    # print(self.objectsToCount[x]['id'])
                                    # if objectID != self.objectsToCount[x]['id']:
                                    if not any(d['id'] == objectID
                                               for d in self.objectsToCount):
                                        # print(str(objectID) + ' not equal to ' + str(self.objectsToCount[x]['id']))
                                        dict_ = {
                                            'coords': centroid,
                                            'is_counted': False,
                                            'id': objectID
                                        }
                                        # Check if the objectid that the system is trying to add already in the self.objects_to_track list
                                        check = next(
                                            (index for (index, d) in enumerate(
                                                self.objectsToCount)
                                             if d["id"] == objectID), None)
                                        # Check if the id has expired before adding to array
                                        index = next((index for (
                                            index,
                                            d) in enumerate(self.timeTracker)
                                                      if d["id"] == objectID),
                                                     None)
                                        if index is not None and check is not None:
                                            current_time = datetime.datetime.now(
                                            )
                                            if current_time >= self.timeTracker[
                                                    index]['time_exp']:
                                                # print(current_time.time() + ' vs ' + self.timeTracker[index]['time_exp'].time(), end=' ')
                                                self.objectsToCount.append(
                                                    dict_)
                                                self.timeTracker.append({
                                                    'id':
                                                    objectID,
                                                    'time_exp':
                                                    datetime.datetime.now() +
                                                    datetime.timedelta(0, 1)
                                                })
                                                # delete na yung tracker here?
                                                self.timeTracker.pop(index)
                                        else:
                                            # Dont check the time just add new one
                                            self.objectsToCount.append(dict_)
                                            self.timeTracker.append({
                                                'id':
                                                objectID,
                                                'time_exp':
                                                datetime.datetime.now() +
                                                datetime.timedelta(0, 1)
                                            })

                                    else:
                                        index = next(
                                            (index for (index, d) in enumerate(
                                                self.objectsToCount)
                                             if d["id"] == objectID), None)
                                        if index is not None:
                                            self.objectsToCount[index][
                                                'coords'] = centroid
                            else:
                                dict_ = {
                                    'coords': centroid,
                                    'is_counted': False,
                                    'id': objectID
                                }
                                self.objectsToCount.append(dict_)
                                self.timeTracker.append({
                                    'id':
                                    objectID,
                                    'time_exp':
                                    datetime.datetime.now() +
                                    datetime.timedelta(0, 1)
                                })
                        else:
                            if self.trafficLightState == 'RED':
                                # If nag violate
                                if len(self.objectsToDetectViolation) > 0:
                                    for x in range(
                                            len(self.objectsToDetectViolation)
                                    ):
                                        # print('[x]: ' + str(x))
                                        # print(self.objectsToCount[x]['id'])
                                        # if objectID != self.objectsToCount[x]['id']:
                                        if not any(d['id'] == objectID
                                                   for d in self.
                                                   objectsToDetectViolation):

                                            # index = next((index for (index, d) in enumerate(self.objectsToDetectViolation) if d["coords"][0] == ()), None)
                                            bbox = []

                                            for x, y, endx, endy in rects:
                                                centroidx = int((x + endx) / 2)

                                                if centroidx == centroid[0]:
                                                    bbox = [x, y, endx, endy]

                                            dict_ = {
                                                'coords': centroid,
                                                'violated': False,
                                                'id': objectID,
                                                'bbox': bbox
                                            }
                                            # Check if the objectid that the system is trying to add already in the self.objects_to_track list
                                            check = next(
                                                (index
                                                 for (index, d) in enumerate(
                                                     self.
                                                     objectsToDetectViolation)
                                                 if d["id"] == objectID), None)
                                            # Check if the id has expired before adding to array
                                            index = next(
                                                (index for (index, d) in
                                                 enumerate(self.timeTracker2)
                                                 if d["id"] == objectID), None)
                                            if index is not None and check is not None:
                                                current_time = datetime.datetime.now(
                                                )
                                                if current_time >= self.timeTracker[
                                                        index]['time_exp']:
                                                    # print(current_time.time() + ' vs ' + self.timeTracker[index]['time_exp'].time(), end=' ')
                                                    self.objectsToDetectViolation.append(
                                                        dict_)
                                                    self.timeTracker2.append({
                                                        'id':
                                                        objectID,
                                                        'time_exp':
                                                        datetime.datetime.now(
                                                        ) + datetime.timedelta(
                                                            0, 5)
                                                    })
                                                    # delete na yung tracker here?
                                                    self.timeTracker2.pop(
                                                        index)
                                            else:
                                                # Dont check the time just add new one
                                                self.objectsToDetectViolation.append(
                                                    dict_)
                                                self.timeTracker2.append({
                                                    'id':
                                                    objectID,
                                                    'time_exp':
                                                    datetime.datetime.now() +
                                                    datetime.timedelta(0, 5)
                                                })

                                        else:
                                            index = next(
                                                (index
                                                 for (index, d) in enumerate(
                                                     self.
                                                     objectsToDetectViolation)
                                                 if d["id"] == objectID), None)
                                            if index is not None:
                                                self.objectsToDetectViolation[
                                                    index]['coords'] = centroid
                                else:
                                    bbox = []

                                    for x, y, endx, endy in rects:
                                        centroidx = int((x + endx) / 2)

                                        if centroidx == centroid[0]:
                                            bbox = [x, y, endx, endy]

                                    dict_ = {
                                        'coords': centroid,
                                        'violated': False,
                                        'id': objectID,
                                        'bbox': bbox
                                    }
                                    self.objectsToDetectViolation.append(dict_)
                                    self.timeTracker2.append({
                                        'id':
                                        objectID,
                                        'time_exp':
                                        datetime.datetime.now() +
                                        datetime.timedelta(0, 1)
                                    })
                                # print('ok')

                        # print(objectID, centroid)

                    if len(self.objectsToCount) > 0:
                        for i in range(len(self.objectsToDetectViolation)):
                            if self.objectsToDetectViolation[i][
                                    'violated'] == False:
                                (x, y
                                 ) = self.objectsToDetectViolation[i]['coords']

                                if y < 200:
                                    # Violated
                                    self.objectsToDetectViolation[i][
                                        'violated'] = True
                                    self.numOfVehiclesViolated += 1
                                    self.violationsDetected.setText(
                                        str(self.numOfVehiclesViolated))
                                    index = next((
                                        index
                                        for (index,
                                             d) in enumerate(self.timeTracker2)
                                        if d["id"] == self.
                                        objectsToDetectViolation[i]['id']),
                                                 None)
                                    del self.timeTracker2[index]

                                    print('BEAT')
                                    x, y, endx, endy = self.objectsToDetectViolation[
                                        i]['bbox']

                                    # Detect platenumber\
                                    car_roi = self.camera2_frame[
                                        int(y * 1.5):int(endy * 1.5),
                                        int(x * 1.5):int(endx * 1.5)]

                                    plate_roi = self.plateDetectionAndOcr(
                                        car_roi)

                                    self.net.sendRoutineUpdate(
                                        self.numOfCarsDetected,
                                        self.numOfVehiclesViolated)

                                    # cv.imshow('roasdasdasd', roi)
                                    time_str = str(time.time())
                                    plate_url = '/home/lr/Desktop/tvds-integrated-final/data/red_light/plate_' + time_str + '.jpg'
                                    car_url = '/home/lr/Desktop/tvds-integrated-final/data/red_light/car_' + time_str + '.jpg'
                                    plate_url2 = 'red_light/plate_' + time_str + '.jpg'
                                    car_url2 = 'red_light/car_' + time_str + '.jpg'
                                    cv.imwrite(plate_url, plate_roi)
                                    cv.imwrite(car_url, car_roi)

                                    data = {
                                        'violation_type':
                                        'PASSING THE RED LIGHT',
                                        'vehicle_type': 'Car',
                                        'plate_number': 'plate',
                                        'plate_number_img_url': plate_url2,
                                        'vehicle_img_url': car_url2
                                    }

                                    add_violation(data)

                    if len(self.objectsToCount) > 0:
                        for i in range(len(self.objectsToCount)):
                            if self.objectsToCount[i]['is_counted'] == False:
                                (x, y) = self.objectsToCount[i]['coords']
                                # print('y['+str(i)+']: ' + str(y))
                                if y < 300:
                                    self.numOfCarsDetected += 1
                                    self.objectsToCount[i]['is_counted'] = True
                                    index = next(
                                        (index
                                         for (index,
                                              d) in enumerate(self.timeTracker)
                                         if d["id"] == self.objectsToCount[i]
                                         ['id']), None)
                                    del self.timeTracker[index]
                                    self.sendUpdates()

                    img = cv.line(img, (372, 200), (861, 200), (255, 0, 255),
                                  1)
                    img = cv.line(img, (372, 300), (861, 300), (255, 255, 0),
                                  1)

                    self.carsDetected.setText(str(self.numOfCarsDetected))

                    cv.polylines(img, [self.yellow_box], True, (255, 125, 125))
                    displayImage(img, True, self.imageLabel)
                    # cv.imshow('dst', dst)
                    # cv.imshow('img', img)
                    # cv.waitKey(1)
                else:
                    displayImage(self.camera1_frame, True, self.imageLabel)

        @QtCore.pyqtSlot()
        def capture_image(self):
            flag, frame = self.trafficLightStatus.read()
            path = r'J:\Face'
            if flag:
                QtWidgets.QApplication.beep()
                name = "opencv_frame_{}.png".format(self._image_counter)
                cv.imwrite(os.path.join(path, name), frame)
                self._image_counter += 1

        def changeCamera(self):
            self.start_camera()
            self.cameraSelected = not self.cameraSelected

        def showConfig(self):
            print('Show config')
            self.config.show()

        @QtCore.pyqtSlot()
        def detectPlateNumber(self, frame):
            frame_process = frame.copy()
            # Read the graph.
            with tf.gfile.FastGFile('ml/plate_number_inference_graph.pb',
                                    'rb') as f:
                graph_def1 = tf.GraphDef()
                graph_def1.ParseFromString(f.read())

                application = QtWidgets.QApplication(sys.argv)

                with tf.Session() as sess:
                    sess = tf.Session()
                    sess.graph.as_default()

                    rows = frame.shape[0]
                    cols = frame.shape[1]

                    # sess.pn_graph.as_default()
                    # tf.import_graph_def(pn_graph_def, name='')
                    tf.import_graph_def(graph_def1, name='')

                    inp = cv.resize(frame_process, (300, 300))
                    inp = inp[:, :, [2, 1, 0]]  # BGR2RGB
                    # Run the model
                    plate_number = sess.run(
                        [
                            sess.graph.get_tensor_by_name('num_detections:0'),
                            sess.graph.get_tensor_by_name(
                                'detection_scores:0'),
                            sess.graph.get_tensor_by_name('detection_boxes:0'),
                            sess.graph.get_tensor_by_name(
                                'detection_classes:0')
                        ],
                        feed_dict={
                            'image_tensor:0':
                            inp.reshape(1, inp.shape[0], inp.shape[1], 3)
                        })

                    # Visualize detected bounding boxes.
                    num_detections = int(plate_number[0][0])
                    rois = []
                    rects = []

                    # Loop over the detections
                    for i in range(num_detections):
                        classId = int(plate_number[3][0][i])
                        score = float(plate_number[1][0][i])

                        bbox = [float(v) for v in plate_number[2][0][i]]

                        if score > 0.2:
                            x = bbox[1] * cols
                            y = bbox[0] * rows
                            right = bbox[3] * cols
                            bottom = bbox[2] * rows

                            new_x = int(x * 1.5)
                            new_y = int(y * 1.5)
                            new_right = int(right * 1.5)
                            new_bottom = int(bottom * 1.5)
                            # Set width threshold
                            cv.rectangle(frame_process, (int(x), int(y)),
                                         (int(right), int(bottom)),
                                         (0, 255, 0), 2)

                    sess.close()
                    return frame_process