Ejemplo n.º 1
0
    def make_axis(self):
        if self.x_time_scaled:
            axis_x = QDateTimeAxis()
            axis_x.setFormat("yyyy-MM-dd HH:mm:ss")
            axis_x.setTitleText("Время")
        else:
            axis_x = QValueAxis()
            axis_x.setTitleText(self.x_name)

        if self.x_min:
            axis_x.setMin(self.x_min)
        if self.x_max:
            axis_x.setMax(self.x_max)

        axis_x.setLabelsAngle(self.x_label_angle)
        axis_x.setTickCount(self.x_tick_num)

        axis_y = QValueAxis()
        if self.y_min:
            axis_y.setMin(self.y_min)
        if self.y_max:
            axis_y.setMax(self.y_max)

        axis_y.setTitleText(self.y_name)
        axis_y.setTickCount(self.y_tick_num)
        axis_y.setLabelsAngle(self.y_label_angle)

        return axis_x, axis_y
Ejemplo n.º 2
0
class BalanceHistoryChartView(QChartView):
    """
    Chart that displays the balance between several dates
    from an account, token or whole portfolio
    """

    def __init__(self,  *args,  **kwargs):
        super().__init__(*args, **kwargs)

        self.chart = QChart()
        self.FIAT_CURRENCY = confighandler.get_fiat_currency()

    def setupChartWithData(self, selectiontype, name=None):
        """
        Chart gets updated displaying new data.
        The data gets extracted from cbalancehistory, according 
        to the selection

        Parameters:
            - selectiontype : in ('account','token','all')
            - name: str, corresponds to account/token on cbalancehistory

        """
        self.chart = QChart()

        self.chart.setTheme(QChart.ChartThemeDark)
        self.chart.setAnimationOptions(QChart.SeriesAnimations)
        self.chart.setBackgroundBrush(QBrush(QColor('#19232d')))
#         self.chart.setTitle("")
#         self.chart.setTitleBrush(QBrush(QColor('white')))

        # Data
        # Get data
        if selectiontype == 'token':
            assert(name is not None)
            data = chistoricalbalances.get_balances_with_token_tuple(name)
        elif selectiontype == 'account':
            assert(name is not None)
            data = chistoricalbalances.get_balances_with_account_tuple(name)
        elif selectiontype == 'all':
            data = chistoricalbalances.get_balances_by_day_tuple()
        # Separate balance_btc from balance_fiat
        dates, balances_btc, balances_fiat = [], [], []
        for date in data:
            dates.append(int(date))
            balances_btc.append(data[date][0])
            balances_fiat.append(data[date][1])

        # Series
        self.btcseries = QSplineSeries()
        self.fiatseries = QSplineSeries()
        for date, balance_btc, balance_fiat in zip(dates, balances_btc, balances_fiat):
            date = datetime.fromtimestamp(date)
            date = datetime(date.year, date.month, date.day)
            dateQ = QDateTime(date).toMSecsSinceEpoch()
            self.btcseries.append(dateQ, balance_btc)
            self.fiatseries.append(dateQ, balance_fiat)

        # Append current point
        currentdate = QDateTime(datetime.today()).toMSecsSinceEpoch()
        if selectiontype == "all":
            # Append current balances
            self.btcseries.append(currentdate,
                                  cbalances.get_total_balance_all_accounts())
            self.fiatseries.append(currentdate,
                                   cbalances.get_total_balance_all_accounts_fiat())
        elif name != '':
            if selectiontype == "account":
                # Append current balances
                self.btcseries.append(
                    currentdate, cbalances.get_total_account_balance(name))
                self.fiatseries.append(
                    currentdate, cbalances.get_total_account_balance_fiat(name))
            elif selectiontype == "token":
                pass

        # Axis X (Dates)
        self.x_axis = QDateTimeAxis()
        self.x_axis.setTickCount(11)
        self.x_axis.setLabelsAngle(70)
        self.x_axis.setFormat("dd-MM-yy")
        self.x_axis.setTitleText(self.tr('Date'))

        # Axis Y (Balances)
        # BTC
        self.y_axis_btc = QValueAxis()
        if len(balances_btc) > 0:
            self.y_axis_btc.setMax(max(balances_btc)*1.1)
            self.y_axis_btc.setMin(min(balances_btc)*0.9)
        # Fiat
        self.y_axis_fiat = QValueAxis()
        if len(balances_fiat) > 0:
            self.y_axis_fiat.setMax(max(balances_fiat)*1.1)
            self.y_axis_fiat.setMin(min(balances_fiat)*0.9)

        self.chart.addAxis(self.y_axis_btc, Qt.AlignLeft)
        self.chart.addAxis(self.y_axis_fiat, Qt.AlignRight)
        self.chart.addAxis(self.x_axis, Qt.AlignBottom)

        # Add series to chart
        # BTC
        self.btcseries.setName("BTC")
        self.chart.addSeries(self.btcseries)
        self.btcseries.attachAxis(self.x_axis)
        self.btcseries.attachAxis(self.y_axis_btc)
        # Fiat
        self.fiatseries.setName(self.FIAT_CURRENCY.upper())
        self.chart.addSeries(self.fiatseries)
        self.fiatseries.attachAxis(self.x_axis)
        self.fiatseries.attachAxis(self.y_axis_fiat)

        self.setChart(self.chart)
        self.setRenderHint(QPainter.Antialiasing)
        self.setStyleSheet("border: 0px")
Ejemplo n.º 3
0
class SeeingMonitor(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(SeeingMonitor, self).__init__()
        self.setupUi(self)

        self.Camera = None
        self.THRESH = None
        self.threshold_auto = False
        self.frame = None
        self.draw_only_frame = None
        self.video_source = VideoSource.NONE
        self.export_video = False
        self.select_noiseArea = False
        self.coordinates_noiseArea = []
        self.lineedit_path.setText(QDir.currentPath())
        self.lineedit_filename.setText("seeing.csv")
        self.save_filename = None
        self._updateFileSave()
        self.pause_pressed = False

        self.datetimeedit_start.setMinimumDateTime(QDateTime.currentDateTime())
        self.datetimeedit_end.setMinimumDateTime(QDateTime.currentDateTime())

        if platform.system() == 'Linux':
            self.button_start.setEnabled(False)
            self.button_settings.setEnabled(False)

        self.button_start.clicked.connect(self.startLiveCamera)
        self.button_settings.clicked.connect(self.showSettings)
        self.button_simulation.clicked.connect(self.startSimulation)
        self.button_import.clicked.connect(self.importVideo)
        self.button_export.clicked.connect(self.exportVideo)
        self.button_noise.clicked.connect(self.selectNoiseArea)
        self.lineedit_path.textEdited.connect(self._updateFileSave)
        self.lineedit_filename.textEdited.connect(self._updateFileSave)
        self.slider_threshold.valueChanged.connect(self._updateThreshold)
        self.checkbox_thresh.stateChanged.connect(self._updateThresholdState)

        # Update the Tilt value
        self.spinbox_b.valueChanged.connect(self._updateFormulaZTilt)
        self.spinbox_d.valueChanged.connect(self._updateFormulaZTilt)
        # Update the constants in the FWHM seeing formula
        self.spinbox_d.valueChanged.connect(self._updateFormulaConstants)
        self.spinbox_lambda.valueChanged.connect(self._updateFormulaConstants)

        # Timer for acquiring images at regular intervals
        self.acquisition_timer = QTimer(parent=self.centralwidget)
        self.timer_interval = None

        self._updateThreshold()
        self._updateFormulaZTilt()
        self._updateFormulaConstants()

        # Storing the Delta X and Y in an array to calculate the Standard Deviation
        self.arr_delta_x = deque(maxlen=100)
        self.arr_delta_y = deque(maxlen=100)

        self.plot_length = 1000
        self.fwhm_lat = 0
        self.fwhm_tra = 0
        self.max_lat = 1
        self.min_lat = 0
        self.max_tra = 1
        self.min_tra = 0

        self.series_lat = QLineSeries()
        self.series_lat.setName("Lateral")
        self.series_tra = QLineSeries()
        self.series_tra.setName("Transversal")

        self.chart = QChart()
        self.chart.addSeries(self.series_lat)
        self.chart.addSeries(self.series_tra)

        # self.chart.createDefaultAxes()
        self.axis_horizontal = QDateTimeAxis()
        self.axis_horizontal.setMin(QDateTime.currentDateTime().addSecs(-60 *
                                                                        1))
        self.axis_horizontal.setMax(QDateTime.currentDateTime().addSecs(0))
        self.axis_horizontal.setFormat("HH:mm:ss.zzz")
        self.axis_horizontal.setLabelsFont(
            QFont(QFont.defaultFamily(self.font()), pointSize=5))
        self.axis_horizontal.setLabelsAngle(-20)
        self.chart.addAxis(self.axis_horizontal, Qt.AlignBottom)

        self.axis_vertical_lat = QValueAxis()
        self.axis_vertical_lat.setRange(self.max_lat, self.min_lat)
        self.chart.addAxis(self.axis_vertical_lat, Qt.AlignLeft)

        self.axis_vertical_tra = QValueAxis()
        self.axis_vertical_tra.setRange(self.max_tra, self.min_tra)
        self.chart.addAxis(self.axis_vertical_tra, Qt.AlignRight)

        self.series_lat.attachAxis(self.axis_horizontal)
        self.series_lat.attachAxis(self.axis_vertical_lat)

        self.series_tra.attachAxis(self.axis_horizontal)
        self.series_tra.attachAxis(self.axis_vertical_tra)

        self.chart.setTitle("Full Width at Half Maximum")
        self.chart.legend().setVisible(True)
        self.chart.legend().setAlignment(Qt.AlignBottom)
        self.chartView = QChartView(self.chart, parent=self.graphicsView)
        self.chartView.resize(640, 250)
        self.chartView.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
        self.chartView.setRenderHint(QPainter.Antialiasing)

    def closeEvent(self, event):
        try:
            self.Camera.StopLive()
        except AttributeError:
            pass

        try:
            self.cap.release()
        except AttributeError:
            pass

        try:
            self.video_writer.release()
        except AttributeError:
            pass

        event.accept()

    def _callbackFunction(self, hGrabber, pBuffer, framenumber, pData):
        """ This is an example callback function for image processig  with 
            opencv. The image data in pBuffer is converted into a cv Matrix
            and with cv.mean() the average brightness of the image is
            measuered.

        :param: hGrabber: This is the real pointer to the grabber object.
        :param: pBuffer : Pointer to the first pixel's first byte
        :param: framenumber : Number of the frame since the stream started
        :param: pData : Pointer to additional user data structure
        """
        if pData.buffer_size > 0:
            image = C.cast(pBuffer, C.POINTER(C.c_ubyte * pData.buffer_size))

            cvMat = np.ndarray(buffer=image.contents,
                               dtype=np.uint8,
                               shape=(pData.height, pData.width,
                                      pData.iBitsPerPixel))

            frame = np.uint8(cvMat)
            self.frame = cv2.resize(frame, (640, 480))
            self.draw_only_frame = self.frame.copy()
            self._monitor()

    def _startLiveCamera(self):

        # Create a function pointer
        Callbackfunc = IC.TIS_GrabberDLL.FRAMEREADYCALLBACK(
            self._callbackFunction)
        ImageDescription = CallbackUserData()

        # Create the camera object
        self.Camera = IC.TIS_CAM()

        self.Camera.ShowDeviceSelectionDialog()
        if self.Camera.IsDevValid() != 1:
            print("[Error Camera Selection] Couldn't open camera device !")
            # QMessageBox.warning(self, "Error Camera Selection", "Couldn't open camera device !")
            # raise Exception("Unable to open camera device !")
            return

        # Now pass the function pointer and our user data to the library
        self.Camera.SetFrameReadyCallback(Callbackfunc, ImageDescription)

        # Handle each incoming frame automatically
        self.Camera.SetContinuousMode(0)

        print('Starting live stream ...')
        self.Camera.StartLive(
            0
        )  ####### PAUSE LIVE STREAM WHEN PAUSE CLICKED ??? ##############################################
        # self.Camera.StartLive(1)

        Imageformat = self.Camera.GetImageDescription()[:3]
        ImageDescription.width = Imageformat[0]
        ImageDescription.height = Imageformat[1]
        ImageDescription.iBitsPerPixel = Imageformat[2] // 8
        ImageDescription.buffer_size = ImageDescription.width * ImageDescription.height * ImageDescription.iBitsPerPixel

        while self.video_source == VideoSource.CAMERA:
            pass

        # self.timer_interval = 20
        # try:
        #     self.acquisition_timer.disconnect()
        # except TypeError:
        #     pass
        # self.acquisition_timer.timeout.connect(self._updateLiveCamera)
        # self.acquisition_timer.start(self.timer_interval)

    def startLiveCamera(self):
        try:
            self.acquisition_timer.disconnect()
        except TypeError:
            pass

        self.video_source = VideoSource.CAMERA
        self.button_export.setEnabled(True)
        self._setPauseButton()

        # Disable other functionalities
        # self.button_simulation.setEnabled(False)

        t = threading.Thread(target=self._startLiveCamera,
                             args=(),
                             daemon=True)
        t.start()

    def showSettings(self):
        if not self.Camera.IsDevValid():
            QMessageBox.warning(
                self, "Camera Selection Error",
                "Please select a camera first by clicking on the button <strong>Start</strong>"
            )
            return

        try:
            self.Camera.ShowPropertyDialog()
        except Exception as e:
            logging.error(traceback.format_exc())
            QMessageBox.warning(self, "Property Dialog Error",
                                traceback.format_exc())

    # def _updateLiveCamera(self):
    #     # Capturing a frame
    #     self.Camera.SnapImage()
    #     frame = self.Camera.GetImage()
    #     frame = np.uint8(frame)
    #     self.frame = cv2.resize(frame, (640, 480))
    #     self.draw_only_frame = self.frame.copy()
    #     self._monitor()

    # self.displayParameters()

    def displayParameters(self):
        parameters_text = ""

        ExposureTime = [0]
        self.Camera.GetPropertyAbsoluteValue("Exposure", "Value", ExposureTime)
        parameters_text = parameters_text + str(ExposureTime[0]) + "\n"

        GainValue = [0]
        self.Camera.GetPropertyAbsoluteValue("Gain", "Value", GainValue)
        parameters_text = parameters_text + str(GainValue[0]) + "\n"

        self.parameters_label.setText(parameters_text)
        self.parameters_label.adjustSize()

    def startSimulation(self):

        if self.Camera != None and self.Camera.IsDevValid() == 1:
            self.Camera.StopLive()
        self.video_source = VideoSource.SIMULATION
        self.button_export.setEnabled(True)
        self._setPauseButton()

        # Disable other functionalities
        # self.button_start.setEnabled(False)
        self.button_settings.setEnabled(False)

        # Generating fake images of DIMM star (One single star that is split by the DIMM)
        self.starsGenerator = FakeStars()
        self.timer_interval = 100

        try:
            self.acquisition_timer.disconnect()
        except TypeError:
            pass
        self.acquisition_timer.timeout.connect(self._updateSimulation)
        self.acquisition_timer.start(self.timer_interval)

    def _updateSimulation(self):
        frame = self.starsGenerator.generate()
        self.frame = cv2.resize(frame, (640, 480))
        self.draw_only_frame = self.frame.copy()
        self._monitor()


################################################################################################################################################################

    def _writeCSV(self, headerOnly=False):
        if headerOnly:
            with open(self.save_filename, "w") as csvFile:
                fieldnames = ["timestamp", "lateral", "transversal", "star"]
                writer = csv.DictWriter(csvFile, fieldnames=fieldnames)
                writer.writeheader()
                csvFile.close()

        else:
            with open(self.save_filename, "a") as csvFile:
                writer = csv.writer(csvFile)
                writer.writerow([
                    self.current.toTime_t(), self.fwhm_lat, self.fwhm_tra,
                    self.lineedit_star.text()
                ])
                # csvFile.write(",".join([str(self.current) , str(self.fwhm_lat), str(self.fwhm_tra), self.lineedit_star.text()]))
                # csvFile.write("\n")
                # csvFile.close()

    def selectNoiseArea(self):
        self.label_info.setText("Please select on the video a noise area.")
        self.button_noise.setText("Selecting ...")
        self.coordinates_noiseArea = []
        self.select_noiseArea = True

    def _set_noiseArea(self, x1, y1, x2, y2):
        if len(self.coordinates_noiseArea) == 0:
            self.coordinates_noiseArea.append([x1, y1])
            self.coordinates_noiseArea.append([x2, y2])

        elif len(self.coordinates_noiseArea) == 2:
            self.coordinates_noiseArea[0] = [x1, y1]
            self.coordinates_noiseArea[1] = [x2, y2]

    def _draw_noiseArea(self):
        if len(self.coordinates_noiseArea) >= 2:
            cv2.rectangle(self.draw_only_frame,
                          (self.coordinates_noiseArea[0][0],
                           self.coordinates_noiseArea[0][1]),
                          (self.coordinates_noiseArea[1][0],
                           self.coordinates_noiseArea[1][1]), (0, 255, 0), 1)

    def _updateFileSave(self):
        self.save_filename = join(self.lineedit_path.text(),
                                  self.lineedit_filename.text())
        self._writeCSV(headerOnly=True)

    def _updateThreshold(self):
        if self.threshold_auto:
            if self.coordinates_noiseArea.__len__() >= 2:
                noise_area = self.frame[self.coordinates_noiseArea[0][1]:self.
                                        coordinates_noiseArea[1][1],
                                        self.coordinates_noiseArea[0][0]:self.
                                        coordinates_noiseArea[1][0]]
                try:
                    self.THRESH = noise_area.max() + 20
                    # self.THRESH = int(round(noise_area.mean()))
                except ValueError:
                    return

                self.slider_threshold.setValue(self.THRESH)
                self.checkbox_thresh.setText("Threshold ({}, auto)".format(
                    self.THRESH))
        else:
            self.THRESH = self.slider_threshold.value()
            self.checkbox_thresh.setText("Threshold ({})".format(self.THRESH))

    def _updateThresholdState(self, state):
        if state == 0:
            self.threshold_auto = False
            self.slider_threshold.setEnabled(True)
        else:
            if self.coordinates_noiseArea.__len__() < 2:
                QMessageBox.information(self, "Select Noise Area",
                                        "Please select the noise area")
                self.selectNoiseArea()

            self.threshold_auto = True
            self.slider_threshold.setEnabled(False)

    def _updateFormulaZTilt(self):
        self.spinbox_d.setStyleSheet("QSpinBox { background-color: blue; }")
        try:
            b = float(self.spinbox_b.value()) / float(self.spinbox_d.value())
        except ZeroDivisionError:
            QMessageBox.warning(self, "Zero Division Error",
                                "D (Apertures Diameter cannot be Zero")
            return
        self.K_lat = 0.364 * (1 - 0.532 * np.power(b, -1 / 3) -
                              0.024 * np.power(b, -7 / 3))
        self.K_tra = 0.364 * (1 - 0.798 * np.power(b, -1 / 3) -
                              0.018 * np.power(b, -7 / 3))

    def _updateFormulaConstants(self):
        # Calculate value to make process faster
        self.A = 0.98 * np.power(
            float(self.spinbox_d.value()) / float(self.spinbox_lambda.value()),
            0.2)

    def _calcSeeing(self):
        std_x = np.std(self.arr_delta_x)
        std_y = np.std(self.arr_delta_y)

        # Seeing
        self.current = QDateTime.currentDateTime()
        self.fwhm_lat = self.A * np.power(std_x / self.K_lat, 0.6)
        self.fwhm_tra = self.A * np.power(std_y / self.K_tra, 0.6)

        threading.Thread(target=self._plotSeeing, args=(), daemon=True).start()
        threading.Thread(target=self._writeCSV, args=(), daemon=True).start()

        self.label_info.setText("lat: " + str(self.fwhm_lat) + " | lon: " +
                                str(self.fwhm_tra))

    def _calcSeeing_arcsec(self):
        std_x = np.std(self.arr_delta_x)
        std_y = np.std(self.arr_delta_y)

        # Seeing
        self.current = QDateTime.currentDateTime()
        self.fwhm_lat = self.A * np.power(
            std_x / self.K_lat, 0.6) * 205.0 * self.spinbox_pwidth.value(
            ) / self.spinbox_focal.value()
        self.fwhm_tra = self.A * np.power(
            std_y / self.K_tra, 0.6) * 205.0 * self.spinbox_pheight.value(
            ) / self.spinbox_focal.value()

        threading.Thread(target=self._plotSeeing, args=(), daemon=True).start()
        threading.Thread(target=self._writeCSV, args=(), daemon=True).start()

        self.label_info.setText("lat: " + str(self.fwhm_lat) + " | lon: " +
                                str(self.fwhm_tra))

    def _monitor(self):

        tic = time.time()

        gray = cv2.cvtColor(self.frame, cv2.COLOR_BGR2GRAY)

        self._updateThreshold()
        _, thresholded = cv2.threshold(gray, self.THRESH, 255,
                                       cv2.THRESH_TOZERO)

        # _, contours, _ = cv2.findContours(thresholded, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        contours, _ = cv2.findContours(thresholded, cv2.RETR_EXTERNAL,
                                       cv2.CHAIN_APPROX_NONE)

        contours = contours[:2]

        # if contours.__len__() > 2:
        #     QMessageBox.warning(self, "Thresholding error", "More than 2 projections were found. " + \
        #         "Please increase threshold manually or select a better noise area.")

        cv2.drawContours(self.draw_only_frame, contours, -1, (0, 255, 0), 2)
        self._draw_noiseArea()

        try:
            moments_star_1 = cv2.moments(contours[0])
            moments_star_2 = cv2.moments(contours[1])

        except IndexError:
            print("Only {} were found ! (Must be at least 2)".format(
                len(contours)))

        else:

            try:
                cX_star1 = int(moments_star_1["m10"] / moments_star_1["m00"])
                cY_star1 = int(moments_star_1["m01"] / moments_star_1["m00"])

                cX_star2 = int(moments_star_2["m10"] / moments_star_2["m00"])
                cY_star2 = int(moments_star_2["m01"] / moments_star_2["m00"])

            except ZeroDivisionError:
                return

            if self.enable_seeing.isChecked():
                delta_x = abs(cX_star2 - cX_star1)
                delta_y = abs(cY_star2 - cY_star1)

                self.arr_delta_x.append(delta_x)
                self.arr_delta_y.append(delta_y)

                # self._calcSeeing()
                self._calcSeeing_arcsec()

            cv2.drawMarker(self.draw_only_frame, (cX_star1, cY_star1),
                           color=(0, 0, 255),
                           markerSize=30,
                           thickness=1)
            cv2.drawMarker(self.draw_only_frame, (cX_star2, cY_star2),
                           color=(0, 0, 255),
                           markerSize=30,
                           thickness=1)

        finally:

            self._displayImage()

            threading.Thread(target=self._writeVideoFile, args=(),
                             daemon=True).start()

        toc = time.time()
        elapsed = toc - tic
        try:
            print("FPS max = {}".format(int(1.0 / elapsed)))
        except ZeroDivisionError:
            pass

    def _displayImage(self):
        qImage = array2qimage(self.draw_only_frame)
        self.stars_capture.setPixmap(QPixmap(qImage))

    def _plotSeeing(self):

        self.axis_horizontal.setMin(QDateTime.currentDateTime().addSecs(-60 *
                                                                        1))
        self.axis_horizontal.setMax(QDateTime.currentDateTime().addSecs(0))

        if self.series_lat.count() > self.plot_length - 1:
            self.series_lat.removePoints(
                0,
                self.series_lat.count() - self.plot_length - 1)

        if self.series_tra.count() > self.plot_length - 1:
            self.series_tra.removePoints(
                0,
                self.series_tra.count() - self.plot_length - 1)

        if self.fwhm_lat > self.max_lat:
            self.max_lat = self.fwhm_lat
            self.axis_vertical_lat.setMax(self.max_lat + 10)
        if self.fwhm_lat < self.min_lat:
            self.min_lat = self.fwhm_lat
            self.axis_vertical_lat.setMax(self.min_lat - 10)
        if self.fwhm_tra > self.max_tra:
            self.max_tra = self.fwhm_tra
            self.axis_vertical_tra.setMax(self.max_tra + 10)
        if self.fwhm_tra < self.min_tra:
            self.min_tra = self.fwhm_tra
            self.axis_vertical_tra.setMax(self.min_tra - 10)

        # print(self.fwhm_lat, self.fwhm_tra)

        self.series_lat.append(self.current.toMSecsSinceEpoch(), self.fwhm_lat)
        self.series_tra.append(self.current.toMSecsSinceEpoch(), self.fwhm_tra)

    def importVideo(self):

        self.video_source = VideoSource.VIDEO
        self.button_export.setEnabled(True)
        self._setPauseButton()

        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        filename, _ = QFileDialog.getOpenFileName(
            self,
            "Import from Video File",
            QDir.currentPath(),
            "Video Files (*.avi *.mp4 *.mpeg *.flv *.3gp *.mov);;All Files (*)",
            options=options)

        if filename:
            if self.Camera != None and self.Camera.IsDevValid() == 1:
                self.Camera.StopLive()

            self.cap = cv2.VideoCapture(filename)

            # print("CAP_PROP_POS_MSEC :", self.cap.get(cv2.CAP_PROP_POS_MSEC))
            # print("CAP_PROP_POS_FRAMES :", self.cap.get(cv2.CAP_PROP_POS_FRAMES))
            # print("CAP_PROP_POS_AVI_RATIO :", self.cap.get(cv2.CAP_PROP_POS_AVI_RATIO))
            # print("CAP_PROP_FRAME_WIDTH :", self.cap.get(cv2.CAP_PROP_FRAME_WIDTH))
            # print("CAP_PROP_FRAME_HEIGHT :", self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
            # print("CAP_PROP_FPS :", self.cap.get(cv2.CAP_PROP_FPS))
            # print("CAP_PROP_FOURCC :", self.cap.get(cv2.CAP_PROP_FOURCC))
            # print("CAP_PROP_FRAME_COUNT :", self.cap.get(cv2.CAP_PROP_FRAME_COUNT))
            # print("CAP_PROP_FORMAT :", self.cap.get(cv2.CAP_PROP_FORMAT))
            # print("CAP_PROP_MODE :", self.cap.get(cv2.CAP_PROP_MODE))
            # print("CAP_PROP_BRIGHTNESS :", self.cap.get(cv2.CAP_PROP_BRIGHTNESS))
            # print("CAP_PROP_CONTRAST :", self.cap.get(cv2.CAP_PROP_CONTRAST))
            # print("CAP_PROP_SATURATION :", self.cap.get(cv2.CAP_PROP_SATURATION))
            # print("CAP_PROP_HUE :", self.cap.get(cv2.CAP_PROP_HUE))
            # print("CAP_PROP_GAIN :", self.cap.get(cv2.CAP_PROP_GAIN))
            # print("CAP_PROP_EXPOSURE :", self.cap.get(cv2.CAP_PROP_EXPOSURE))
            # print("CAP_PROP_CONVERT_RGB :", self.cap.get(cv2.CAP_PROP_CONVERT_RGB))
            # print("CAP_PROP_WHITE_APERTURE :", self.cap.get(cv2.CAP_PROP_APERTURE))
            # print("CAP_PROP_RECTIFICATION :", self.cap.get(cv2.CAP_PROP_RECTIFICATION))
            # print("CAP_PROP_ISO_SPEED :", self.cap.get(cv2.CAP_PROP_ISO_SPEED))
            # print("CAP_PROP_BUFFERSIZE :", self.cap.get(cv2.CAP_PROP_BUFFERSIZE))

            if self.cap.isOpened() == False:
                QMessageBox.warning(self, "Import from Video",
                                    "Cannot load file '{}'.".format(filename))
                return

            self.timer_interval = round(1000.0 /
                                        self.cap.get(cv2.CAP_PROP_FPS))
            try:
                self.acquisition_timer.disconnect()
            except TypeError:
                pass
            self.acquisition_timer.timeout.connect(self._grabVideoFrame)
            self.acquisition_timer.start(self.timer_interval)

    def _grabVideoFrame(self):
        ret, frame = self.cap.read()
        if ret == True:
            self.frame = cv2.resize(frame, (640, 480))
            self.draw_only_frame = self.frame.copy()
            self._monitor()

        else:
            try:
                self.acquisition_timer.disconnect()
            except TypeError:
                pass

            QMessageBox.information(self, "Import from Video",
                                    "Video complete !")
            self.cap.release()

    def exportVideo(self):
        # if not self.enable_seeing.isChecked():
        #     answer = QMessageBox.question(self,
        #         "Export to Video File",
        #         "Seeing Monitoring is not activated. Continue ?",
        #         QMessageBox.Yes|QMessageBox.No,
        #         QMessageBox.No)

        #     if answer == QMessageBox.No:
        #         return

        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        filename, _ = QFileDialog.getSaveFileName(
            self,
            "Export to Video File",
            QDir.currentPath(),
            "All Files (*);;Video Files (*.avi *.mp4 *.mpeg *.flv *.3gp *.mov)",
            options=options)

        if filename:
            if splitext(filename)[1] != ".avi":
                filename = splitext(filename)[0] + ".avi"
                QMessageBox.information(
                    self, "Export to Video File",
                    "Only '.avi' extension is supported. Video will be saved as '{}'"
                    .format(filename))

            print(round(1000.0 / float(self.timer_interval)))

            self.video_writer = cv2.VideoWriter(
                filename,
                cv2.VideoWriter_fourcc(*'MJPG'),
                round(1000.0 / float(self.timer_interval)),
                (
                    640, 480
                )  #################################################################################
            )
            self.export_video = True

    def _writeVideoFile(self):
        current = QDateTime.currentDateTime()
        if self.export_video and current >= self.datetimeedit_start.dateTime() and \
            current < self.datetimeedit_end.dateTime():

            # self.video_writer.write(self.frame)
            self.video_writer.write(self.draw_only_frame)

    def _setPauseButton(self):
        self.button_pause.setEnabled(True)
        self.button_pause.setText("⏸ Pause")
        self.button_pause.clicked.connect(self._pause)

    def _pause(self):
        self.pause_pressed = True

        # IC_SuspendLive IC_StopLive ##################################################################################
        self.button_pause.setText("▶ Resume")
        self.button_pause.clicked.connect(self._resume)

        if self.video_source == VideoSource.CAMERA:
            self.Camera.StopLive()
        else:
            self.acquisition_timer.stop()

    def _resume(self):
        self.pause_pressed = False
        self._setPauseButton()

        if self.video_source == VideoSource.CAMERA:
            self.Camera.StartLive(0)
        else:
            try:
                self.acquisition_timer.disconnect()
            except TypeError:
                pass

            self.acquisition_timer.start(self.timer_interval)

            if self.video_source == VideoSource.CAMERA:
                pass
            elif self.video_source == VideoSource.SIMULATION:
                self.acquisition_timer.timeout.connect(self._updateSimulation)
            elif self.video_source == VideoSource.VIDEO:
                self.acquisition_timer.timeout.connect(self._grabVideoFrame)
Ejemplo n.º 4
0
class TotalEquityChartView(QChartView):
    """
    Chart that displays the balance between several dates
    from an account, token or whole portfolio
    """
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.chart = QChart()

    def setupChartWithData(self, data, linecolor='#422F8A'):
        """
        Chart gets updated displaying the new data.

        Data has to be expressed on a dictionary form:
            - keys are timestamps
            - values are total balance for that timestamp
        """
        self.chart = QChart()

        self.chart.setTheme(QChart.ChartThemeDark)
        self.chart.setAnimationOptions(QChart.SeriesAnimations)
        self.chart.setBackgroundBrush(QBrush(QColor("transparent")))
        #         self.chart.setTitle("")
        #         self.chart.setTitleBrush(QBrush(QColor('white')))

        # Axis X (Dates)
        self.x_axis = QDateTimeAxis()
        self.x_axis.setTickCount(11)
        self.x_axis.setLabelsAngle(70)
        font = QFont()
        font.setFamily('Roboto')
        font.setLetterSpacing(QFont.PercentageSpacing, 110)
        font.setPointSize(8)
        self.x_axis.setLabelsFont(font)
        self.x_axis.setFormat("dd-MM-yy")
        self.x_axis.setTitleText(self.tr('Date'))
        self.x_axis.setTitleVisible(False)
        self.x_axis.setLineVisible(False)
        self.x_axis.setGridLineVisible(False)

        # Axis Y (Balances)
        self.y_axis = QValueAxis()
        if data != {}:
            self.y_axis.setMax(max(data.values()) * 1.05)
            self.y_axis.setMin(min(data.values()) * 0.95)
        # self.y_axis.setMinorGridLineVisible(False)
        self.y_axis.setLineVisible(False)
        self.y_axis.setGridLineColor(QColor("#ECE9F1"))

        self.chart.addAxis(self.y_axis, Qt.AlignLeft)
        self.chart.addAxis(self.x_axis, Qt.AlignBottom)

        # Series
        self.btcseries = QSplineSeries()
        for date in data:
            balance = data[date]
            date = QDateTime(datetime.fromtimestamp(int(float(date))))
            self.btcseries.append(date.toMSecsSinceEpoch(), balance)

        self.btcseries.setName("BTC")
        pen = QPen(QColor(linecolor))
        pen.setWidth(3)
        self.btcseries.setPen(pen)

        # Series functionality
        self.btcseries.hovered.connect(self.selectPoint)

        self.chart.addSeries(self.btcseries)
        self.btcseries.attachAxis(self.x_axis)
        self.btcseries.attachAxis(self.y_axis)

        self.setChart(self.chart)
        self.setRenderHint(QPainter.Antialiasing)
        self.setStyleSheet("border: 0px; background-color: rgba(0,0,0,0); ")

        self.chart.legend().hide()

    def selectPoint(self, point, state):
        """ Shows point where mouse is hovered """
        self.chart.setTitle(
            f"{int(point.y())} {confighandler.get_fiat_currency().upper()}")