ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • OpenCV에서 캡처한 영상을 pyQt5 윈도우에 보여주기
    OpenCV/OpenCV with pyQt5 2019. 1. 24. 13:38



    OpenCV에서 캡처한 영상을 pyQt5로 작성된 GUI에서 보여주는 방법을 다룹니다.

    깃허브에 있는 코드를 수정하여 사용했습니다.




    처음 실행하면 버튼 2개만 보입니다.





    start 버튼을 클릭하면 웹캠 영상이 보입니다.





    Canny 버튼을 클릭하면 오른쪽에 캐니 영상을 보여줍니다.




    # 출처 - https://github.com/ddd4117/GUI/blob/master/src/camera_test.py
    # 수정 - webnautes

    import cv2
    import sys
    from PyQt5 import QtCore
    from PyQt5 import QtWidgets
    from PyQt5 import QtGui


    class ShowVideo(QtCore.QObject):

       flag = 0

       camera = cv2.VideoCapture(0)

       ret, image = camera.read()
       height, width = image.shape[:2]

       VideoSignal1 = QtCore.pyqtSignal(QtGui.QImage)
       VideoSignal2 = QtCore.pyqtSignal(QtGui.QImage)

       def __init__(self, parent=None):
           super(ShowVideo, self).__init__(parent)

       @QtCore.pyqtSlot()
       def startVideo(self):
           global image

           run_video = True
           while run_video:
               ret, image = self.camera.read()
               color_swapped_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

               qt_image1 = QtGui.QImage(color_swapped_image.data,
                                       self.width,
                                       self.height,
                                       color_swapped_image.strides[0],
                                       QtGui.QImage.Format_RGB888)
               self.VideoSignal1.emit(qt_image1)


               if self.flag:
                   img_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
                   img_canny = cv2.Canny(img_gray, 50, 100)

                   qt_image2 = QtGui.QImage(img_canny.data,
                                            self.width,
                                            self.height,
                                            img_canny.strides[0],
                                            QtGui.QImage.Format_Grayscale8)

                   self.VideoSignal2.emit(qt_image2)


               loop = QtCore.QEventLoop()
               QtCore.QTimer.singleShot(25, loop.quit) #25 ms
               loop.exec_()

       @QtCore.pyqtSlot()
       def canny(self):
           self.flag = 1 - self.flag


    class ImageViewer(QtWidgets.QWidget):
       def __init__(self, parent=None):
           super(ImageViewer, self).__init__(parent)
           self.image = QtGui.QImage()
           self.setAttribute(QtCore.Qt.WA_OpaquePaintEvent)

       def paintEvent(self, event):
           painter = QtGui.QPainter(self)
           painter.drawImage(0, 0, self.image)
           self.image = QtGui.QImage()

       def initUI(self):
           self.setWindowTitle('Test')

       @QtCore.pyqtSlot(QtGui.QImage)
       def setImage(self, image):
           if image.isNull():
               print("Viewer Dropped frame!")

           self.image = image
           if image.size() != self.size():
               self.setFixedSize(image.size())
           self.update()


    if __name__ == '__main__':
       app = QtWidgets.QApplication(sys.argv)


       thread = QtCore.QThread()
       thread.start()
       vid = ShowVideo()
       vid.moveToThread(thread)

       image_viewer1 = ImageViewer()
       image_viewer2 = ImageViewer()

       vid.VideoSignal1.connect(image_viewer1.setImage)
       vid.VideoSignal2.connect(image_viewer2.setImage)

       push_button1 = QtWidgets.QPushButton('Start')
       push_button2 = QtWidgets.QPushButton('Canny')
       push_button1.clicked.connect(vid.startVideo)
       push_button2.clicked.connect(vid.canny)

       vertical_layout = QtWidgets.QVBoxLayout()
       horizontal_layout = QtWidgets.QHBoxLayout()
       horizontal_layout.addWidget(image_viewer1)
       horizontal_layout.addWidget(image_viewer2)
       vertical_layout.addLayout(horizontal_layout)
       vertical_layout.addWidget(push_button1)
       vertical_layout.addWidget(push_button2)

       layout_widget = QtWidgets.QWidget()
       layout_widget.setLayout(vertical_layout)

       main_window = QtWidgets.QMainWindow()
       main_window.setCentralWidget(layout_widget)
       main_window.show()
       sys.exit(app.exec_())




    최초 작성  2019. 1. 24


    포스트 작성시에는 문제 없었지만 이후 문제가 생길 수 있습니다.
    댓글로 알려주시면 빠른 시일내에 답변을 드리겠습니다.

    여러분의 응원으로 좋은 컨텐츠가 만들어집니다. 지금 본 내용이 도움이 되었다면 유튜브 구독 부탁드립니다. 감사합니다 : )

    유튜브 구독하기


    댓글 12

    • ryu 2019.01.25 12:53


      저는 vc로 해봤는데요.
      QImage에 Mat 데이터 집어넣고 QLabel(view1) 에 setPixmap() 호출하면 되더군요.
      제가 Qt를 지워버려서 다음에 혹시 필요할까봐 여기에 남겨요,
      --------
      void MainWindow::OnTimer()
      {
      Mat img;
      Mat1b img_gray;

      cap.read(img);

      cvtColor( img, img, COLOR_BGR2RGB );
      cvtColor( img, img_gray, COLOR_BGR2GRAY );

      QImage qimg1(img.data, img.cols, img.rows, img.step, QImage::Format_RGB888 );
      QImage qimg2(img_gray.data, img_gray.cols, img_gray.rows, img_gray.step, QImage::Format_Grayscale8 );

      ui->view1->setPixmap( QPixmap::fromImage(qimg1) );
      ui->view2->setPixmap( QPixmap::fromImage(qimg2) );
      }

    • 안녕하세요 2019.03.05 21:04


      감사합니다 덕분에 졸음감지코드에 gui를 입힐 수 있게 되었습니다.
      지금은 코드를 실행시켰을때 검은 화면이 아닌 바로 웹캠 화면이 나오도록 수정해보고 있습니다만... 쉬울것 같았는데 맘대로 되질 않네요
      혹시 어떻게 해야 하는지 알려주실 수 있나요?

      • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.03.05 21:25 신고


        다음처럼 vid.startVideo()를 추가하면됩니다.

        main_window.show()
        vid.startVideo()
        sys.exit(app.exec_())

      • 안녕하세요 2019.03.05 21:48


        처음에 startVideo를 실행시키면
        검은이미지에 관련된 코드는 없어도 될것 같은데, Image_viewer, ImageViewer() 관련 라인만 지우면 되는건 아닌가요??

      • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.03.05 21:52 신고


        버튼 만드는 코드와 버튼 누를때 동작하도록 하는 코드 외에는 다 필요한 부분입니다.

    • eksox 2019.03.08 16:57


      코드 응용해보고 있습니다
      저기서 위젯을 추가하고 싶은데 클래스나 함수를 만들어서 추가 하려면 showvideo클래스 안에 만들고 vid.ㅇㅇㅇㅇ 로 호출시키면 되나요?

    • Marek Wojciechowski 2019.05.25 01:25


      Hello.
      My name is Marek and for a long time I try to compile via cmake last version OpenCV 4.1 contrib for 32bit Python 3.7. There are so many errors in Visual Studio 15 I can not handle it. I want to use sirf, surf features for my programming with Kinect 360 (or if You can tell me there are new solutions in opencv for segmentation 3d ?) Can You help me ?
      wojciechowski.marek@outlook.com

    • 2020.01.28 09:51


      비밀댓글입니다

    • 2020.02.05 17:33


      비밀댓글입니다

Designed by Tistory.