Ejemplo n.º 1
0
def ndarrayToQImage(ndimg, format=QImage.Format_ARGB32):
    """
    Converts a 3D numpy ndarray to a QImage. No sanity check is
    done regarding the compatibility of the ndarray shape with
    the QImage format.
    @param ndimg: The ndarray to be converted
    @type ndimg: ndarray
    @param format: The QImage format (default ARGB32)
    @type format:
    @return: The converted image
    @rtype: QImage
    """
    if ndimg.ndim != 3 or ndimg.dtype != 'uint8':
        raise ValueError(
            "ndarray2QImage : array must be 3D with dtype=uint8, found ndim=%d, dtype=%s"
            % (ndimg.ndim, ndimg.dtype))
    bytePerLine = ndimg.shape[1] * ndimg.shape[2]
    if len(np.ravel(ndimg).data) != ndimg.shape[0] * bytePerLine:
        raise ValueError("ndarrayToQImage : conversion error")
    # build QImage from buffer
    qimg = QImage(ndimg.data, ndimg.shape[1], ndimg.shape[0], bytePerLine,
                  format)
    # keep a ref. to buffer to protect it from garbage collector
    qimg.buf_ = ndimg.data
    if qimg.format() == QImage.Format_Invalid:
        raise ValueError("ndarrayToQImage : wrong conversion")
    return qimg
Ejemplo n.º 2
0
 def loadMap(self, path: str):
     # Check image encoder
     image = QImage(path)
     if(image.format() != QImage.Format_Grayscale8):
         print('Wrong map pixel format, map should be Grayscale8.')
         return
     self.image = image
     self.oldImage = self.image.copy()
     self.update()
Ejemplo n.º 3
0
    def QImageToCV(image: QImage) -> ndarray:
        if image.format() != QImage.Format_RGB888:
            image = image.convertToFormat(QImage.Format_RGB888)

        width = image.width()
        height = image.height()

        ptr = image.bits()
        arr = array(ptr).reshape(height, width, 3)

        return arr
Ejemplo n.º 4
0
def qimg_to_rgb_arr(qimg: QImage) -> RGBArrayF:
    """Convert a :class:`QtGui.QImage` to an :data:`RGBArrayF`
    """
    fmt = QImage.Format_RGB32
    if qimg.format() != fmt:
        qimg = qimg.convertToFormat(fmt)

    width, height = qimg.width(), qimg.height()
    num_pixels = width * height

    bfr = qimg.constBits()
    int_arr = np.frombuffer(bfr, dtype=np.uint8, count=num_pixels * 4)

    bgra_arr = int_arr.reshape((height, width, 4)) / 255

    # Format_RGB32 stored as 0xffRRGGBB
    # so take only the first 3 items but in reverse
    rgb_arr = bgra_arr[..., 2::-1]

    return rgb_arr
Ejemplo n.º 5
0
    def redoIt(self):
        maya_cmds.undoInfo(stateWithoutFlush=False)
        try:
            image = QImage(self.image)
            if image.format() != QImage.Format_RGBA8888:
                image = image.convertToFormat(QImage.Format_RGBA8888)

            imageBits = image.bits()
            imageWidth = image.width()
            imageHeight = image.height()
            imageWidthM = imageWidth - 1
            imageHeightM = imageHeight - 1

            mFnMesh = OpenMaya.MFnMesh(
                OpenMaya.MGlobal.getSelectionListByName(
                    self.shape).getDagPath(0))
            mPoints = mFnMesh.getPoints(OpenMaya.MSpace.kWorld)
            self.mPoints = OpenMaya.MPointArray(mPoints)

            tmp1, uvIdsFace = mFnMesh.getAssignedUVs(self.uvName)
            tmp2, vertexIdsFace = mFnMesh.getVertices()
            u, v = mFnMesh.getUVs(self.uvName)
            uvs = [0] * len(u)
            for i in xrange(len(uvIdsFace)):
                uvIdFace = uvIdsFace[i]
                uvs[vertexIdsFace[i]] = [u[uvIdFace], v[uvIdFace]]

            if self.matrixIs.X:
                diffX = self.matrixMax.X - self.matrixMin.X
                for i in xrange(len(mPoints)):
                    u = int((uvs[i][0] % 1.0) * imageWidthM)
                    v = int((uvs[i][1] % 1.0) * imageHeightM)
                    mPoints[i].x += ((ord(imageBits[
                        (u + v * imageWidth) * 4 + self.matrixCha.X]) * diffX)
                                     / 255.0) + self.matrixMin.X
            if self.matrixIs.Y:
                diffY = self.matrixMax.Y - self.matrixMin.Y
                for i in xrange(len(mPoints)):
                    u = int((uvs[i][0] % 1.0) * imageWidthM)
                    v = int((uvs[i][1] % 1.0) * imageHeightM)
                    mPoints[i].y += ((ord(imageBits[
                        (u + v * imageWidth) * 4 + self.matrixCha.Y]) * diffY)
                                     / 255.0) + self.matrixMin.Y
            if self.matrixIs.Z:
                diffZ = self.matrixMax.Z - self.matrixMin.Z
                for i in xrange(len(mPoints)):
                    u = int((uvs[i][0] % 1.0) * imageWidthM)
                    v = int((uvs[i][1] % 1.0) * imageHeightM)
                    mPoints[i].z += ((ord(imageBits[
                        (u + v * imageWidth) * 4 + self.matrixCha.Z]) * diffZ)
                                     / 255.0) + self.matrixMin.Z
            if self.matrixIs.N:
                diffN = self.matrixMax.N - self.matrixMin.N
                mNormals = mFnMesh.getVertexNormals(True,
                                                    OpenMaya.MSpace.kWorld)
                for i in xrange(len(mPoints)):
                    u = int((uvs[i][0] % 1.0) * imageWidthM)
                    v = int((uvs[i][1] % 1.0) * imageHeightM)
                    mPoints[i].x += mNormals[i].x * ((
                        (ord(imageBits[
                            (u + v * imageWidth) * 4 + self.matrixCha.N]) *
                         diffN) / 255.0) + self.matrixMin.N)
                    mPoints[i].y += mNormals[i].y * ((
                        (ord(imageBits[
                            (u + v * imageWidth) * 4 + self.matrixCha.N]) *
                         diffN) / 255.0) + self.matrixMin.N)
                    mPoints[i].z += mNormals[i].z * ((
                        (ord(imageBits[
                            (u + v * imageWidth) * 4 + self.matrixCha.N]) *
                         diffN) / 255.0) + self.matrixMin.N)
            mFnMesh.setPoints(mPoints, OpenMaya.MSpace.kWorld)
            mFnMesh.updateSurface()
        except Exception as e:
            print >> stderr, str(e)
        maya_cmds.undoInfo(stateWithoutFlush=True)
Ejemplo n.º 6
0
class Map(QQuickPaintedItem):

    def __init__(self, parent = None):
        super(Map, self).__init__(parent)

        self.viewport = None

        self.setAcceptedMouseButtons(Qt.AllButtons)
        self.generate()

    clicked = Signal(QPoint)

    @Slot()
    def generate(self):
        # QImage does not work with bits, only with bytes
        self.image = QImage(300, 300, QImage.Format_Grayscale8)
        self.oldImage = None
        self.generateMap()
        self._percentage = 0

        self._pressClick = QPoint()

    def pixel(self, x: int, y: int, image = None) -> bool:
        if not image:
            image = self.image

        # This solves:
        # QImage::pixelIndex: Not applicable for 8-bpp images (no palette)
        return image.bits()[int(x) + int(y) * image.bytesPerLine()] & 0xff

    def setPixel(self, x: int, y: int, value: int, image = None):
        if not image:
            image = self.image

        # This solves:
        # QImage::pixelIndex: Not applicable for 8-bpp images (no palette)
        image.bits()[int(x) + int(y) * image.bytesPerLine()] = value

    def createRandomMap(self):
        for i in range(self.image.byteCount()):
            if random.random() < 0.35:
                self.image.bits()[i] = 255
            else:
                self.image.bits()[i] = 0

    def countNeighbors(self, x: int, y: int, image = None, n = 1) -> int:
        if not image:
            image = self.image

        count = 0
        for i in range(-n , n + 1):
            for u in range(-n , n + 1):
                if not i and not u:
                    continue

                #TODO: pixel function is poor
                # need to use bits()
                if x + i < 0 or y + u < 0 or \
                    x + i >= image.width() or y + u >= image.height():
                    count += 1
                    continue

                if not self.pixel(x + i, y + u, image):
                    count += 1

        return count

    @Slot(int)
    def doStep(self, n = 1):
        if self.image.format() != QImage.Format_Grayscale8:
            print("Wrong file format, generate map again.")
            return

        deathLimit = 14
        self._percentage = 0
        for _ in range(n):
            _image = self.image.copy()
            for x in range(self.image.width()):
                self._percentage += 1.0/(self.image.width()*n)
                if x%10 == 0:
                    # Update percentage
                    self.percentageChanged.emit()
                    # processEvent is necessary
                    QEventLoop().processEvents()
                    # Update map
                    self.update()
                for y in range(self.image.height()):
                    if self.countNeighbors(x, y, _image, 2) > deathLimit or \
                        x == 0 or y == 0 or x == _image.width() - 1 or y == _image.height() - 1:
                        self.setPixel(x, y, 0)
                    else:
                        self.setPixel(x, y, 255)
        # Update percentage
        self.update()
        self.oldImage = self.image.copy()
        self.percentageChanged.emit()
        QEventLoop().processEvents()

    def generateMap(self):
        self.createRandomMap()
        self.update()
        self.oldImage = self.image.copy()

    def paint(self, painter):
        painter.drawImage(QRect(0, 0, self.width(), self.height()), self.image)
        self.viewport = painter.viewport()

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Space:
            print('Update..')
            start = time.time()
            self.doStep()
            print('Took: %.2fs' % (time.time() - start))
        event.accept()

    def mousePressEvent(self, event):
        a, b = event.pos().x()*self.image.width()/self.width(), event.pos().y()*self.image.height()/self.height()
        self.clicked.emit(QPoint(a, b))

    def mouseMoveEvent(self, event):
        a, b = event.pos().x()*self.image.width()/self.width(), event.pos().y()*self.image.height()/self.height()
        self.clicked.emit(QPoint(a, b))

    def percentage(self):
        return self._percentage

    percentageChanged = Signal()
    percentage = Property(float, percentage, notify=percentageChanged)

    @Slot()
    def addVehicle(self):
        self.image = self.image.convertToFormat(QImage.Format_RGBA8888)
        painter = QPainter(self.image)
        painter.drawImage(QRect(50, 50, 13, 15), QImage("imgs/turtle.png"))
        painter.end()
        self.update()

    @Slot(str)
    def saveMap(self, path: str):
        # Check image encoder
        if(self.image.format() != QImage.Format_Grayscale8):
            print('Wrong map pixel format, create map without vehicle added.')
            return
        ok = self.image.save(path)
        if(not ok):
            print('It was not possible to save Map in:', path)

    @Slot(str)
    def loadMap(self, path: str):
        # Check image encoder
        image = QImage(path)
        if(image.format() != QImage.Format_Grayscale8):
            print('Wrong map pixel format, map should be Grayscale8.')
            return
        self.image = image
        self.oldImage = self.image.copy()
        self.update()