crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

zuze
  опции профиля:
сообщение 29.3.2013, 10:34
Сообщение #1


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Я пытаюсь закрасить область красным цветом за определённое время. Область будет закрашиватся каждый раз пока я не остановлю таймер.
Код:
# Глобальные
phi = 0.0
FlagStopRunPhi = 0
RunStopTimer = 1
timer = QtCore.QTimer()
im1 = QtGui.QImage(720, 492, QtGui.QImage.Format_ARGB32)

# В конструкторе

# Запустить таймер
self.connect(self.ui.pushButton_3, QtCore.SIGNAL("clicked()"), self.BlockTimer)

# Что происходит по таймеру
self.connect(timer, QtCore.SIGNAL("timeout()"), self.MyTimer)

def paintEvent(self, QPaintEvent):
      self.MyDraw()

# Запустить таймер
def BlockTimer(self):
            timer.start(0.05*1000)/60)

# Что происходит по таймеру
def MyTimer(self):
        global phi
        global im1

        if self.ui.checkBox_4.isChecked():
            for j in range(0, 720, 1):
                for i in range(491, -1, -1):
                    im1.setPixel(j, i, QtGui.QColor(255, 0, 0, 255).rgba())

        self.update()

        if self.ui.radioButton_2.isChecked():
            if int(self.MyRadianToGradus(phi)+0.5)*720/360 < 720:
                phi += self.MyGradusToRadian(6.0)
            else:
                phi = self.MyGradusToRadian(6.0)

# Рисуем
def MyDraw(self):
        global im1
        global phi

        Tochka = QtGui.QPainter()
        Tochka.begin(self)

        Tochka.translate(50, 50)

        Tochka.drawImage(0, 0, im1, 0, 0, int((2*self.MyRadianToGradus(phi))+0.5), 492)

        Tochka.end()


Должно быстро закрашиватся цветом, а закрашивается, только через каждые 0.5 секунды. Почему так происходит? В Qt всё быстро закрашивается.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
6 страниц V   1 2 3 > »   
Начать новую тему
Ответов (1 - 57)
Iron Bug
  опции профиля:
сообщение 29.3.2013, 11:02
Сообщение #2


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


питон - интерпретатор. его скорость от 10 до 500 раз ниже, чем у кода С++, в зависимости от того, что делаешь.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 29.3.2013, 11:17
Сообщение #3


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Iron Bug @ 29.3.2013, 11:02) *
питон - интерпретатор. его скорость от 10 до 500 раз ниже, чем у кода С++, в зависимости от того, что делаешь.


А можно ли в коде на Python вставить код, который однозначно показывал, что виноват сам Python, а не я?

Притом, такая простейшая операция, как закрашивание области цветом во времени. Мне не веритя, что такая простая операция затормаживает таймер в Python.

Сообщение отредактировал zuze - 29.3.2013, 11:22
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 29.3.2013, 16:57
Сообщение #4


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


если ты утверждаешь, что Qt не тормозит, то больше не на что списать тормоза, кроме как на интерфейс между Qt и питоном.

ну и реализация алгоритма весьма странная: у тебя каждый раз вызывается процедура закрашивания точки. это вызывает целую цепочку операций, в итоге идёт обращение к графической библиотеке и это происходит для каждой точки. естественно, что это тормозит. наверняка есть более быстрые методы работы с заполнением прямоугольника цветом, чтобы не делать столько длинных вызовов. кроме того, у тебя каждый раз в каждой итерации создаётся объект QColor, да ещё и с вызовом его метода, а на любое создание объекта нужно довольно много времени. питон - интерпретатор, он не умеет оптимизировать такие сложные вещи, это надо делать самому.
в общем, там много где можно опимизировать.

а для измерения времени можно попробовать навставлять таймеры и писать замеренное время в какой-то лог (только не на экран, а в память, а то ещё ужаснее будут тормоза из-за самих записей).
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 3.4.2013, 15:28
Сообщение #5


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Прямоугольная область с торможениями закрашивается красным цветом. Но вот один раз я абсолютно также сделал и прямоугольная область быстро начала зарисовыватся красным цветом.
Как будто это сбой самого Pathon-а. Решил привести полный код. Может кто увидит, где может быть ошибка и отпишется.
Мой код:
# -*- coding: utf-8 -*-

from PyQt4 import QtCore, QtGui, uic
import math
import os
import struct

phi = 0.0
timer = QtCore.QTimer()
im = QtGui.QImage(720, 492, QtGui.QImage.Format_ARGB32)


class ld(QtGui.QDialog):
    def __init__(self, parent=None):
        super(ld, self).__init__(parent)
        self.ui = uic.loadUi("ld.ui", self)

        self.connect(timer, QtCore.SIGNAL("timeout()"), self.MyTimer)
        timer.start((0.005 * 1000) / 60)

    def paintEvent(self, QPaintEvent):
        if self.ui.radioButton.isChecked():
            painterRect = QtGui.QPainter(self)
            painterRect.setBrush(QtGui.QColor('black'))
            painterRect.drawRect(50, 50, 720, 492)

            self.MyDraw()

        self.update()

    def MyRadianToGradus(self, phiedit):
        gradus = phiedit * 360 / (2 * math.pi)
        return gradus

    def MyGradusToRadian(self, phiedit):
        radian = phiedit * 2 * math.pi / (360)
        return radian

    def MyTimer(self):
        global phi
        global im

        if self.ui.checkBox.isChecked():
            for j in range(0, 720, 1):
                for i in range(491, -1, -1):
                    im.setPixel(j, i, QtGui.QColor(255, 0, 0, 255).rgba())

        self.update()

        if int(self.MyRadianToGradus(phi) + 0.5) * 720 / 360 < 720:
            phi += self.MyGradusToRadian(6.0)
        else:
            phi = self.MyGradusToRadian(6.0)

    def MyDraw(self):
        global im
        global phi

        Tochka = QtGui.QPainter()
        Tochka.begin(self)

        Tochka.translate(50, 50)

        Tochka.drawImage(0, 0, im, 0, 0, int((2 * self.MyRadianToGradus(phi)) + 0.5), 492)

        Tochka.end()

if __name__ == '__main__':
    import sys

    app = QtGui.QApplication(sys.argv)

    window = ld()
    window.show()

    sys.exit(app.exec_())


Сообщение отредактировал zuze - 3.4.2013, 15:51
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 4.4.2013, 9:20
Сообщение #6


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


timer.start((0.005 * 1000) / 60)

(0.005 * 1000) / 60 ~ 0
Поэтому таймер будет выстреливать так быстро как может, то есть постоянно.

А в обработчике таймера его ждет такой цикл:
if self.ui.checkBox.isChecked():
    for j in range(0, 720, 1):
        for i in range(491, -1, -1):
            im.setPixel(j, i, QtGui.QColor(255, 0, 0, 255).rgba())

Т.е. картинка перегенерируется постоянно, это небыстро, отсюда и тормоза.

Сообщение отредактировал lanz - 4.4.2013, 9:21
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 4.4.2013, 9:24
Сообщение #7


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(lanz @ 4.4.2013, 9:20) *
Т.е. картинка перегенерируется постоянно, это небыстро, отсюда и тормоза.


А как это поправить?

У меня даже таймер

timer.start((0.05 * 1000) / 60)


тормозит, а такой таймер необходим и в Qt работал. А почему он в Python иногда проскакивает с быстрой скоростью?

Сообщение отредактировал zuze - 4.4.2013, 9:29
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 4.4.2013, 9:50
Сообщение #8


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


Цитата
А как это поправить?


Нужно картинку сгенерировать один раз, например при запуске программы.

Цитата
такой таймер необходим и в Qt работал

Может он и в Qt тормозил, 0.8 мс это очень быстро, так быстро даже курсор мыши не обновляется, 15-30 мс более разумные рамки.

Цитата
А почему он в Python иногда проскакивает с быстрой скоростью?

Может быть тысяча причин и ни на одну нельзя полагаться. Например удачно выпадает переключение процессов или байт код питоновский закешировался.
Написание приложений реального времени в Windows сродни квантовой механике :lol:
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 4.4.2013, 10:17
Сообщение #9


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(lanz @ 4.4.2013, 9:50) *
Может он и в Qt тормозил, 0.8 мс это очень быстро, так быстро даже курсор мыши не обновляется, 15-30 мс более разумные рамки.


Я сделал так

timer.start(5000)


А в место 5 секунд обновляется, через каждые 3 секунды.

Я делал так

timer.start(15)


Картинка через каждые 0,5 секунды обновляется.

Что же с этим таймером?

Сообщение отредактировал zuze - 4.4.2013, 10:27
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 4.4.2013, 10:37
Сообщение #10


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


Если картинка не успевает обновится за 15 мс (а она наверняка не успевает) то поток блокируется до тех пор, пока она не обновится. Все это время сообщения от таймера скапливаются и будут обработаны только когда поток освободится. Поэтому и задержка, т.е. реальное время где то 0,5 секунды и быстрее не получится.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 4.4.2013, 10:45
Сообщение #11


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(lanz @ 4.4.2013, 10:37) *
Поэтому и задержка, т.е. реальное время где то 0,5 секунды и быстрее не получится.


1. Можно ли это как-то документально прочитать, про скорости таймера в Python?
2. А почему тогда в место 5 секунд обновляется, через каждые 3 секунды?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 4.4.2013, 10:57
Сообщение #12


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


1. Таймер в Qt. Python только вызывает функции.
2. А как были посчитаны эти 3 секунды?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 4.4.2013, 11:11
Сообщение #13


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(lanz @ 4.4.2013, 10:57) *
2. А как были посчитаны эти 3 секунды?


Я делал так

timer.start(5000)


А считал в уме. Решил проверинть на секундомере на смартфоне. В итоге первые несколько раз по 3 секунды, а потом идёт интервал по 5 секунд, даже немного поменше (4,7 или 4,8 секунды).
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 5.4.2013, 13:46
Сообщение #14


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Как я понял, мой коде есть ряд ошибок:
1. Код не удовлетворяет модели "модель-представление-контроллер (Model-View-Controller, MVC)". Не совсем понимаю, как это сделать.
2. Я вызываю перерисовку всего окна по таймеру и жду следующей перерисовку от таймера. Наверно надо пересовывать, только следующий кусочек.
3. Возможно я не в той функции запускаю таймер.
4. В методе MyTimer ты в не зависимости от того активен self.checkBox или нет, проверяю phi на условие и в зависимости от результата меняю его.
Это я поправил, вот так:
def MyTimer(self):
        global phi
        global im1

        if self.ui.checkBox_4.isChecked():
            for j in range(0, 720, 1):
                for i in range(491, -1, -1):
                    im1.setPixel(j, i, QtGui.QColor(255, 0, 0, 255).rgba())

            self.update()

            if int(self.MyRadianToGradus(phi)+0.5)*720/360 < 720:
                phi += self.MyGradusToRadian(6.0)
            else:
                phi = self.MyGradusToRadian(6.0)


Помогите пожалуйста разобратся с ошибочками 1-3.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 8.4.2013, 8:45
Сообщение #15


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


Цитата
Код не удовлетворяет модели "модель-представление-контроллер (Model-View-Controller, MVC)". Не совсем понимаю, как это сделать.

Это не ошибка сама по себе. Не любой код должен удовлетворять такой модели.
http://ru.wikipedia.org/wiki/Model-View-Controller

Цитата
Я вызываю перерисовку всего окна по таймеру и жду следующей перерисовку от таймера. Наверно надо пересовывать, только следующий кусочек.

Основные тормоза не от этого, а скорее всего, что картинка готовится каждый раз, когда надо ее вывести:
if self.ui.checkBox_4.isChecked():
            for j in range(0, 720, 1):
                for i in range(491, -1, -1):
                    im1.setPixel(j, i, QtGui.QColor(255, 0, 0, 255).rgba())

Этот код не зависит от phi, зачем он вызывается каждый раз при перерисовке?

Цитата
Возможно я не в той функции запускаю таймер.

Не вижу проблемы.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 8.4.2013, 8:54
Сообщение #16


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(lanz @ 8.4.2013, 8:45) *
Основные тормоза не от этого, а скорее всего, что картинка готовится каждый раз, когда надо ее вывести:

if self.ui.checkBox_4.isChecked():
            for j in range(0, 720, 1):
                for i in range(491, -1, -1):
                    im1.setPixel(j, i, QtGui.QColor(255, 0, 0, 255).rgba())


Если дело в этом коде, то он необходим, так как тут подготавливаеться картинка, через каждый промежуток времени. А заранее подготовить нельзя, так как в будущем будет не один цвет, а много разных картинок, которые будут менятся по таймеру.

Не ужели для такой простой задачи в Python без потоков не обойтись?

На всякий случай прикрепляю два фала ld.py и ld.ui лежащих в архиве ld.zip. Возможно они помогут решить проблему с торможением.

Сообщение отредактировал zuze - 8.4.2013, 9:58
Прикрепленные файлы
Прикрепленный файл  ld.zip ( 1.35 килобайт ) Кол-во скачиваний: 200
 
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 8.4.2013, 10:21
Сообщение #17


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Решил проверить время выполнения кода.

if self.ui.radioButton.isChecked():
            self.start = time.time()
            for j in range(0, 720, 1):
                for i in range(491, -1, -1):
                    im.setPixel(j, i, QtGui.QColor(255, 0, 0, 255).rgba())

            self.end = time.time()
            self.secs = self.end - self.start
            print self.secs  # миллисекунды


Какие-то странные результаты, хотя я поставил таймер 5000 миллисекунд.
А сами результаты такие:
0.836999893188
0.838999986649
0.837999820709
0.832000017166
0.836999893188

Сообщение отредактировал zuze - 8.4.2013, 10:21
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 8.4.2013, 10:35
Сообщение #18


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


Все правильно, подготовка картинки занимает почти секунду.

Цитата
Если дело в этом коде, то он необходим, так как тут подготавливаеться картинка, через каждый промежуток времени.

Картинку необязательно готовить каждый кадр, можно ее готовить только когда возникнет необходимость в новой.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 8.4.2013, 10:43
Сообщение #19


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(lanz @ 8.4.2013, 10:35) *
Картинку необязательно готовить каждый кадр, можно ее готовить только когда возникнет необходимость в новой.


У меня необходимость постоянная в выводе картинок. Сначала берутся значения из двоичного файла и рисуеться картинка, через определённый промежуток времени. Затем рисуется картинка из второго файла, а первая картинка, как бы затираеться. Затем рисуеться картинка из третьего файла, а вторая картинка, как бы затираеться.

Схема вывода картинок:

_______________________________
|-----------------------|------------------------|
|Первая картинка | Фон -----------------|
|-----------------------|------------------------|
_______________________________|

________________________________
|-----------------------|------------------------|
|Вторая картинка | Первая картинка |
|-----------------------|------------------------|
_______________________________|

_______________________________
|----------------------|-------------------------|
|Третья картинка | Вторая картинка |
|----------------------|------------------------|
______________________________|

и так далее.

Сообщение отредактировал zuze - 8.4.2013, 10:50
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 8.4.2013, 10:51
Сообщение #20


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


Это все понятно, но картинка обновляется только когда начинает рисоваться новая, а не каждый шаг (по phi) отрисовки картинки.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 8.4.2013, 11:05
Сообщение #21


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(lanz @ 8.4.2013, 10:51) *
Это все понятно, но картинка обновляется только когда начинает рисоваться новая, а не каждый шаг (по phi) отрисовки картинки.


Вы говорите о том, что я из таймера должен убрать

self.update()


но это не помогло.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 8.4.2013, 11:41
Сообщение #22


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


Нет, я о том чтобы убрать вот это
 if self.ui.checkBox_4.isChecked():
            for j in range(0, 720, 1):
                for i in range(491, -1, -1):
                    im1.setPixel(j, i, QtGui.QColor(255, 0, 0, 255).rgba())
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 8.4.2013, 12:19
Сообщение #23


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(lanz @ 8.4.2013, 11:41) *
Нет, я о том чтобы убрать вот это

if self.ui.checkBox_4.isChecked():
            for j in range(0, 720, 1):
                for i in range(491, -1, -1):
                    im1.setPixel(j, i, QtGui.QColor(255, 0, 0, 255).rgba())


А куда, можно убрать?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 8.4.2013, 12:22
Сообщение #24


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


Туда, где загружается картинка.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 8.4.2013, 13:14
Сообщение #25


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(lanz @ 8.4.2013, 12:22) *
Туда, где загружается картинка.


Так у меня картинка загружается тутже. Я загрузку картинки заменил на загрузку цвета. В таком случае, что делать?

Может такая задача в Python решаеться только с помощью потока и чтобы не использовался GIL (Global Interpreter Lock)?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 8.4.2013, 14:00
Сообщение #26


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(zuze @ 8.4.2013, 10:21) *
Все правильно, подготовка картинки занимает почти секунду.


Почему всё правильно. У меня же таймер обновляется 5 секунд значит значения должно показаться 5 или близкое.
А выводится:
0.836999893188
0.838999986649
0.837999820709
0.832000017166
0.836999893188
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 8.4.2013, 16:03
Сообщение #27


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


Потому что время замеряется ВНУТРИ одного вызова и показывает сколько времени проходит ВНУТРИ отрисовки, а не МЕЖДУ вызовами таймера.

Все зависит от того, как генерируются картинки. Они берутся не из файла, так откуда же?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 8.4.2013, 16:11
Сообщение #28


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(lanz @ 8.4.2013, 16:03) *
Все зависит от того, как генерируются картинки. Они берутся не из файла, так откуда же?


Значения беруться из двоичного файла и заносяться в список.
То есть в будущем будет такой код:

for j in range(0, 720, 1):
     for i in range(491, -1, -1):
            bf = struct.unpack("B", fp.read(1))
            im.setPixel(j, i, QtGui.QColor(bf[0], bf[0], bf[0], 255).rgba())


Это аналог кода в Qt который выгляжит так:

for (int j = 0; j < 720; j++)
{
     for (int i = 491; i >= 0; i--)
     {
          buffer[i][j] = getc(fp);
          im.setPixel(j, i, QColor(buffer[i][j], buffer[i][j], buffer[i][j], 255).rgba());
      }
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 8.4.2013, 16:52
Сообщение #29


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


Это я помню :lol:
В Qt этот код был не в paintEvent.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 8.4.2013, 21:12
Сообщение #30


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(lanz @ 8.4.2013, 16:52) *
В Qt этот код был не в paintEvent.


Он был в MyTimer, а тут

for j in range(0, 720, 1):
     for i in range(491, -1, -1):
            bf = struct.unpack("B", fp.read(1))
            im.setPixel(j, i, QtGui.QColor(bf[0], bf[0], bf[0], 255).rgba())


лежит в MyTimer. Всё аналогично.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 9.4.2013, 8:25
Сообщение #31


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


И в том треде я писал, что надо вынести этот код из таймера.

И вообще, насколько я помню файлы запрещено использовать, значит данные будут приходить не из файлов, а каким то другим путем. Из сокетов или из порта/карты захвата. Значит надо формировать картинки по событию поступления их в программу. И добавлять в очередь например, но каждый кадр перерисовывать их нельзя.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 9.4.2013, 9:40
Сообщение #32


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(lanz @ 9.4.2013, 8:25) *
И вообще, насколько я помню файлы запрещено использовать, значит данные будут приходить не из файлов


Так как это эмуляция, то в настоящий момент использую файлы.

Как я понял всё работает прекрасно, если избавится от циклов.

Вот код:

# -*- coding: utf-8 -*-
from PyQt4 import QtCore, QtGui, uic
import math
phi = 0.0
class ld(QtGui.QDialog):
    def __init__(self, parent=None):
        super(ld, self).__init__(parent)
        self.ui = uic.loadUi("ld.ui", self)
        self.timer = QtCore.QTimer()
        self.connect(self.timer, QtCore.SIGNAL("timeout()"), self.MyTimer)
        self.timer.setInterval(3)
        self.timer.start()
    def paintEvent(self, QPaintEvent):
        if self.ui.radioButton.isChecked():
            painterRect = QtGui.QPainter(self)
            painterRect.setBrush(QtGui.QColor('black'))
            painterRect.drawRect(50, 50, 720, 492)
            self.MyDraw()
        self.update()
    def MyRadianToGradus(self, phiedit):
        gradus = phiedit * 360 / (2 * math.pi)
        return gradus
    def MyGradusToRadian(self, phiedit):
        radian = phiedit * 2 * math.pi / (360)
        return radian
    def MyTimer(self):
        global phi
        self.update()
        if int(self.MyRadianToGradus(phi) + 0.5) * 720 / 360 < 720:
            phi += self.MyGradusToRadian(6.0)
        else:
            phi = self.MyGradusToRadian(6.0)
    def MyDraw(self):
        global phi
        p = QtGui.QPainter(self)
        p.translate(50, 50)
        p.fillRect(0, 0, int(self.MyRadianToGradus(phi)+0.5)*720/360, 492, QtGui.QColor('red'))
if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    window = ld()
    window.show()
    sys.exit(app.exec_())


То есть мне надо избавится от циклов в двух моментах:
1. Вывод изображений на экран.
2. Заполнения объекта QImage значениями из файла.

Если я в пункте номер 1 избавляюсь от циклов с помощью drawImage, то от циклов во втором пункте я не смог изавится.

Может кто знает, как избавится от циклов в обоих пунктах?

Сообщение отредактировал zuze - 9.4.2013, 9:59
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 9.4.2013, 13:35
Сообщение #33


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


Во втором пункте никак не избавиться.

С какой скоростью появляются новые картинки?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 9.4.2013, 13:38
Сообщение #34


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(lanz @ 9.4.2013, 13:35) *
С какой скоростью появляются новые картинки?


Самая маленькая скорость появление следующей картинки будет, через 10 секунд, а самая большая скорось появление следующей картинки будет, через 0,05 секунды.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 10.4.2013, 14:20
Сообщение #35


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


А сколько времени должна рисоваться одна картинка?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 10.4.2013, 15:55
Сообщение #36


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(lanz @ 10.4.2013, 14:20) *
А сколько времени должна рисоваться одна картинка?


Самая маленькая скорость появление следующей картинки будет, через 10 секунд, а самая большая скорось появление следующей картинки будет, через 0,05 секунды.
При скорости рисовании картинки 0,05 * 1000 мс, рисования одного кусочка картинки (0,05 * 1000) / 60 мс
При скорости рисовании картинки 10 * 1000 мс, рисования одного кусочка картинки (10 * 1000) / 60 мс

То есть за время "0,05 * 1000 мс" или "10 * 1000 мс" рисунок нарисуется полностью за 60 раз срабатывания таймера.

Сообщение отредактировал zuze - 10.4.2013, 15:55
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 10.4.2013, 16:21
Сообщение #37


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


Очень странные цифры, за 50 мс - это два - три кадра, зачем перерисовывать картинку 60 раз?

И если надо так быстро получать картинки, используйте numpy например, а потом загружайте картинку напрямую через QImage::scanline ()
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 11.4.2013, 15:16
Сообщение #38


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(lanz @ 10.4.2013, 16:21) *
зачем перерисовывать картинку 60 раз?


Я не всю картинку перерисовываю 60 раз, а я дорисовываю, кусочек картинки каждый раз и полностью картинка появляется когда пройдёт таймер 60 раз.

Цитата(lanz @ 10.4.2013, 16:21) *
И если надо так быстро получать картинки, используйте numpy например, а потом загружайте картинку напрямую через QImage::scanline()


a = numpy.fromfile(fp, dtype=numpy.uint8)
a = numpy.flipud(a.reshape((height, width), order='F'))


Но вот как правильно загрузить я не понял. Помогите пожалуйста это понять.

Я пробовал так сделать:

a = numpy.fromfile(fp, dtype=numpy.uint8)
a = numpy.flipud(a.reshape((492, 720), order='F'))
a.tostring()
im = QtGui.QImage.__init__(self, self, 492, 720, self.Format_Indexed8)


Для вывода так делаю:

def MyDraw(self):
        global im

        Tochka = QtGui.QPainter()
        Tochka.begin(self)

        Tochka.translate(50, 50)
        Tochka.drawImage(0, 0, im, 0, 0, int((2*self.MyRadianToGradus(phi))+0.5), 492)

        Tochka.end()

        self.update()


Выдаётся вот такая ошибка:

im = QtGui.QImage.__init__(self, self, 492, 720, self.Format_Indexed8)
TypeError: 'sip.methoddescriptor' object is not callable

Я пробовал в место

a.tostring()
im = QtGui.QImage.__init__(self, self, 492, 720, self.Format_Indexed8)


Написать

self.__data = a.tostring()
im = QtGui.QImage.__init__(self, self.__data, 492, 720, self.Format_Indexed8)


Пробоывал ещё так:

self.__data = a.tostring()
im = QtGui.QImage.__init__(self.__data, 492, 720, self.Format_Indexed8)


Таже самая ошибка. Не знаю важно или нет, но у меня Python 2.6

Как я понял я не правильно конструктор определил, а вот как правильно не понимаю. Помогите пожалуйста понять.

Сообщение отредактировал zuze - 15.4.2013, 9:12
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 15.4.2013, 13:06
Сообщение #39


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Сделал так:

data = a.tostring()
im = QtGui.QImage(data, 492, 720, QtGui.QImage.Format_ARGB32)


Это ошибка пропадает.
Но в момент первого срабатывания таймера возникает ошибка:
Появляется окно с выбором из трёх кнопок:
1 кнопка (Искать решение проблемы в Интернете и закрыть программу)
2 кнопка (Закрыть программу)
3 кнопка (отладить программу)

А текстом пишется:
Process finished with exit code -1073741819

В чём может быть дело?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 15.4.2013, 13:55
Сообщение #40


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


Ошибка при работе с памятью скорее всего, видимо с размером что то напутано.

Выложите проект, попробую потыркать.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 15.4.2013, 14:25
Сообщение #41


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(lanz @ 15.4.2013, 13:55) *
Выложите проект, попробую потыркать.


# -*- coding: utf-8 -*-

from PyQt4 import QtCore, QtGui, uic
import numpy
import math  # Для pi, sin, cos
import os    # Для работы с файлами
import struct
import time

dir = os.path.join(os.getcwd(), "file") # Выбор текущей директории с файлами
phi = 0.0

im = QtGui.QImage(720, 492, QtGui.QImage.Format_ARGB32)

class ld(QtGui.QDialog):
    def __init__(self, parent=None):
        super(ld, self).__init__(parent)
        self.ui = uic.loadUi("ld.ui", self)

        self.connect(self.ui.radioButton_2, QtCore.SIGNAL("clicked()"), self.MyClickRect)

        self.timer = QtCore.QTimer()
        self.connect(self.timer, QtCore.SIGNAL("timeout()"), self.MyTimer)
        self.timer.setInterval(5000)
        self.timer.start()

    def paintEvent(self, QPaintEvent):
        if self.ui.radioButton_2.isChecked():
            painterRect = QtGui.QPainter(self)
            painterRect.setBrush(QtGui.QColor('black'))
            painterRect.drawRect(50, 50, 720, 492)
            self.MyDraw()

    def MyClickRect(self):
        self.update()

    def MyRadianToGradus(self, phiedit):
        gradus = phiedit * 360/(2*math.pi)
        return gradus

    def MyGradusToRadian(self, phiedit):
        radian = phiedit * 2*math.pi / (360)
        return radian

    def MyTimer(self):
        global dir
        global phi
        global im
        global fp

        if self.ui.checkBox_4.isChecked():
            os.chdir(dir)
            try:
                fp = open("1.dat", "rb")
            except IOError:
                print "Cannot open file read!"

            fp.seek(0, 2)
            size = fp.tell()
            fp.seek(size - (492*720), 0)

            a = numpy.fromfile(fp, dtype=numpy.uint8)
            a = numpy.flipud(a.reshape((492, 720), order='F'))
            data = a.tostring()
            im = QtGui.QImage(data, 492, 720, QtGui.QImage.Format_ARGB32)

            self.update()

        if self.ui.radioButton_2.isChecked():
            if int((self.MyRadianToGradus(phi)+0.5)*720)/360 < 720:
                phi += self.MyGradusToRadian(6.0) # Поворот и смещение линии в полярных и пямоугольных координатах
            else:
                phi = self.MyGradusToRadian(6.0)

    def MyDraw(self):
        global im

        Tochka = QtGui.QPainter()
        Tochka.begin(self)

        Tochka.translate(50, 50)
        Tochka.drawImage(0, 0, im, 0, 0, int((2*self.MyRadianToGradus(phi))+0.5), 492)

        Tochka.end()

        self.update()

if __name__ == '__main__':
    import sys

    app = QtGui.QApplication(sys.argv)

    window = ld()
    window.show()

    sys.exit(app.exec_())


К сожалению я немогу дать Вам файл. Можно использовать любую строку длинной 492 * 720, только тогда не нужен код:
fp.seek(0, 2)
size = fp.tell()
fp.seek(size - (492*720), 0)


Прикреплённый архив содержит ld.ui

Может дело в a.tostring(), которая вроде не всегда стабильно работает. Может какой другому можно подготовить данные из файла, что бы из загрузить затем в объект QImage?

Сообщение отредактировал zuze - 15.4.2013, 14:15
Прикрепленные файлы
Прикрепленный файл  ld.zip ( 604 байт ) Кол-во скачиваний: 135
 
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 15.4.2013, 16:43
Сообщение #42


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


1. Не нужно вызывать update в методе paintEvent это плодит ненужные циклы отрисовки.
2. Если используете Indexed8, то нужно определить таблицу цветов,
Цитата
If format is an indexed color format, the image color table is initially empty and must be sufficiently expanded with setColorCount() or setColorTable() before the image is used.

3. Если используете ARGB32, то байт должно быть в 4 раза больше (красная, зеленая, синияя и альфа - компоненты) т.е. размер файла должен быть 492*720*4.
4. data должен быть валиден в течении всего времени жизни картинки. (т.е. не должен быть локальной переменной)
Цитата
The buffer must remain valid throughout the life of the QImage. The image does not delete the buffer at destruction.

Это происходит потому что вызывается конструктор с неконстантным первым uchar*.
5. Эти преобразования бесполезны.
a = numpy.fromfile(fp, dtype=numpy.uint8)
a = numpy.flipud(a.reshape((492, 720), order='F'))
data = a.tostring()

То же самое будет если сделать
data = fp.read()

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 16.4.2013, 8:44
Сообщение #43


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Я сделал так:
# -*- coding: utf-8 -*-

from PyQt4 import QtCore, QtGui, uic
import math
import os
import struct

dir = os.path.join(os.getcwd(), "file")
phi = 0.0

im = QtGui.QImage(720, 492, QtGui.QImage.Format_ARGB32)

class ld(QtGui.QDialog):
    def __init__(self, parent=None):
        super(ld, self).__init__(parent)
        self.ui = uic.loadUi("ld.ui", self)

        self.connect(self.ui.radioButton_2, QtCore.SIGNAL("clicked()"), self.MyClickRect)

        self.timer = QtCore.QTimer()
        self.connect(self.timer, QtCore.SIGNAL("timeout()"), self.MyTimer)
        self.timer.setInterval(5000)
        self.timer.start()

    def paintEvent(self, QPaintEvent):
        if self.ui.radioButton_2.isChecked():
            painterRect = QtGui.QPainter(self)
            painterRect.setBrush(QtGui.QColor('black'))
            painterRect.drawRect(50, 50, 720, 492)
            self.MyDraw()

    def MyClickRect(self):
        self.update()

    def MyTimer(self):
        global im
        global dir
        global phi
        global fp

        if self.ui.checkBox_4.isChecked():
            os.chdir(dir)
            try:
                fp = open("07_30_29.28C", "rb")
            except IOError:
                print "Cannot open file read!"

            fp.seek(0, 2)
            size = fp.tell()
            fp.seek(size - (492*720), 0)

            data = fp.read()

            im = QtGui.QImage(data, 720, 492, QtGui.QImage.Format_ARGB32)

            self.update()

        if self.ui.radioButton_2.isChecked():
            if int((math.degrees(phi)+0.5)*720)/360 < 720:
                phi += math.radians(6.0)
            else:
                phi = math.radians(6.0)

    def MyDraw(self):
        global im

        Tochka = QtGui.QPainter()
        Tochka.begin(self)

        Tochka.translate(50, 50)
        Tochka.drawImage(0, 0, im, 0, 0, int((2*math.degrees(phi))+0.5), 492)

        Tochka.end()

if __name__ == '__main__':
    import sys

    app = QtGui.QApplication(sys.argv)

    window = locatordialog()
    window.show()

    sys.exit(app.exec_())


В этом коде случилось следующие:
1. update в методе paintEvent.
2. В место собственных функций преобразование из радиан в градусы и обратно использовал стандартные.
3. Преобразование строки заменил на такое data = fp.read()

Я незнаю как сделать im локально, так как я im использую в MyTimer(), но также я im использую в MyDraw(). Подскажите пожалуйста, как это сделать?

Цитата(lanz @ 15.4.2013, 16:43) *
Эти преобразования бесполезны.

a = numpy.fromfile(fp, dtype=numpy.uint8)
a = numpy.flipud(a.reshape((492, 720), order='F'))
data = a.tostring()


Не знаю на сколько они безполезны, но если в циклах заполняем im сзначениями из a, то всё прекрасно, картинка рисуется, но медленно. Вот я немного удивлён, что эти преобразования бесполезны.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 16.4.2013, 9:46
Сообщение #44


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


Цитата
Я незнаю как сделать im локально, так как я im использую в MyTimer(), но также я im использую в MyDraw(). Подскажите пожалуйста, как это сделать?

Не надо делать im локальным, надо сделать data глобальным/членом класса. data должна существовать после того как управление выйде из MyTimer поскольку коструктор QImage сохраняет только указатель на дату.

Цитата
Вот я немного удивлён, что эти преобразования бесполезны.

Это я проглядел что массив флипается.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 16.4.2013, 10:07
Сообщение #45


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(lanz @ 16.4.2013, 9:46) *
Не надо делать im локальным, надо сделать data глобальным/членом класса. data должна существовать после того как управление выйде из MyTimer поскольку коструктор QImage сохраняет только указатель на дату.


Сделал в конструкторе класса, так:

self.data = []


Сделал в MyTimer

a = numpy.fromfile(fp, dtype=numpy.uint8)
a = numpy.flipud(a.reshape((720, 492), order='F'))
self.data = a.tostring()

im = QtGui.QImage(self.data, 720, 492, QtGui.QImage.Format_ARGB32)


И всё равно, таже ошибка?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 16.4.2013, 10:23
Сообщение #46


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


Конечно. Загружаете 720*492 байт, а картинке говорите что их 720*492*4 (Format_ARGB32)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 16.4.2013, 10:36
Сообщение #47


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(lanz @ 16.4.2013, 10:23) *
Конечно. Загружаете 720*492 байт, а картинке говорите что их 720*492*4 (Format_ARGB32)


А как картинке задать, что бы брала только 720*492? Я думал достаточно указать QtGui.QImage.Format_ARGB, но такого формата нету.

Сообщение отредактировал zuze - 16.4.2013, 11:13
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 16.4.2013, 11:29
Сообщение #48


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


Можно использовать Format_Indexed8, только нужно обязательно задать таблицу цветов.
http://qt-project.org/doc/qt-4.8/qimage.html#setColorTable
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 16.4.2013, 12:21
Сообщение #49


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(lanz @ 16.4.2013, 11:29) *
Можно использовать Format_Indexed8, только нужно обязательно задать таблицу цветов.


Сделал так:

a = numpy.fromfile(fp, dtype=numpy.uint8)
a = numpy.flipud(a.reshape((720, 492), order='F'))
self.data = a.tostring()

im = QtGui.QImage(self.data, 720, 492, QtGui.QImage.Format_Indexed8)
QtGui.QImage.setColorTable(QtGui.qRgba(255, 0, 0, 255))


Всё равно, тажа ошибка.

Сообщение отредактировал zuze - 16.4.2013, 12:21
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 16.4.2013, 12:48
Сообщение #50


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


setColorTable нужно вызывать у конкретного экземпляра QImage, кроме того туда нужно передать вектор цветов, а не один цвет.

Сообщение отредактировал lanz - 16.4.2013, 12:49
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 16.4.2013, 13:00
Сообщение #51


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(lanz @ 16.4.2013, 12:48) *
setColorTable нужно вызывать у конкретного экземпляра QImage, кроме того туда нужно передать вектор цветов, а не один цвет.


Сделал, так:

im.setColorTable(QtGui.QVector4D(QtGui.qRgba(255, 0, 0, 255)))


Всё равно, таже ошибка.

Надеюсь Вы не забыли, что каждый байт двоичного файла это цвет модели RGB. Возможно из-за этого не надо было использовать Format_Indexed8, а что-то другое.

Сообщение отредактировал zuze - 16.4.2013, 13:00
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 16.4.2013, 13:59
Сообщение #52


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


            im = QtGui.QImage(data, 492, 720, QtGui.QImage.Format_Indexed8)
            colortable = []
            for i in xrange(255):
                colortable.append (QtGui.qRgb(i, i, i))
            im.setColorTable (colortable);            
            self.update()


Вектор - это массив цветов.

Цитата
Надеюсь Вы не забыли, что каждый байт двоичного файла это цвет модели RGB

И как эти цвета в нем упакованы?

Сообщение отредактировал lanz - 16.4.2013, 14:00
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 16.4.2013, 14:07
Сообщение #53


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(lanz @ 16.4.2013, 13:59) *
И как эти цвета в нем упакованы?


Сначала идёт служебная информация, которую мы пропускаем смещением начала чтения данных из файла.
Первый байт после управляющих символов - это R = 1-й байт, G = 1-й байт, B = 1-й байт. Второй байт следующая точка в цветности RGB по токомуже принципу.
В результате получаеться прямоугольная область с рисунком.

Сделал примерно как у Вас, только в место data, у меня self.data

im = QtGui.QImage(self.data, 720, 492, QtGui.QImage.Format_Indexed8)

colortable = []
for i in xrange(255):
       colortable.append (QtGui.qRgb(i, i, i))
       im.setColorTable(colortable)


Всё равно, таже ошибка.

Сообщение отредактировал zuze - 16.4.2013, 14:16
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 16.4.2013, 14:36
Сообщение #54


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


Цитата
Первый байт после управляющих символов - это R = 1-й байт, G = 1-й байт, B = 1-й байт. Второй байт следующая точка в цветности RGB по токомуже принципу.

Арифметика - царица наук :lol:


Каждая точка занимает три байта.
Размер картинки - 720*492 точки.

Вопрос - сколько байт занимает картинка?

И сравните ответ с тем что вы написали вот тут:
Раскрывающийся текст
fp.seek(0, 2)
size = fp.tell()
fp.seek(size - (492*720), 0)


Кстати такой формат есть - RGB888

Сообщение отредактировал lanz - 16.4.2013, 14:39
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 16.4.2013, 14:41
Сообщение #55


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(lanz @ 16.4.2013, 14:36) *
Вопрос - сколько байт занимает картинка?


Размер файла у меня 492*720 + 8 байт. Я сместил на 8 байт, так как они управляющие.
R = 1-й байт, G = 1-й байт, B = 1-й байт - этим я хотел показать, что на кажом иттерации цика, если он был значения R, G и B равны.
Общая картинка бы нартсовалась когда бы прошли циклы такие:

for j in range(0, 720, 1):
       for i in range(491, -1, -1):


Сделал так:

# Глобально
im = QtGui.QImage(720, 492, QtGui.QImage.Format_RGB888)

# В конструкторе
self.data = []

# В MyTimer()
a = numpy.fromfile(fp, dtype=numpy.uint8)
a = numpy.flipud(a.reshape((720, 492), order='F'))
self.data = a.tostring()

im = QtGui.QImage(self.data, 720, 492, QtGui.QImage.Format_RGB888)


Таже ошибка.

Сообщение отредактировал zuze - 16.4.2013, 14:46
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 16.4.2013, 15:42
Сообщение #56


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


У меня все отрисовывается без ошибок.
Возможно проблема в загрузке файла. Можете файл забить каким то одним значением и выложить вместе с проектом?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 7.5.2013, 10:53
Сообщение #57


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


lanz, прошу прощения, что не отвечал, был в отпуске.

Всё равно тут цикл хоть и один.

Пешил воспользоваться библиотекой matplotlib, так как вроде она сразу выводить массив на экран. Пока хочу целиком картинку вывести.

Вот код:

# -*- coding: utf-8 -*-

from PyQt4 import QtCore, QtGui, uic
import numpy
import math
import os
import struct
import matplotlib.pyplot as plt

dir = os.path.join(os.getcwd(), "file")
phi = 0.0

a = []

class ld(QtGui.QDialog):
    def __init__(self, parent=None):
        super(ld, self).__init__(parent)
        self.ui = uic.loadUi("ld.ui", self)

        self.connect(self.ui.radioButton_2, QtCore.SIGNAL("clicked()"), self.MyClickRect)

        self.timer = QtCore.QTimer()
        self.connect(self.timer, QtCore.SIGNAL("timeout()"), self.MyTimer)
        self.timer.setInterval(5000)
        self.timer.start()

    def paintEvent(self, QPaintEvent):
        if self.ui.radioButton_2.isChecked():
            painterRect = QtGui.QPainter(self)
            painterRect.setBrush(QtGui.QColor('black'))
            painterRect.drawRect(50, 50, 720, 492)
            self.MyDraw()

    def MyClickRect(self):
        self.update()

    def MyTimer(self):
        global dir
        global phi
        global fp
        global a

        if self.ui.checkBox_4.isChecked():
            os.chdir(dir)
            try:
                fp = open("1.dat", "rb")

            except IOError:
                print "Cannot open file read!"

            fp.seek(0, 2)
            size = fp.tell()
            fp.seek(size - (492*720), 0)

            a = numpy.fromfile(fp, dtype=numpy.uint8)
            a = numpy.flipud(a.reshape((492, 720), order='F'))
            a.tostring()

        self.update()

        if self.ui.radioButton_2.isChecked():
            if int((math.degrees(phi)+0.5)*720)/360 < 720:
                phi += math.radians(6.0)
            else:
                phi = math.radians(6.0)

    def MyDraw(self):
        plt.imshow(a, interpolation="none")
                plt.show()

if __name__ == '__main__':
    import sys

    app = QtGui.QApplication(sys.argv)

    window = ld()
    window.show()

    sys.exit(app.exec_())


Картинка выводится в отельном окне, но к сожалению ошибки:

plt.imshow(a, interpolation="none")


Ошибка такая:

File "D:/PythonProject/l/ld.py", line 44, in paintEvent
self.MyDraw()
File "D:/PythonProject/l/ld.py", line 100, in MyDraw
plt.imshow(a, interpolation="none")
File "D:\Python26\Lib\site-packages\matplotlib\pyplot.py", line 2737, in imshow
imlim=imlim, resample=resample, url=url, **kwargs)
File "D:\Python26\Lib\site-packages\matplotlib\axes.py", line 7105, in imshow
im.set_data(X)
File "D:\Python26\Lib\site-packages\matplotlib\image.py", line 422, in set_data
raise TypeError("Invalid dimensions for image data")
TypeError: Invalid dimensions for image data

Может это из-за того, что в отельном окне всё рисуется?

И ещё вопросик: как переделать

plt.imshow(a, interpolation="none")


Чтобы получилось аналог этого:

Tochka.drawImage(0, 0, im, 0, 0, int((2*math.degrees(phi))+0.5), 492)


Может я зря воспользоваться библиотекой matplotlib, а можно было воспользоватся библиотекой PIL (Python Imaging Library)?
Но я, что-то не нашёл функции для рисования картинки по данным из двухмерного массива.

Сообщение отредактировал zuze - 8.5.2013, 13:17
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 14.5.2013, 9:30
Сообщение #58


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


С выводом картинки, насколько я понял проблем нет. Тормозит тогда, когда картинка пересоздается.
Matplotlib и PIL не нужны, поскольку вы используете ту же функциональность Qt(setPixel/drawImage).
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

6 страниц V   1 2 3 > » 
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0


RSS Рейтинг@Mail.ru Текстовая версия Сейчас: 7.4.2025, 1:30