Socket傳送影像

      在〈Socket傳送影像〉中尚無留言

主程式 MahalVideo.py

主程式為Server端. 是顯示影像的地方. 包含了 MahalVideo.py 及Internet.py

#!/usr/bin/python3
import sys
from PyQt5.QtGui import QPixmap, QImage
from PyQt5.QtWidgets import QMainWindow, QApplication
from Camera import Camera
from Internet import Internet
from ui.ui_mainwindow import *
class MainWindow(QMainWindow,Ui_MainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)
        self.bytesPerLine = 3 * 1920
        self.InternetThread=Internet()
        self.InternetThread.callback.connect(self.refreshWindow)
        self.InternetThread.start()
        self.btnExit.clicked.connect(self.btnExit_click)
    def refreshWindow(self, img):
        w=self.img.width()
        h=self.img.height()
        qimg = QImage(img.data, 1920, 1080, self.bytesPerLine, QImage.Format_RGB888).rgbSwapped().scaled(w, h, transformMode=QtCore.Qt.SmoothTransformation)
        self.img.setPixmap(QPixmap.fromImage(qimg))
    def btnExit_click(self):
        app.closeAllWindows()
if __name__ == "__main__":
    app = QApplication(sys.argv)
    mainwindow = MainWindow()
    #mainwindow.show()
    mainwindow.showFullScreen()
    #mainwindow.showMaximized()
    app.exec()

Internet.py

請注意, Internet.py亦為Server端程式, 其中socket bind的位址, 不能為網址, 也不能是localhost, 只能為區域網路IP

import socket

import cv2
import numpy
from PyQt5.QtCore import QThread, pyqtSignal


class Internet(QThread):
    callback = pyqtSignal(object)  # 自定義訊號, Qt的文件中有說明, 必需為類別變數
    def __init__(self, parent=None):
        super().__init__(parent)
        self.runFlag = True
    def __del__(self):
        self.runFlag = False
        cv2.destroyAllWindows()
        self.wait()
    def run(self):
        TCP_IP = "192.168.1.2"#一定只能區網
        TCP_PORT = 8002
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.bind((TCP_IP, TCP_PORT))
        s.listen(True)
        conn, addr = s.accept()
        while self.runFlag:
            length = self.recvall(conn, 16)
            stringData = self.recvall(conn, int(length))
            data = numpy.frombuffer(stringData, dtype='uint8')
            img = cv2.imdecode(data, 1)
            #cv2.imshow('SERVER', decimg)
            self.callback.emit(img)
        s.close()

    def recvall(self, sock, count):
        buf = b''
        while count:
            newbuf = sock.recv(count)
            if not newbuf: return None
            buf += newbuf
            count -= len(newbuf)
        return buf

client.py

client.py為影像傳送端(比如Respberry). TCP_IP可以為外網或網域

#!/usr/bin/python3
import socket
import cv2
import numpy

TCP_IP = "192.168.1.2"#此處可為網域或外網
TCP_PORT = 8002
sock = socket.socket()

cam = cv2.VideoCapture(0)
cam.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
cam.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)
runFlag=True
sock.connect((TCP_IP, TCP_PORT))
encode_param=[int(cv2.IMWRITE_JPEG_QUALITY),90]

while runFlag:
    ret, frame = cam.read()
    result, imgencode = cv2.imencode('.jpg', frame, encode_param)
    data = numpy.array(imgencode)
    byteData = data.tobytes()
    sock.send( str(len(byteData)).ljust(16).encode(encoding='utf_8', errors='strict'))
    sock.send(byteData);

    #decimg=cv2.imdecode(data,1)
    #cv2.imshow('CLIENT',decimg)
    #cv2.waitKey(30)

sock.close()
cv2.destroyAllWindows()

todo
參考
codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/369901/

kknews.cc/zh-tw/code/xeqkggg.html

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *