Прозрачное окно в opencv
Мне нужно сделать так, что бы я мог выводить только rectangle, при этом что бы всё остальное было полностью прозрачным - по настоящему прозрачным.
Вот код:
while True:
img = p_out.recv()
for (x,y,w,h) in t1.detectMultiScale(img, ais, ain):
p_in2.send(np.asarray([x,y,w,h]))
cv2.rectangle(img, (x, y),(x+w, y+h), (0, 0, 255), 2)
cv2.imshow("Vision", img)
if cv2.waitKey(1) & 0 == 1:
break
p.s На то как я получаю img не смотрите, это просто попытка сделать фон прозрачным.
Ответы (3 шт):
Автор решения: Александр
→ Ссылка
Я не нашёл как сделать прозрачное окно на cv2
Вот альтернатива
import sys
import numpy
import cv2
from PyQt5.QtWidgets import QWidget, QApplication, QMessageBox
from PyQt5.QtCore import Qt, QPoint
from PyQt5.QtGui import QPixmap, QPalette, QBrush, QImage
from PIL import Image, ImageDraw, ImageQt
# Отловить ошибки в слотах PyQt5
def log_uncaught_exceptions(ex_cls, ex, tb):
text = '{}: {}:\n'.format(ex_cls.__name__, ex)
import traceback
text += ''.join(traceback.format_tb(tb))
print(text)
QMessageBox.critical(None, 'Error', text)
quit()
sys.excepthook = log_uncaught_exceptions
class TransparentWindow(QWidget):
def __init__(self):
super().__init__()
self.interface()
def interface(self):
self.setWindowFlags(Qt.Window | Qt.FramelessWindowHint)
self.setWindowFlag(Qt.WindowStaysOnTopHint)
pil_image = Image.new('RGBA', (300, 300), (0, 0, 0, 0))
draw = ImageDraw.Draw(pil_image)
draw.rectangle((0, 0, 300, 300), outline=(0, 0, 255), width=5)
numpy_array = numpy.array(pil_image)
opencv_image = cv2.cvtColor(numpy_array, cv2.COLOR_RGBA2BGRA)# cv2.COLOR_BGR2HSV
# Start coordinate, here (5, 5)
# represents the top left corner of rectangle
start_point = (5, 5)
# Ending coordinate, here (220, 220)
# represents the bottom right corner of rectangle
end_point = (220, 220)
# Blue color in BGRA
color = (0, 0, 255, 255)
# Line thickness of 2 px
thickness = 2
# Using cv2.rectangle() method
# Draw a rectangle with blue line borders of thickness of 2 px
image = cv2.rectangle(opencv_image, start_point, end_point, color, thickness)
# Конвертируем изображение из OpenCV в PIL
pil_image = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGRA2RGBA))
image_qt = ImageQt.toqimage(pil_image)
pixmap = QPixmap.fromImage(image_qt)
palette = self.palette()
palette.setBrush(QPalette.Normal, QPalette.Window, QBrush(pixmap))
palette.setBrush(QPalette.Inactive, QPalette.Window, QBrush(pixmap))
self.setPalette(palette)
self.setMask(pixmap.mask())
def drag_window(self, event):
delta = QPoint(event.globalPos() - self.old_position)
self.move(self.x() + delta.x(), self.y() + delta.y())
self.old_position = event.globalPos()
def mousePressEvent(self, event):
"""Выбрать окно при помощи мыши"""
self.old_position = event.globalPos()
self.old_position = event.globalPos()
def mouseMoveEvent(self, event):
"""Переместить окно с помощью мыши"""
self.drag_window(event)
x, y = self.get_window_coordinates()
width, height = self.get_window_size()
region = x, y, width, height
def get_window_size(self):
"""Вернёт кортеж(width, height) размер окна"""
size = self.frameSize().width(), self.frameSize().height()
return size
def get_window_coordinates(self):
"""Вернёт кортеж(x, y) координаты окна"""
coordinates = self.x(), self.y()
return coordinates
def main():
application = QApplication(sys.argv)
transparent_window = TransparentWindow()
transparent_window.show()
sys.exit(application.exec_())
if __name__ == '__main__':
main()
Автор решения: Maxim Timakov
→ Ссылка
Вариант через прозрачный фон
import sys
from typing import List
from PySide2.QtCore import Qt
from PySide2.QtGui import QPainter, QPaintEvent, QPen
from PySide2.QtWidgets import QMainWindow, QApplication
class MyWindow(QMainWindow):
def __init__(self):
super().__init__(None)
self.setAttribute(Qt.WA_TranslucentBackground)
def paintEvent(self, _: QPaintEvent) -> None:
g = QPainter(self)
rc = self.rect()
g.fillRect(rc, Qt.transparent)
fg = QPen()
fg.setColor(Qt.red)
fg.setWidth(5)
g.setPen(fg)
g.drawRect(rc)
def main(args: List[str]) -> int:
app = QApplication(args)
w = MyWindow()
w.show()
return app.exec_()
if __name__ == '__main__':
sys.exit(main(sys.argv))
Демо(ОС: Debian testing):
UPD: этот способ не работает в Windows
Автор решения: S. Nick
→ Ссылка
Как вариант:
import sys
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.Qt import *
class Widget(QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.title = QLabel('<h1 style="color: red;">Title Bar</h1>' )
self.title.setAlignment(Qt.AlignCenter)
btn_size = 35
self.btn_close = QPushButton("x")
self.btn_close.setFixedSize(btn_size, btn_size)
self.btn_close.setStyleSheet("background-color: red;")
self.btn_min = QPushButton("_")
self.btn_min.setFixedSize(btn_size, btn_size)
self.btn_min.setStyleSheet("background-color: gray;")
self.btn_max = QPushButton("+")
self.btn_max.setFixedSize(btn_size, btn_size)
self.btn_max.setStyleSheet("background-color: gray;")
self.line = QFrame(self)
self.line.setStyleSheet("border: 3px solid rgb(255, 205, 0);")
self.line.setFrameShape(QtWidgets.QFrame.HLine)
title_bar = QHBoxLayout()
title_bar.setContentsMargins(0, 0, 0, 0)
title_bar.addWidget(self.title)
title_bar.addWidget(self.btn_min)
title_bar.addWidget(self.btn_max)
title_bar.addWidget(self.btn_close)
main_layout = QVBoxLayout(self)
main_layout.setContentsMargins(0, 0, 0, 0)
main_layout.addLayout(title_bar)
main_layout.addWidget(self.line)
main_layout.addStretch()
self.setWindowFlags(Qt.FramelessWindowHint)
class MainWindow(QMainWindow): # QMainWindow -QWidget
def __init__(self):
super(MainWindow, self).__init__()
self.centralwidget = QWidget()
self.setCentralWidget(self.centralwidget)
self.widget = Widget(self)
self.widget.btn_close.clicked.connect(self.btn_close_clicked)
self.widget.btn_min.clicked.connect(self.btn_min_clicked)
self.widget.btn_max.clicked.connect(self.btn_max_clicked)
lbl = QLabel('Hello World !!', self, alignment=Qt.AlignHCenter | Qt.AlignTop)
lbl.setStyleSheet("""
QLabel {
font-family: 'Consolas';
color: red;
font-size: 55px;
}
""")
self.setAttribute(Qt.WA_TranslucentBackground, True )
self.setAttribute(Qt.WA_NoSystemBackground, False)
self.setWindowFlags(Qt.FramelessWindowHint)
self.setStyleSheet("""
MainWindow {
background-color: rgba(0, 215, 55, 0);
/* попробуйте заменить строку выше на: v^ <---
background-color: rgba(0, 215, 55, 70);
*/
border: 3px solid rgb(255, 205, 0);
}
""")
self.button = QPushButton("Quit", self)
self.button.setAutoFillBackground(False)
self.button.setStyleSheet("""
background-color: qlineargradient(spread:pad,
x1:0.988818, y1:0.915,
x2:0, y2:0,
stop:0 rgba(53, 129, 90, 255),
stop:1 rgba(255, 255, 255, 255));
font: 75 16pt \"Georgia\";
""")
self.button.setFixedSize(100, 100)
self.button.clicked.connect(self.close)
layout = QVBoxLayout(self.centralwidget)
layout.addWidget(self.widget)
layout.addWidget(lbl)
layout.addStretch()
layout.addWidget(self.button, alignment=Qt.AlignCenter)
def btn_close_clicked(self):
quit()
def btn_min_clicked(self):
self.showMinimized()
def btn_max_clicked(self):
if self.isMaximized():
self.showNormal()
self.widget.btn_max.setText('+')
else:
self.showMaximized()
self.widget.btn_max.setText('R')
def mousePressEvent(self, event):
self.old_Pos = event.globalPos()
self.old_width = self.width()
self.old_height = self.height()
def mouseMoveEvent(self, event):
if (event.buttons() == Qt.LeftButton):
delta = QPoint (event.globalPos() - self.old_Pos)
if (self.old_Pos.x() > self.x() + self.old_width - 10) or \
(self.old_Pos.y() > self.y() + self.old_height - 10):
w = self.old_width+delta.x() if self.old_width+delta.x() > 230 else 230
h = self.old_height+delta.y() if self.old_height+delta.y() > 85 else 85
self.setFixedSize(w, h)
else:
self.move(self.x() + delta.x(), self.y() + delta.y())
self.old_Pos = event.globalPos()
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MainWindow()
w.resize(600, 400)
w.show()
sys.exit(app.exec())


