Я хотел бы написать инструмент для маркировки изображений с использованием PyQT4:
- загрузить несколько изображений из указанной папки;для каждого изображения:
- пользователь выбирает объекты (например, автомобиль) из изображений, рисуя область для этого объекта с помощью мыши
- , когда выбор сделан, отображается маска объектаНаложенный на исходное изображение
- , когда выбор всех объектов завершен, программа сохраняет каждую маску объекта (фон: 0, передний план: 255) как отдельное изображение png
- пользователь должен иметь возможность увеличивать / уменьшать изображение
Я уже написал аналогичную программу (без увеличения / уменьшения) на c ++ с wxWidgets.Я новичок в PyQT4 и пытаюсь узнать, как все работает.Самым сложным кажется рисование и правильное получение масок объектов, даже когда пользователь увеличивает / уменьшает.
Какие классы PyQT были бы идеальными для этой проблемы?Как я могу правильно получить маски объектов (возможно, в виде массива) и сохранить их?
Большое спасибо.
Следуя вашей рекомендации, я написал фрагмент кода для отображенияimage и рисуйте на изображении с помощью мыши (все еще в стадии эксперимента и обучения).
Я сохраняю изображение в QGraphicsPixmapItem, добавляю его к сцене.Затем я рисую изображение, переопределяя его метод рисования.Наконец, я переопределяю события мыши, чтобы определить положение мыши и нарисовать там круг.Но когда я двигаю мышь, старый круг удаляется, а новый окрашивается.То есть круг не нарисован на самом изображении.Я думаю, мне следует использовать что-то вроде следующего, чтобы рисование было постоянным на изображении:
painter = QPainter()
painter.begin(pixmap)
# here do the drawing
painter.end()
Но проблема в том, что функция рисования уже принимает художника в качестве аргумента;воссоздание нового в функции рисования не работает (очевидно) ..
Вот код:
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class ImageDrawPanel(QGraphicsPixmapItem):
def __init__(self, pixmap=None, parent=None, scene=None):
super(ImageDrawPanel, self).__init__()
self.x, self.y = -1, -1
self.radius = 10
self.pen = QPen(Qt.SolidLine)
self.pen.setColor(Qt.black)
self.pen.setWidth(2)
self.brush = QBrush(Qt.yellow)
def paint(self, painter, option, widget=None):
painter.drawPixmap(0, 0, self.pixmap())
painter.setPen(self.pen)
painter.setBrush(self.brush)
if self.x >= 0 and self.y >= 0:
painter.drawEllipse(self.x-self.radius, self.y-self.radius, 2*self.radius, 2*self.radius)
self.x, self.y = -1, -1
def mousePressEvent (self, event):
print 'mouse pressed'
self.x=event.pos().x()
self.y=event.pos().y()
self.update()
def mouseMoveEvent (self, event):
print 'mouse moving'
self.x=event.pos().x()
self.y=event.pos().y()
self.update()
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.scene = QGraphicsScene()
self.scene.setSceneRect(0, 0, 800, 600)
pixmap=self.openImage()
self.imagePanel = ImageDrawPanel(scene = self.scene)
self.imagePanel.setPixmap(pixmap)
self.scene.addItem(self.imagePanel)
self.view = QGraphicsView(self.scene)
layout = QHBoxLayout()
layout.addWidget(self.view)
self.widget = QWidget()
self.widget.setLayout(layout)
self.setCentralWidget(self.widget)
self.setWindowTitle("Image Draw")
def openImage(self):
fname = QFileDialog.getOpenFileName(self, "Open image", ".", "Image Files (*.bmp *.jpg *.png *.xpm)")
if fname.isEmpty(): return None
return QPixmap(fname)
import sys
if __name__ == "__main__":
app = QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
sys.exit(app.exec_())
Что мне теперь делать, чтобы навсегда нарисовать на изображении?Я могу сохранить все точки и заново нарисовать их краской, но это не кажется эффективным.Должен ли я рисовать в QGraphicsScene, а не в самом QGraphicsPixmapItem?
Вторая проблема, после рисования на изображении, как я могу получить маску выделенной области?Что-то вроде создания нового изображения с альфа-каналом, а затем извлечения значений пикселей?Или рисовать на пустом изображении параллельно?Затем я также должен отслеживать увеличение / уменьшение масштаба ..