opencv와 pyqt5를 통합하여 구독자가 GUI로 이미지를 표시하도록 시도했지만 버튼을 클릭하면 이미지가 표시되지 않습니다. pyqt5를 구독자에 통합하기 전에 opencv 자체만으로 이미지를 표시 할 수있었습니다.
-Ubuntu 18.04를 사용하고 있습니다.
내 게시자 코드 :
def main():
image_pub = rospy.Publisher("/image", Image, queue_size=1)
rate = rospy.Rate(50)
bridge = CvBridge()
while not rospy.is_shutdown():
print("------------Mask detection processing one time!------------")
image_path='/home/sk/catkin_ws/src/test/scripts/p_e.png'
cv_image = cv2.imread(image_path)
# read a image using opencv
# change to your real image path
print(cv_image.shape)
#cv2.imshow("Pikachu", cv_image)
msg_image = bridge.cv2_to_imgmsg(cv_image, encoding = "bgr8")
stamp = rospy.Time.now()
msg_image.header.frame_id = "camera_link"
msg_image.header.stamp = stamp
image_pub.publish(msg_image)
rate.sleep()
if __name__ == '__main__':
try:
rospy.init_node('image_pub_node', anonymous=True)
main()
rospy.spin()
except KeyboardInterrupt:
print("Shutting down")
sys.exit(0)
pass
내 구독자 코드 :
class ImageWidget(QtWidgets.QWidget):
#def callback(self,data):
def callback(self,rosdata):
global cv_image
#self.bridge = CvBridge()
self.bridge = CvBridge()
#print("in callback")
rate = rospy.Rate(10)
rate.sleep()
try:
cv_image = self.bridge.imgmsg_to_cv2(rosdata, "bgr8")
#cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8")
except CvBridgeError as e:
print(e)
def __init__(self, parent=None):
super(ImageWidget, self).__init__(parent)
self.button = QtWidgets.QPushButton('Show picture')
self.button.clicked.connect(self.main)
self.image_frame = QtWidgets.QLabel()
self.layout = QtWidgets.QVBoxLayout()
self.layout.addWidget(self.button)
self.layout.addWidget(self.image_frame)
self.setLayout(self.layout)
def main(self):
rospy.init_node('image_sub_node', anonymous=True)
self.image_sub = rospy.Subscriber("/image", Image, self.callback, queue_size=1, buff_size=52428800)
rate = rospy.Rate(50) #50Hz
bridge = CvBridge()
while not rospy.is_shutdown():
print("------------Mask detection processing one time!------------")
try:
self.cv_image = cv2.imread('Image')
self.cv_image = QtGui.QImage(self.cv_image.data, self.cv_image.shape[1], self.cv_image.shape[0], QtGui.QImage.Format_RGB888).rgbSwapped()
self.image_frame.setPixmap(QtGui.QPixmap.fromImage(self.cv_image))
except Exception:
continue
rate.sleep()
if __name__ == '__main__':
try:
app = QtWidgets.QApplication(sys.argv)
image_widget = ImageWidget()
image_widget.show()
sys.exit(app.exec_())
rospy.init_node('image_sub_node', anonymous=True)
main()
rospy.spin()
except KeyboardInterrupt:
pass
exec_ () 메서드는 이벤트 루프를 실행하므로 Qt가 실행을 마친 후에 만 실행이 완료되고 sys.exit와 연결하면 후속 코드가 실행되지 않습니다.
반면에 while 루프를 사용해서는 안되지만 이벤트 루프 만 사용하고 신호를 사용하여 콜백 (보조 스레드에서 실행 됨)의 정보를 창으로 보내면됩니다.
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from sensor_msgs.msg import Image
from cv_bridge import CvBridge, CvBridgeError
import rospy
import cv2
class SubscriberManager(QtCore.QObject):
imageChanged = QtCore.pyqtSignal(QtGui.QImage)
def __init__(self, parent=None):
super(SubscriberManager, self).__init__(parent)
self.bridge = CvBridge()
self.subscriber = None
def start(self, name):
self.stop()
self.subscriber = rospy.Subscriber(
name, Image, self._callback, queue_size=1, buff_size=52428800
)
def stop(self):
if self.subscriber is not None:
self.subscriber.unregister()
self.subscriber = None
def _callback(self, rosdata):
try:
cv_image = self.bridge.imgmsg_to_cv2(rosdata, "bgr8")
except CvBridgeError as e:
print(e)
else:
src = cv2.cvtColor(cv_image, cv2.COLOR_BGR2RGB)
h, w, ch = src.shape
bytesPerLine = ch * w
qImg = QtGui.QImage(
src.data, w, h, bytesPerLine, QtGui.QImage.Format_RGB888
)
self.imageChanged.emit(qImg)
class ImageWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(ImageWidget, self).__init__(parent)
self.button = QtWidgets.QPushButton("Show picture")
self.image_frame = QtWidgets.QLabel()
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.button)
lay.addWidget(self.image_frame)
self.subscribe_manager = SubscriberManager()
self.subscribe_manager.imageChanged.connect(self.on_image_changed)
self.button.clicked.connect(self.start)
def start(self):
self.subscribe_manager.start("/image")
@QtCore.pyqtSlot(QtGui.QImage)
def on_image_changed(self, image):
self.image_frame.setPixmap(QtGui.QPixmap.fromImage(image))
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
rospy.init_node("image_sub_node", anonymous=True)
image_widget = ImageWidget()
image_widget.show()
sys.exit(app.exec_())
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다