반응형



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


반응형

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

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

유튜브 구독하기


제가 쓴 책도 한번 검토해보세요.

  1. 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) );
    }

  2. 안녕하세요 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 신고

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

  3. eksox 2019.03.08 16:57

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

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.03.08 18:45 신고

      if __name__ == '__main__': 다음에 기존코드있는 위치에 필요한 위젯을 추가해야 합니다.

  4. 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

  5. 2020.01.28 09:51

    비밀댓글입니다

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2020.01.28 21:13 신고

      리눅스 환경 같은데 맞나요?

      정확한 에러 메시지가 무엇인가요?

    • 2020.03.05 15:54

      비밀댓글입니다

  6. helpme 2020.05.21 15:24

    안녕하세요.
    python openCV with pyqt5로 공부하고 중에 블로그 보고 많이 알아가고 있습니다만
    혹시 실례가 안된다면 저기서 카메라 영상을 저장을 하려면 어떻게 해야되는지 알려주실 수 있을까요??ㅠㅠ
    cv2.VideoWriter() 함수 저장하는 걸로는 저장이 안되는데 qimage는 따로 해야하나요??

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2020.05.21 15:37 신고

      opencv 방식으로 가능할텐데 이상하군요. 안된다면 qt에서 영상 저장하는 코드를 찾아보세요

+ Recent posts