如何使用 cv2.circle 在 Qlabel 内的图像上绘制一个圆圈
Posted
技术标签:
【中文标题】如何使用 cv2.circle 在 Qlabel 内的图像上绘制一个圆圈【英文标题】:How to draw a circle on an image inside a Qlabel with using cv2.circle 【发布时间】:2021-05-07 19:28:27 【问题描述】:在我使用 Qt Designer 创建的界面中,我将带有 setPixmap 的 PNG 图像添加到 Qlabel (label_map_view) 中,并且我想使用 cv2.circle 在此图像中的某些点绘制一个圆。但我做不到。这可能吗?
我的代码:
import rospy
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import QTimer
from PyQt5.QtGui import QImage
from PyQt5.QtGui import QPixmap
from geometry_msgs.msg import Twist
from nav_msgs.msg import Odometry
import cv2
import numpy as np
import otonom_hareket_3hedef
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1300, 850)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth())
MainWindow.setSizePolicy(sizePolicy)
MainWindow.setMinimumSize(QtCore.QSize(1300, 850))
MainWindow.setMaximumSize(QtCore.QSize(1300, 850))
palette = QtGui.QPalette()
brush = QtGui.QBrush(QtGui.QColor(238, 238, 236))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Button, brush)
brush = QtGui.QBrush(QtGui.QColor(238, 238, 236))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush)
brush = QtGui.QBrush(QtGui.QColor(238, 238, 236))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Window, brush)
brush = QtGui.QBrush(QtGui.QColor(238, 238, 236))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Button, brush)
brush = QtGui.QBrush(QtGui.QColor(238, 238, 236))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush)
brush = QtGui.QBrush(QtGui.QColor(238, 238, 236))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Window, brush)
brush = QtGui.QBrush(QtGui.QColor(238, 238, 236))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Button, brush)
brush = QtGui.QBrush(QtGui.QColor(238, 238, 236))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush)
brush = QtGui.QBrush(QtGui.QColor(238, 238, 236))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Window, brush)
MainWindow.setPalette(palette)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
font.setStyleStrategy(QtGui.QFont.PreferDefault)
MainWindow.setFont(font)
MainWindow.setWindowOpacity(1.0)
MainWindow.setStyleSheet("background-color: rgb(238, 238, 236);\n"
"")
MainWindow.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly)
MainWindow.setDocumentMode(False)
MainWindow.setUnifiedTitleAndToolBarOnMac(False)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
self.centralwidget.setObjectName("centralwidget")
self.layoutWidget = QtWidgets.QWidget(self.centralwidget)
self.layoutWidget.setGeometry(QtCore.QRect(9, 9, 481, 141))
self.layoutWidget.setObjectName("layoutWidget")
self.position_layout = QtWidgets.QFormLayout(self.layoutWidget)
self.position_layout.setContentsMargins(0, 0, 0, 0)
self.position_layout.setObjectName("position_layout")
self.label_position = QtWidgets.QLabel(self.layoutWidget)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.label_position.setFont(font)
self.label_position.setStyleSheet("color: rgb(61, 52, 139)")
self.label_position.setObjectName("label_position")
self.position_layout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label_position)
self.label_x = QtWidgets.QLabel(self.layoutWidget)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.label_x.setFont(font)
self.label_x.setStyleSheet("color: rgb(230, 175, 46);")
self.label_x.setObjectName("label_x")
self.position_layout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_x)
self.line_x = QtWidgets.QLineEdit(self.layoutWidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.line_x.sizePolicy().hasHeightForWidth())
self.line_x.setSizePolicy(sizePolicy)
self.line_x.setMinimumSize(QtCore.QSize(15, 15))
self.line_x.setMaximumSize(QtCore.QSize(300, 50))
self.line_x.setStyleSheet("background-color: rgb(172, 190, 216);")
self.line_x.setObjectName("line_x")
self.position_layout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.line_x)
self.label_y = QtWidgets.QLabel(self.layoutWidget)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.label_y.setFont(font)
self.label_y.setStyleSheet("color: rgb(230, 175, 46);")
self.label_y.setObjectName("label_y")
self.position_layout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.label_y)
self.line_y = QtWidgets.QLineEdit(self.layoutWidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.line_y.sizePolicy().hasHeightForWidth())
self.line_y.setSizePolicy(sizePolicy)
self.line_y.setMaximumSize(QtCore.QSize(300, 50))
self.line_y.setStyleSheet("background-color: rgb(172, 190, 216);")
self.line_y.setObjectName("line_y")
self.position_layout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.line_y)
self.layoutWidget1 = QtWidgets.QWidget(self.centralwidget)
self.layoutWidget1.setGeometry(QtCore.QRect(680, 600, 411, 151))
self.layoutWidget1.setObjectName("layoutWidget1")
self.control_layout = QtWidgets.QGridLayout(self.layoutWidget1)
self.control_layout.setContentsMargins(0, 0, 0, 0)
self.control_layout.setObjectName("control_layout")
self.stop_button = QtWidgets.QPushButton(self.layoutWidget1)
self.stop_button.setStyleSheet("background-color: rgb(61, 52, 139);\n"
"color: rgb(238, 238, 236);r")
icon = QtGui.QIcon.fromTheme("stop")
self.stop_button.setIcon(icon)
self.stop_button.setObjectName("stop_button")
self.control_layout.addWidget(self.stop_button, 2, 1, 1, 1)
self.backward_button = QtWidgets.QPushButton(self.layoutWidget1)
self.backward_button.setStyleSheet("background-color: rgb(61, 52, 139);\n"
"color: rgb(238, 238, 236);r")
icon = QtGui.QIcon.fromTheme("down")
self.backward_button.setIcon(icon)
self.backward_button.setObjectName("backward_button")
self.control_layout.addWidget(self.backward_button, 3, 1, 1, 1)
self.right_button = QtWidgets.QPushButton(self.layoutWidget1)
self.right_button.setStyleSheet("background-color: rgb(61, 52, 139);\n"
"color: rgb(238, 238, 236);r")
icon = QtGui.QIcon.fromTheme("forward")
self.right_button.setIcon(icon)
self.right_button.setObjectName("right_button")
self.control_layout.addWidget(self.right_button, 2, 2, 1, 1)
self.left_button = QtWidgets.QPushButton(self.layoutWidget1)
self.left_button.setStyleSheet("background-color: rgb(61, 52, 139);\n"
"color: rgb(238, 238, 236);r")
icon = QtGui.QIcon.fromTheme("back")
self.left_button.setIcon(icon)
self.left_button.setObjectName("left_button")
self.control_layout.addWidget(self.left_button, 2, 0, 1, 1)
self.forward_button = QtWidgets.QPushButton(self.layoutWidget1)
font = QtGui.QFont()
font.setBold(False)
font.setItalic(False)
font.setWeight(50)
font.setStrikeOut(False)
font.setKerning(True)
self.forward_button.setFont(font)
self.forward_button.setStyleSheet("background-color: rgb(61, 52, 139);\n"
"color: rgb(238, 238, 236);r")
icon = QtGui.QIcon.fromTheme("up")
self.forward_button.setIcon(icon)
self.forward_button.setObjectName("forward_button")
self.control_layout.addWidget(self.forward_button, 1, 1, 1, 1)
self.label = QtWidgets.QLabel(self.layoutWidget1)
font = QtGui.QFont()
font.setBold(True)
font.setUnderline(False)
font.setWeight(75)
font.setStrikeOut(False)
font.setStyleStrategy(QtGui.QFont.PreferDefault)
self.label.setFont(font)
self.label.setStyleSheet("color: rgb(230, 175, 46);")
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setObjectName("label")
self.control_layout.addWidget(self.label, 0, 1, 1, 1)
self.layoutWidget2 = QtWidgets.QWidget(self.centralwidget)
self.layoutWidget2.setGeometry(QtCore.QRect(10, 150, 481, 111))
self.layoutWidget2.setObjectName("layoutWidget2")
self.vertical_layout = QtWidgets.QFormLayout(self.layoutWidget2)
self.vertical_layout.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
self.vertical_layout.setContentsMargins(0, 0, 0, 0)
self.vertical_layout.setSpacing(6)
self.vertical_layout.setObjectName("vertical_layout")
self.label_velocity = QtWidgets.QLabel(self.layoutWidget2)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.label_velocity.setFont(font)
self.label_velocity.setStyleSheet("color: rgb(61, 52, 139)")
self.label_velocity.setObjectName("label_velocity")
self.vertical_layout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label_velocity)
self.label_linear = QtWidgets.QLabel(self.layoutWidget2)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.label_linear.setFont(font)
self.label_linear.setStyleSheet("color: rgb(230, 175, 46);")
self.label_linear.setObjectName("label_linear")
self.vertical_layout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_linear)
self.line_linear = QtWidgets.QLineEdit(self.layoutWidget2)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.line_linear.sizePolicy().hasHeightForWidth())
self.line_linear.setSizePolicy(sizePolicy)
self.line_linear.setMaximumSize(QtCore.QSize(300, 50))
self.line_linear.setStyleSheet("background-color: rgb(172, 190, 216);")
self.line_linear.setObjectName("line_linear")
self.vertical_layout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.line_linear)
self.label_angular = QtWidgets.QLabel(self.layoutWidget2)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.label_angular.setFont(font)
self.label_angular.setStyleSheet("color: rgb(230, 175, 46);")
self.label_angular.setObjectName("label_angular")
self.vertical_layout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.label_angular)
self.line_angular = QtWidgets.QLineEdit(self.layoutWidget2)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.line_angular.sizePolicy().hasHeightForWidth())
self.line_angular.setSizePolicy(sizePolicy)
self.line_angular.setMaximumSize(QtCore.QSize(300, 50))
self.line_angular.setStyleSheet("background-color: rgb(172, 190, 216);")
self.line_angular.setObjectName("line_angular")
self.vertical_layout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.line_angular)
self.map_button = QtWidgets.QPushButton(self.centralwidget)
self.map_button.setGeometry(QtCore.QRect(810, 540, 151, 25))
self.map_button.setStyleSheet("background-color: rgb(61, 52, 139);\n"
"color: rgb(238, 238, 236);r")
self.map_button.setObjectName("map_button")
self.label_map_view = QtWidgets.QLabel(self.centralwidget)
self.label_map_view.setGeometry(QtCore.QRect(540, 30, 709, 497))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label_map_view.sizePolicy().hasHeightForWidth())
self.label_map_view.setSizePolicy(sizePolicy)
self.label_map_view.setMinimumSize(QtCore.QSize(709, 497))
self.label_map_view.setMaximumSize(QtCore.QSize(709, 497))
self.label_map_view.setText("")
**img_msg=self.label_map_view.setPixmap(QtGui.QPixmap("../map/house_gazebo.png"))
img = np.frombuffer(img_msg.data,dtype=np.uint8).reshape(img_msg.height, img_msg.width, -1)
cv2.circle(img,(100,100),100,(0,0,255),-1)**
self.label_map_view.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
self.label_map_view.setObjectName("label_map_view")
self.label_map = QtWidgets.QLabel(self.centralwidget)
self.label_map.setGeometry(QtCore.QRect(870, 0, 41, 17))
self.label_map.setMaximumSize(QtCore.QSize(16777215, 16777215))
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.label_map.setFont(font)
self.label_map.setStyleSheet("color: rgb(61, 52, 139)")
self.label_map.setAlignment(QtCore.Qt.AlignCenter)
self.label_map.setObjectName("label_map")
self.label_camera = QtWidgets.QLabel(self.centralwidget)
self.label_camera.setGeometry(QtCore.QRect(20, 280, 501, 451))
self.label_camera.setLayoutDirection(QtCore.Qt.LeftToRight)
self.label_camera.setText("")
self.label_camera.setAlignment(QtCore.Qt.AlignCenter)
self.label_camera.setOpenExternalLinks(False)
self.label_camera.setObjectName("label_camera")
self.camera_button = QtWidgets.QPushButton(self.centralwidget)
self.camera_button.setGeometry(QtCore.QRect(210, 760, 111, 25))
self.camera_button.setStyleSheet("background-color: rgb(61, 52, 139);\n"
"color: rgb(238, 238, 236);r")
self.camera_button.setIconSize(QtCore.QSize(16, 16))
self.camera_button.setAutoDefault(False)
self.camera_button.setDefault(False)
self.camera_button.setFlat(False)
self.camera_button.setObjectName("camera_button")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1300, 22))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Robot Controller Interface"))
self.label_position.setText(_translate("MainWindow", "Position Indicator"))
self.label_x.setText(_translate("MainWindow", "Position x:"))
self.label_y.setText(_translate("MainWindow", "Position y:"))
self.stop_button.setText(_translate("MainWindow", "Stop"))
self.backward_button.setText(_translate("MainWindow", "Backward"))
self.right_button.setText(_translate("MainWindow", "Right"))
self.left_button.setText(_translate("MainWindow", "Left"))
self.forward_button.setText(_translate("MainWindow", "Forward"))
self.label.setText(_translate("MainWindow", "Robot Controller"))
self.label_velocity.setText(_translate("MainWindow", "Velocity Indicator"))
self.label_linear.setText(_translate("MainWindow", "Linear Velocity:"))
self.label_angular.setText(_translate("MainWindow", "Angular Velocity:"))
self.map_button.setText(_translate("MainWindow", "Autonomous Driving"))
self.label_map.setText(_translate("MainWindow", "MAP"))
self.camera_button.setText(_translate("MainWindow", "Start Camera"))
rospy.init_node('robot_interface')
self.pub=rospy.Publisher('cmd_vel', Twist, queue_size=10)
self.vel_msg=Twist()
rospy.Subscriber('odom', Odometry, self.odomCallback)
self.stop_button.clicked.connect(self.stop)
self.forward_button.clicked.connect(self.forward)
self.backward_button.clicked.connect(self.backward)
self.right_button.clicked.connect(self.turnRight)
self.left_button.clicked.connect(self.turnLeft)
self.line_angular.setText(str(0.0))
self.line_linear.setText(str(0.0))
self.line_x.setText(str(0.0))
self.line_y.setText(str(0.0))
# create a timer
self.timer = QTimer()
# set timer timeout callback function
self.timer.timeout.connect(self.viewCam)
# set control_bt callback clicked function
self.camera_button.clicked.connect(self.controlTimer)
self.map_button.clicked.connect(otonom_hareket_3hedef.movebase_client)
def circle(self,img_msg):
img = np.frombuffer(img_msg.data, dtype=np.uint8).reshape(img_msg.height, img_msg.width, -1)
cv2.circle(img,(100,100),100,(0,0,255),-1)
def odomCallback(self,message):
self.line_x.setText(str(round(message.pose.pose.position.x,4)))
self.line_y.setText(str(round(message.pose.pose.position.y,4)))
def stop(self):
self.vel_msg.linear.x=0.0
self.vel_msg.angular.z=0.0
self.pub.publish(self.vel_msg)
self.line_linear.setText(str(self.vel_msg.linear.x))
self.line_angular.setText(str(self.vel_msg.angular.z))
def forward(self):
self.vel_msg.linear.x=0.2
self.vel_msg.angular.z=0.0
self.pub.publish(self.vel_msg)
self.line_linear.setText(str(self.vel_msg.linear.x))
self.line_angular.setText(str(self.vel_msg.angular.z))
def backward(self):
self.vel_msg.linear.x=-0.2
self.vel_msg.angular.z=0.0
self.pub.publish(self.vel_msg)
self.line_linear.setText(str(self.vel_msg.linear.x))
self.line_angular.setText(str(self.vel_msg.angular.z))
def turnRight(self):
self.vel_msg.linear.x=0.0
self.vel_msg.angular.z=-0.3
self.pub.publish(self.vel_msg)
self.line_linear.setText(str(self.vel_msg.linear.x))
self.line_angular.setText(str(self.vel_msg.angular.z))
def turnLeft(self):
self.vel_msg.linear.x=0.0
self.vel_msg.angular.z=0.3
self.pub.publish(self.vel_msg)
self.line_linear.setText(str(self.vel_msg.linear.x))
self.line_angular.setText(str(self.vel_msg.angular.z))
# view camera
def viewCam(self):
# read image in BGR format
ret, image = self.cap.read()
# convert image to RGB format
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# get image infos
height, width, channel = image.shape
step = channel * width
# create QImage from image
qImg = QImage(image.data, width, height, step, QImage.Format_RGB888)
# show image in img_label
self.label_camera.setPixmap(QPixmap.fromImage(qImg))
# start/stop timer
def controlTimer(self):
# if timer is stopped
if not self.timer.isActive():
# create video capture
self.cap = cv2.VideoCapture(0)
# start timer
self.timer.start(20)
# update control_bt text
self.camera_button.setText("Stop")
# if timer is started
else:
# stop timer
self.timer.stop()
# release video capture
self.cap.release()
# update control_bt text
self.camera_button.setText("Start")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
【问题讨论】:
【参考方案1】:如果你想在一个将显示在 QLabel 中的图像上绘图,那么最好用 opencv 加载图像,绘制圆,将 numpy 数组转换为 QImage,将 QImage 转换为 QPixmap 并将其设置在QLabel:
center_coordinates = (30, 30)
radius = 20
color = (255, 0, 0)
thickness = 2
image_input = cv.imread("../map/house_gazebo.png")
image_output = cv2.circle(image_input, center_coordinates, radius, color, thickness)
src = cv2.cvtColor(image_output, cv2.COLOR_BGR2RGB)
h, w, ch = src.shape
bytesPerLine = ch * w
qimage = QtGui.QImage(src.data, w, h, bytesPerLine, QtGui.QImage.Format_RGB888)
self.label_map_view.setPixmap(QPixmap.fromImage(qimage))
【讨论】:
以上是关于如何使用 cv2.circle 在 Qlabel 内的图像上绘制一个圆圈的主要内容,如果未能解决你的问题,请参考以下文章