def repaintArea(self):

        self._overlay_stack.append(self.mask_pixmap.copy())
        if self.direct_mask_paint:
            self._offscreen_mask_stack.append(self._offscreen_mask.copy())
        orig_mask = self.mask_pixmap.toImage().convertToFormat(
            QImage.Format_ARGB32)
        msk = alpha_view(orig_mask).copy()
        msk[np.where((msk > 0))] = 255
        msk = 255 - msk
        msk1 = 255 - np.copy(msk)
        the_mask = cv2.copyMakeBorder(np.zeros(msk1.shape[:2], np.uint8), 1, 1,
                                      1, 1, cv2.BORDER_CONSTANT, 0)
        seed_point = (int(self.lastCursorLocation.x()),
                      int(self.lastCursorLocation.y()))
        cv2.floodFill(msk1, the_mask, seed_point, 0, 0, 1)
        paintin = np.bitwise_xor(msk, msk1)
        new_img = np.dstack((rgb_view(orig_mask), alpha_view(orig_mask)))
        new_img[np.where(
            (paintin == 0))] = list(self.brush_fill_color.getRgb())
        new_qimg = array2qimage(new_img)

        if self.direct_mask_paint:
            omask = byte_view(self._offscreen_mask).copy()
            omask = omask.reshape(omask.shape[:-1])
            tc = self.d_rgb2gray[self.brush_fill_color.name()]
            omask[np.where((paintin == 0))] = tc
            self._offscreen_mask = QImage(omask.data, omask.shape[1],
                                          omask.shape[0], omask.strides[0],
                                          QImage.Format_Grayscale8)

        self.mask_pixmap = QPixmap.fromImage(new_qimg)
        self._overlayHandle.setPixmap(self.mask_pixmap)
def test_alpha_view():
    qimg = QtGui.QImage(320, 240, QtGui.QImage.Format_ARGB32)
    qimg.fill(23)
    v = qimage2ndarray.alpha_view(qimg)
    qimg.setPixel(12, 10, QtGui.qRgb(12,34,56))
    assert_equal(v[10,12], 255)
    assert_equal(v[10,11], 0)
Beispiel #3
0
 def getRoomFromPix(self, pos):
     r = 5
     best_room, best_pixels = None, 0
     for idx, box in enumerate(self.imageBounds):
         # Check to see if clicked position is inside the bounds of current image
         if box[0].x() < pos.x() < box[1].x() and box[0].y() < pos.y(
         ) < box[1].y():
             # Check to see if the number of nearby pixels is greater than the current max
             values = qimage2ndarray.alpha_view(self.images[idx])
             x, y = int(pos.x() - box[0].x()), int(pos.y() - box[0].y())
             min_x, min_y = max(0, x - r), max(0, y - r)
             max_x, max_y = min(values.shape[0] - 1,
                                x + r + 1), min(values.shape[1] - 1,
                                                y + r + 1)
             pixels = values[min_x:max_x, min_y:max_y].sum()
             if pixels > best_pixels:
                 best_pixels = pixels
                 best_room = idx
     return best_room
 def export_ndarray(self):
     mask = self.mask_pixmap.toImage().convertToFormat(QImage.Format_ARGB32)
     return np.dstack((rgb_view(mask).copy(), alpha_view(mask).copy()))
    def fillArea(self,
                 remove_closed_contour=False,
                 remove_only_current_color=True):

        # Store previous state so we can go back to it
        self._overlay_stack.append(self.mask_pixmap.copy())

        if self.direct_mask_paint:
            self._offscreen_mask_stack.append(self._offscreen_mask.copy())

        # We first convert the mask to a QImage and then to ndarray
        orig_mask = self.mask_pixmap.toImage().convertToFormat(
            QImage.Format_ARGB32)
        msk = alpha_view(orig_mask).copy()

        # Apply simple tresholding and invert the image
        msk[np.where((msk > 0))] = 255
        msk = 255 - msk
        msk1 = np.copy(msk)

        if remove_closed_contour:
            msk1 = 255 - msk1

        if remove_closed_contour:
            if remove_only_current_color:
                the_mask = np.ones(msk1.shape[:2],
                                   np.uint8) * 255  # Initial mask
                fullmask = self.export_ndarray_noalpha(
                )  # Get the colored version
                reds, greens, blues = fullmask[:, :,
                                               0], fullmask[:, :,
                                                            1], fullmask[:, :,
                                                                         2]
                cur_col = list(self.brush_fill_color.getRgb()
                               )[:-1]  # Only current color is considered
                # So that fill happens only for this specific color
                the_mask[
                    np.isclose(reds, cur_col[0], atol=PIXMAP_CONV_BUG_ATOL)
                    & np.isclose(greens, cur_col[1], atol=PIXMAP_CONV_BUG_ATOL)
                    & np.isclose(blues, cur_col[2],
                                 atol=PIXMAP_CONV_BUG_ATOL)] = 0

            else:
                the_mask = np.zeros(msk1.shape[:2], np.uint8)
        else:
            the_mask = cv2.bitwise_not(np.copy(msk))

        the_mask = cv2.copyMakeBorder(the_mask, 1, 1, 1, 1,
                                      cv2.BORDER_CONSTANT, 0)

        # Fill the contour
        seed_point = (int(self.lastCursorLocation.x()),
                      int(self.lastCursorLocation.y()))
        cv2.floodFill(msk1, the_mask, seed_point, 0, 0, 1)

        # We paint in only the newly arrived pixels (or remove the pixels in the contour)
        if remove_closed_contour:
            paintin = msk1
        else:
            paintin = msk - msk1  # This is fill case

        # Take original pixmap image: it has two components, RGB and ALPHA
        new_img = np.dstack((rgb_view(orig_mask), alpha_view(orig_mask)))

        # Fill the newly created area with current brush color
        if not remove_closed_contour:
            new_img[np.where(
                (paintin == 255))] = list(self.brush_fill_color.getRgb())
        else:
            new_img[np.where((paintin == 0))] = (0, 0, 0, 0)  # Erase
        new_qimg = array2qimage(new_img)

        # In case of direct drawing, need to update the offscreen mask as well
        if self.direct_mask_paint:
            omask = byte_view(self._offscreen_mask).copy()
            omask = omask.reshape(omask.shape[:-1])
            if not remove_closed_contour:
                tc = self.d_rgb2gray[self.brush_fill_color.name()]
                omask[np.where((paintin == 255))] = tc
            else:
                omask[np.where((paintin == 0))] = 0
            self._offscreen_mask = QImage(omask.data, omask.shape[1],
                                          omask.shape[0], omask.strides[0],
                                          QImage.Format_Grayscale8)

        # Finally update the screen stuff
        self.mask_pixmap = QPixmap.fromImage(new_qimg)
        self._overlayHandle.setPixmap(self.mask_pixmap)