如何使用 cv2.circle 在 Qlabel 内的图像上绘制圆圈

How to draw a circle on an image inside a Qlabel with using cv2.circle

在我使用 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_())

如果你想在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))