Browse Source

增加相机参数配置修改保存

zx 1 year ago
parent
commit
09ebbfd6b2
9 changed files with 392 additions and 122 deletions
  1. 85 37
      Viewer/CustomFrame.py
  2. 0 1
      Viewer/GrpcClient.py
  3. 42 6
      Viewer/MainWnd.py
  4. 63 16
      Viewer/def.proto
  5. 33 19
      Viewer/def_pb2.py
  6. 106 9
      Viewer/def_pb2.pyi
  7. 62 29
      Viewer/def_pb2_grpc.py
  8. 1 5
      Viewer/main.py
  9. 0 0
      Viewer/proto.sh

+ 85 - 37
Viewer/CustomFrame.py

@@ -1,12 +1,11 @@
 
-from PyQt5.QtWidgets import (QWidget,QVBoxLayout,QTabWidget,QSplitter, QFileDialog,QMessageBox,
+from PyQt5.QtWidgets import (QWidget,QVBoxLayout,QTabWidget,QSplitter, QFileDialog,QMessageBox,QComboBox,
                              QLineEdit,QTextEdit,QCheckBox,QLabel,QFrame,QPushButton,QMenu,QAction)
 from PyQt5.QtGui import QPixmap,QImage,QPainter,QResizeEvent,QCloseEvent,QPaintEvent
-from PyQt5.QtCore import QSize,QTimer,QRect,Qt
+from PyQt5.QtCore import QRect,Qt
 import numpy as np
 import math
 import def_pb2 as pb
-from concurrent.futures import ThreadPoolExecutor, as_completed, wait
 import GrpcClient as rpc
 import vtk
 import cv2
@@ -16,6 +15,7 @@ from vtkmodules.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
 
 import threading
 class ControlFrame(QFrame):
+    cameraMap={"相机1":1,"相机2":2,"相机3":3,"相机4":4}
     def __init__(self):
         QFrame.__init__(self)
         self.setGeometry(0, 0, 500, 500)
@@ -29,7 +29,14 @@ class ControlFrame(QFrame):
         self.images_=images
 
     def DisplayMeasureInfo(self,info : pb.MeasureInfo):
-        self.ErrorInfo.setText(info.error)
+        xstr="x\t:  %.3f\n"%(info.x) if info.HasField("x") else "x\t:  None\n"
+        ystr="y\t:  %.3f\n"%(info.y) if info.HasField("y") else "y\t:  None\n"
+        thetastr="角度\t:  %.3f\n"%(info.theta*180.0/np.pi) if info.HasField("theta") else "角度\t:  None\n"
+        widthstr="宽\t:  %.3f\n"%(info.width) if info.HasField("width") else "宽\t:  None\n"
+        wheelbasestr="轴距\t:  %.3f\n"%(info.wheelbase) if info.HasField("wheelbase") else "轴距\t:  None\n"
+        fthetastr="前轮角\t:  %.3f\n"%(info.ftheta*180.0/np.pi) if info.HasField("ftheta") else "前轮角\t:  None\n"
+        error=info.error
+        self.ErrorInfo.setText(xstr+ystr+thetastr+widthstr+wheelbasestr+fthetastr+error)
     def OnAction(self,dtype,id):
         client=rpc.GrpcStream()
         ip=self.IPEdit.text()
@@ -46,57 +53,80 @@ class ControlFrame(QFrame):
 
         self.begstatic = QLabel(self)
         self.begstatic.setText("   IP:")
-        self.begstatic.setGeometry(20, 5, 80, 30)
+        self.begstatic.setGeometry(20, 5, 80, 25)
         self.IPEdit = QLineEdit(self)
-        self.IPEdit.setText("192.168.2.55")
-        self.IPEdit.setGeometry(90, 5, 150, 30)
+        self.IPEdit.setText("10.211.31.16")
+        self.IPEdit.setGeometry(90, 5, 150, 25)
 
         self.endstatic = QLabel(self)
         self.endstatic.setText("Port:")
-        self.endstatic.setGeometry(20, 50, 80, 30)
+        self.endstatic.setGeometry(20, 35, 80, 25)
         self.PortEdit = QLineEdit(self)
         self.PortEdit.setText("9876")
-        self.PortEdit.setGeometry(90, 50, 150, 30)
+        self.PortEdit.setGeometry(90, 35, 150, 25)
+
+        self.btnImageStreamCheck = QCheckBox("实时图像", self)
+        self.btnImageStreamCheck.setGeometry(20, 65, 120, 30)
+        self.btnImageStreamCheck.clicked.connect(self.RealTimeImagecb)
+
+        self.btnDataStreamCheck = QCheckBox("实时结果打印", self)
+        self.btnDataStreamCheck.setGeometry(150, 65, 120, 30)
+        self.btnDataStreamCheck.clicked.connect(self.RealTimeDatacb)
 
         self.btnGrab = QPushButton(self)
-        self.btnGrab.setGeometry(20, 140, 100, 40)
+        self.btnGrab.setGeometry(20, 100, 100, 40)
         self.btnGrab.setText("抓取图像")
         self.btnGrab.clicked.connect(self.btnGrabImageClick)
 
         self.btnCancel = QPushButton(self)
-        self.btnCancel.setGeometry(150, 140, 100, 40)
+        self.btnCancel.setGeometry(150, 100, 100, 30)
         self.btnCancel.setText("抓取点云")
         self.btnCancel.clicked.connect(self.btnGrabCloudClick)
 
         self.btnMergeSave = QPushButton(self)
-        self.btnMergeSave.setGeometry(20, 200, 100, 40)
+        self.btnMergeSave.setGeometry(20, 160, 100, 40)
         self.btnMergeSave.setText("拼接保存")
         self.btnMergeSave.clicked.connect(self.btnMergeSaveClick)
 
         self.btnSaveAllCloud = QPushButton(self)
-        self.btnSaveAllCloud.setGeometry(150, 200, 100, 40)
-        self.btnSaveAllCloud.setText("保存allPoints")
+        self.btnSaveAllCloud.setGeometry(150, 135, 100, 30)
+        self.btnSaveAllCloud.setText("合并保存点云")
 
-        self.btnImageStreamCheck = QCheckBox("实时图像", self)
-        self.btnImageStreamCheck.setGeometry(20, 90, 120, 40)
-        self.btnImageStreamCheck.clicked.connect(self.RealTimeImagecb)
-
-        self.btnDataStreamCheck = QCheckBox("实时结果打印", self)
-        self.btnDataStreamCheck.setGeometry(150, 90, 120, 40)
-        self.btnDataStreamCheck.clicked.connect(self.RealTimeDatacb)
+        self.btnSaveWheelSampleCloud = QPushButton(self)
+        self.btnSaveWheelSampleCloud.setGeometry(150, 170, 100, 30)
+        self.btnSaveWheelSampleCloud.setText("保存轮胎样本")
 
         self.MatrixEdit = QTextEdit(self)
         self.MatrixEdit.setText("输入4x4变换矩阵")
-        self.MatrixEdit.setGeometry(20, 250, 500, 100)
+        self.MatrixEdit.setGeometry(20, 205, 500, 90)
         #self.MatrixEdit.setLineWrapMode()
         self.MatrixEdit.setAlignment(Qt.AlignTop)
         self.btnMatrix = QPushButton(self)
-        self.btnMatrix.setGeometry(20, 360, 100, 40)
-        self.btnMatrix.setText("转换rpy")
+        self.btnMatrix.setGeometry(20, 300, 100, 30)
+        self.btnMatrix.setText("转换rpy,xyz")
         self.btnMatrix.clicked.connect(self.matrix2rpy)
 
+        self.ParameterEdit = QTextEdit(self)
+        self.ParameterEdit.setText("")
+        self.ParameterEdit.setGeometry(20, 340, 130, 150)
+
+        self.CameraListEdit=QComboBox(self)
+        self.CameraListEdit.addItems(self.cameraMap.keys())
+        self.CameraListEdit.setGeometry(155, 340, 100, 30)
+
+
+        self.btnChange = QPushButton(self)
+        self.btnChange.setGeometry(155, 390, 100, 40)
+        self.btnChange.setText("修改参数")
+        self.btnChange.clicked.connect(self.ChangeCameraParameter)
+
+        self.btnSave = QPushButton(self)
+        self.btnSave.setGeometry(155, 450, 100, 40)
+        self.btnSave.setText("写入参数")
+        self.btnSave.clicked.connect(self.SaveCameraParameter)
+
         self.ErrorInfo = QLabel(self)
-        self.ErrorInfo.setGeometry(20, 450, 250, 400)
+        self.ErrorInfo.setGeometry(20, 495, 250, 400)
         self.ErrorInfo.setWordWrap(True)
         self.ErrorInfo.setAlignment(Qt.AlignTop)
 
@@ -150,7 +180,7 @@ class ControlFrame(QFrame):
             ip=self.IPEdit.text()
             port=int(self.PortEdit.text())
             try:
-                client.GrabImage(ip,port,0)
+                client.GrabImage(ip,port,-1)
             except Exception as e:
                 QMessageBox.information(self, 'ERROR',str(e),QMessageBox.Ok,QMessageBox.Ok)
 
@@ -166,7 +196,7 @@ class ControlFrame(QFrame):
             img_down=np.concatenate([img3,img4],axis=1)
             image=np.concatenate([img_up,img_down],axis=0)
 
-            file=time.strftime("%Y%m%d-%H%M%S")+'.png'
+            file=time.strftime("%Y%m%d-%H%M%S")+'.jpg'
             cv2.imwrite("./images/"+file,image)
         else:
             print("  ---------------")
@@ -189,7 +219,7 @@ class ControlFrame(QFrame):
         port=int(self.PortEdit.text())
         try:
             for id in range(4):
-                client.GrabCloud(ip,port,id+1)
+                client.GrabCloud(ip,port,id)
         except Exception as e:
             QMessageBox.information(self, 'ERROR',str(e),QMessageBox.Ok,QMessageBox.Ok)
     def rotationMatrixToEulerAngles(self,R) :
@@ -205,28 +235,41 @@ class ControlFrame(QFrame):
             y = math.atan2(-R[2,0], sy)
             z = 0
         return np.array([x, y, z])
+    def SaveCameraParameter(self):
+        camera=self.CameraListEdit.currentText()
+        id=self.cameraMap[camera]
+        text=self.ParameterEdit.toPlainText()
+
+        print(" 保存相机%d参数:%s"%(id,text))
+    def ChangeCameraParameter(self):
+        camera=self.CameraListEdit.currentText()
+        id=self.cameraMap[camera]
+        text=self.ParameterEdit.toPlainText()
+
+        print(" 修改相机%d参数:%s"%(id,text))
     def matrix2rpy(self):
         text=""
         str=self.MatrixEdit.toPlainText()
         nums=str.split('\n')
         if not len(nums)==4:
-            text="Data format Error"
+            text="变换矩阵格式错误  需要4x4矩阵"
         else:
             matrix=np.zeros(shape=[4,4],dtype=np.float32)
             count=0
             for line in nums:
                 datas=line.split(' ')
                 if not len(datas)==4:
-                    text="Data format Error"
+                    text="变换矩阵格式错误  需要4x4矩阵"
                     break
                 else:
                     matrix[count,:]=[float(datas[0]),float(datas[1]),float(datas[2]),float(datas[3])]
                 count+=1
 
             rpy=self.rotationMatrixToEulerAngles(matrix)
-            text="rpy : %.3f  %.3f  %.3f\nxyz : %.3f  %.3f  %.3f"%(math.degrees(rpy[0]),math.degrees(rpy[1]),math.degrees(rpy[2]),
+            text="\"roll\" : %.3f,\n\"pitch\": %.3f,\n\"yaw\": %.3f,\n\"x\":%.3f,\n\"y\":%.3f,\n\"z\":%.3f,"%(math.degrees(rpy[0]),math.degrees(rpy[1]),math.degrees(rpy[2]),
                                             matrix[0,3],matrix[1,3],matrix[2,3])
-        QMessageBox.information(self, '旋转变换转rpy-t',text,QMessageBox.Ok,QMessageBox.Ok)
+        self.ParameterEdit.setText(text)
+        #QMessageBox.information(self, '旋转变换转rpy-t',text,QMessageBox.Ok,QMessageBox.Ok)
     def btnCancelClick(self):
         pass
 class ImageViewer(QLabel):
@@ -245,8 +288,8 @@ class ImageViewer(QLabel):
         self.update()
 
     def updataData(self):
-        self.OnAction(self.dtype,self.id)
-        print("%d,%d"%(self.dtype,self.id))
+        self.OnAction(self.dtype,self.id-1)
+        print("%d,%d"%(self.dtype,self.id-1))
 
     def contextMenuEvent(self, a0):
         menu=QMenu(self)
@@ -358,10 +401,13 @@ class VtkPointCloudCanvas(QWidget):
             if type==1:
                 if prob>0.9:
                     self._point_cloud.addPoint(point)
-                    colors.InsertNextTypedTuple((int(255*prob),int(255-prob*255),255-int(prob*255)))
+                    colors.InsertNextTypedTuple((0,255,0))
             else:
                 self._point_cloud.addPoint(point)
-                colors.InsertNextTypedTuple((int(255*prob),int(255-prob*255),255-int(prob*255)))
+                if prob>0.9:
+                    colors.InsertNextTypedTuple((0,255,0))
+                else:
+                    colors.InsertNextTypedTuple((255,0,0))
         self._point_cloud.vtkPolyData.GetPointData().SetScalars(colors)
         self._vtk_widget.update()
     def resetViewer(self):
@@ -406,7 +452,7 @@ class PointCLViwer(QSplitter):
     def resetViewer(self):
         self.pclViewer.resetViewer()
     def updataData(self):
-        self.OnAction(self.dtype,self.id)
+        self.OnAction(self.dtype,self.id-1)
     def displayWheelPoints(self):
         self.pclViewer.displayPCL(self.pointCloud,1)
     def displayAllPoints(self):
@@ -498,6 +544,8 @@ class ViewerFrame(QFrame):
         if c==1:
             npdata = npdata.reshape([h,w])
             qimg=QImage(npdata.data,w,h,QImage.Format_Grayscale8)
+
+
         pix=QPixmap(qimg)
         return pix
     def PbCloud2Pts(self,cloud:pb.PointCloud):

+ 0 - 1
Viewer/GrpcClient.py

@@ -1,5 +1,4 @@
 import time
-from PyQt5.QtWidgets import QMessageBox
 import grpc
 import def_pb2 as pb
 import def_pb2_grpc as mrpc

+ 42 - 6
Viewer/MainWnd.py

@@ -1,12 +1,9 @@
 
-import math
-import time
-import sys
 from PyQt5.QtGui import *
 from PyQt5.QtWidgets import *
-from PyQt5.QtCore import *
 from CustomFrame import *
-
+import os
+import datetime
 
 class MainWindow(QMainWindow):
     """docstring for Mainwindow"""
@@ -17,12 +14,15 @@ class MainWindow(QMainWindow):
         self.Controller = ControlFrame()
         self.viewerFrame = ViewerFrame(self.Controller.OnAction)
         self.Controller.btnSaveAllCloud.clicked.connect(self.saveAllCloud)
+        self.Controller.btnSaveWheelSampleCloud.clicked.connect(self.saveWheelSampleCloud)
 
         splitter= self.split_()
         self.setCentralWidget(splitter)
     def saveAllCloud(self):
         fileName2, ok2 = QFileDialog.getSaveFileName(self, "文件保存", "C:/","All Files (*);;Text Files (*.txt)")
-        print(fileName2 ,ok2)
+        if fileName2=="":
+            return
+
         with open(fileName2,"w+") as f:
             for point in self.viewerFrame.pcViewer1.pointCloud:
                 prob=point[3]
@@ -37,6 +37,42 @@ class MainWindow(QMainWindow):
                 prob=point[3]
                 f.write("%f %f %f %d %d %d\n"%(point[0],point[1],point[2],int(255*prob),int(255-prob*255),255-int(prob*255)))
     #窗口基础属性
+    def saveWheelSampleCloud(self):
+        print(" save wheel sample")
+        path="./wheelSamples"
+        folder=os.path.exists(path)
+        if not folder:
+            os.mkdir(path)
+
+        str=datetime.datetime.now().strftime("%Y-%m-%d_%H:%M:%S")
+        sampleFolder=path+"/"+str
+        folder2=os.path.exists(sampleFolder)
+        if not folder2:
+            os.mkdir(sampleFolder)
+
+        with open(sampleFolder+"/1.txt","w+") as f:
+            for point in self.viewerFrame.pcViewer1.pointCloud:
+                prob=point[3]
+                if prob>0.8:
+                    f.write("%f %f %f\n"%(point[0],point[1],point[2]))
+        with open(sampleFolder+"/2.txt","w+") as f:
+            for point in self.viewerFrame.pcViewer2.pointCloud:
+                prob=point[3]
+                if prob>0.8:
+                    f.write("%f %f %f\n"%(point[0],point[1],point[2]))
+        with open(sampleFolder+"/3.txt","w+") as f:
+            for point in self.viewerFrame.pcViewer3.pointCloud:
+                prob=point[3]
+                if prob>0.8:
+                    f.write("%f %f %f\n"%(point[0],point[1],point[2]))
+        with open(sampleFolder+"/4.txt","w+") as f:
+            for point in self.viewerFrame.pcViewer4.pointCloud:
+                prob=point[3]
+                if prob>0.8:
+                    f.write("%f %f %f\n"%(point[0],point[1],point[2]))
+        text="样本已保存到:%s 文件夹下"%(sampleFolder)
+        QMessageBox.information(self, '保存轮胎样本',text,QMessageBox.Ok,QMessageBox.Ok)
+
     def basic(self):
         #设置标题,大小,图标
         self.setWindowTitle("RPC3DView")

+ 63 - 16
Viewer/def.proto

@@ -1,12 +1,20 @@
 syntax = "proto3";
 package JetStream;
 
+message CoordinateTransformation3D {
+  optional float x = 1;
+  optional float y = 2 ;
+  optional float z = 3 ;
+  optional float roll = 4 ;
+  optional float pitch = 5;
+  optional float yaw = 6 ;
+}
+
 message RequestCmd
 {
   int32 Id=1;  // 对于获取对应id的相机数据。1,2,3,4,其他表示所有
-  //对于打开视频流
+  optional CoordinateTransformation3D params = 2;
 }
-
 message Response{
   string info=2;
 }
@@ -15,14 +23,33 @@ message Image{
   int32 width=1;
   int32 height=2;
   int32 channel=3;
-  bytes data=4;
+  bool encode = 4;
+  bytes data= 5;
 }
-
 message PointCloud{
   int32 size=1;
   bytes data=2;
 }
-
+message LabelImage{
+  int32 label=1;
+  Image ir=2;
+}
+message Line{
+  int32 begin=1;
+  int32 end=2;
+}
+message SegBox{
+  int32 x = 1;
+  int32 y = 2;
+  int32 width = 3;
+  int32 height = 4;
+  float confidence = 5;
+  repeated Line lines= 6;
+}
+message LabelYolo{
+  int32 label=1;
+  repeated SegBox boxes=2;
+}
 message ResImage{
   Image img1=1;
   Image img2=2;
@@ -36,28 +63,48 @@ message ResCloud{
   PointCloud cloud4=4;
 }
 message MeasureInfo {
-  float x=1;
-  float y=2;
-  float theta=3;
-  float width=4;
-  float wheelbase=5;
-  float ftheta=6;
-  int32 border=7;
-  string error=8;
+  optional float x=1;
+  optional float y=2;
+  optional float trans_x=3;
+  optional float trans_y=4;
+  optional float theta=5;
+  optional float width=6;
+  optional float wheelbase=7;
+  optional float ftheta=8;
+  // 超界说明,此参数没有表示正常。
+  // 1:超宽,2:轴距超长,
+  // 3:前超界,4:后超界,5:左,6:右,7:左倾角过大,8:右倾角过大,9:前轮角过大
+  optional int32 border_plc=9;
+  optional int32 border_display=10;
+  optional string error=11;
 }
 message ResFrame{
   ResImage images=1;
   ResCloud clouds=2;
-
   MeasureInfo measure_info=3;
 }
-
 service StreamServer{
   rpc OpenImageStream(RequestCmd) returns(stream ResImage){}
   rpc OpenMeasureDataStream(RequestCmd) returns(stream MeasureInfo){}
-  rpc Detect(RequestCmd) returns(ResFrame){}
   rpc CloseImageStream(RequestCmd) returns(Response){}
   rpc CloseMeasureDataStream(RequestCmd) returns(Response){}
   rpc GetCloud(RequestCmd) returns(ResCloud){}
   rpc GetImage(RequestCmd) returns(ResImage){}
+  rpc setTofTransformation(RequestCmd) returns(Response){}
+  rpc saveTofTransformation(RequestCmd) returns(Response){}
+}
+message Boundary{
+  float radius=1; //转台半径
+  float left=2;
+  float right=3;
+  float buttom=4;
+  float minAngle=5;
+  float maxAngle=6;
+  float fwheelAngle=7;
 }
+message Limit{
+  Boundary plc_limit=1;
+  Boundary display_limit=2;
+  float maxWidth=3;
+  float maxWheelBase=4;
+}

File diff suppressed because it is too large
+ 33 - 19
Viewer/def_pb2.py


+ 106 - 9
Viewer/def_pb2.pyi

@@ -1,14 +1,33 @@
+from google.protobuf.internal import containers as _containers
 from google.protobuf import descriptor as _descriptor
 from google.protobuf import message as _message
-from typing import ClassVar as _ClassVar, Mapping as _Mapping, Optional as _Optional, Union as _Union
+from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union
 
 DESCRIPTOR: _descriptor.FileDescriptor
 
+class CoordinateTransformation3D(_message.Message):
+    __slots__ = ["x", "y", "z", "roll", "pitch", "yaw"]
+    X_FIELD_NUMBER: _ClassVar[int]
+    Y_FIELD_NUMBER: _ClassVar[int]
+    Z_FIELD_NUMBER: _ClassVar[int]
+    ROLL_FIELD_NUMBER: _ClassVar[int]
+    PITCH_FIELD_NUMBER: _ClassVar[int]
+    YAW_FIELD_NUMBER: _ClassVar[int]
+    x: float
+    y: float
+    z: float
+    roll: float
+    pitch: float
+    yaw: float
+    def __init__(self, x: _Optional[float] = ..., y: _Optional[float] = ..., z: _Optional[float] = ..., roll: _Optional[float] = ..., pitch: _Optional[float] = ..., yaw: _Optional[float] = ...) -> None: ...
+
 class RequestCmd(_message.Message):
-    __slots__ = ["Id"]
+    __slots__ = ["Id", "params"]
     ID_FIELD_NUMBER: _ClassVar[int]
+    PARAMS_FIELD_NUMBER: _ClassVar[int]
     Id: int
-    def __init__(self, Id: _Optional[int] = ...) -> None: ...
+    params: CoordinateTransformation3D
+    def __init__(self, Id: _Optional[int] = ..., params: _Optional[_Union[CoordinateTransformation3D, _Mapping]] = ...) -> None: ...
 
 class Response(_message.Message):
     __slots__ = ["info"]
@@ -17,16 +36,18 @@ class Response(_message.Message):
     def __init__(self, info: _Optional[str] = ...) -> None: ...
 
 class Image(_message.Message):
-    __slots__ = ["width", "height", "channel", "data"]
+    __slots__ = ["width", "height", "channel", "encode", "data"]
     WIDTH_FIELD_NUMBER: _ClassVar[int]
     HEIGHT_FIELD_NUMBER: _ClassVar[int]
     CHANNEL_FIELD_NUMBER: _ClassVar[int]
+    ENCODE_FIELD_NUMBER: _ClassVar[int]
     DATA_FIELD_NUMBER: _ClassVar[int]
     width: int
     height: int
     channel: int
+    encode: bool
     data: bytes
-    def __init__(self, width: _Optional[int] = ..., height: _Optional[int] = ..., channel: _Optional[int] = ..., data: _Optional[bytes] = ...) -> None: ...
+    def __init__(self, width: _Optional[int] = ..., height: _Optional[int] = ..., channel: _Optional[int] = ..., encode: bool = ..., data: _Optional[bytes] = ...) -> None: ...
 
 class PointCloud(_message.Message):
     __slots__ = ["size", "data"]
@@ -36,6 +57,46 @@ class PointCloud(_message.Message):
     data: bytes
     def __init__(self, size: _Optional[int] = ..., data: _Optional[bytes] = ...) -> None: ...
 
+class LabelImage(_message.Message):
+    __slots__ = ["label", "ir"]
+    LABEL_FIELD_NUMBER: _ClassVar[int]
+    IR_FIELD_NUMBER: _ClassVar[int]
+    label: int
+    ir: Image
+    def __init__(self, label: _Optional[int] = ..., ir: _Optional[_Union[Image, _Mapping]] = ...) -> None: ...
+
+class Line(_message.Message):
+    __slots__ = ["begin", "end"]
+    BEGIN_FIELD_NUMBER: _ClassVar[int]
+    END_FIELD_NUMBER: _ClassVar[int]
+    begin: int
+    end: int
+    def __init__(self, begin: _Optional[int] = ..., end: _Optional[int] = ...) -> None: ...
+
+class SegBox(_message.Message):
+    __slots__ = ["x", "y", "width", "height", "confidence", "lines"]
+    X_FIELD_NUMBER: _ClassVar[int]
+    Y_FIELD_NUMBER: _ClassVar[int]
+    WIDTH_FIELD_NUMBER: _ClassVar[int]
+    HEIGHT_FIELD_NUMBER: _ClassVar[int]
+    CONFIDENCE_FIELD_NUMBER: _ClassVar[int]
+    LINES_FIELD_NUMBER: _ClassVar[int]
+    x: int
+    y: int
+    width: int
+    height: int
+    confidence: float
+    lines: _containers.RepeatedCompositeFieldContainer[Line]
+    def __init__(self, x: _Optional[int] = ..., y: _Optional[int] = ..., width: _Optional[int] = ..., height: _Optional[int] = ..., confidence: _Optional[float] = ..., lines: _Optional[_Iterable[_Union[Line, _Mapping]]] = ...) -> None: ...
+
+class LabelYolo(_message.Message):
+    __slots__ = ["label", "boxes"]
+    LABEL_FIELD_NUMBER: _ClassVar[int]
+    BOXES_FIELD_NUMBER: _ClassVar[int]
+    label: int
+    boxes: _containers.RepeatedCompositeFieldContainer[SegBox]
+    def __init__(self, label: _Optional[int] = ..., boxes: _Optional[_Iterable[_Union[SegBox, _Mapping]]] = ...) -> None: ...
+
 class ResImage(_message.Message):
     __slots__ = ["img1", "img2", "img3", "img4"]
     IMG1_FIELD_NUMBER: _ClassVar[int]
@@ -61,24 +122,30 @@ class ResCloud(_message.Message):
     def __init__(self, cloud1: _Optional[_Union[PointCloud, _Mapping]] = ..., cloud2: _Optional[_Union[PointCloud, _Mapping]] = ..., cloud3: _Optional[_Union[PointCloud, _Mapping]] = ..., cloud4: _Optional[_Union[PointCloud, _Mapping]] = ...) -> None: ...
 
 class MeasureInfo(_message.Message):
-    __slots__ = ["x", "y", "theta", "width", "wheelbase", "ftheta", "border", "error"]
+    __slots__ = ["x", "y", "trans_x", "trans_y", "theta", "width", "wheelbase", "ftheta", "border_plc", "border_display", "error"]
     X_FIELD_NUMBER: _ClassVar[int]
     Y_FIELD_NUMBER: _ClassVar[int]
+    TRANS_X_FIELD_NUMBER: _ClassVar[int]
+    TRANS_Y_FIELD_NUMBER: _ClassVar[int]
     THETA_FIELD_NUMBER: _ClassVar[int]
     WIDTH_FIELD_NUMBER: _ClassVar[int]
     WHEELBASE_FIELD_NUMBER: _ClassVar[int]
     FTHETA_FIELD_NUMBER: _ClassVar[int]
-    BORDER_FIELD_NUMBER: _ClassVar[int]
+    BORDER_PLC_FIELD_NUMBER: _ClassVar[int]
+    BORDER_DISPLAY_FIELD_NUMBER: _ClassVar[int]
     ERROR_FIELD_NUMBER: _ClassVar[int]
     x: float
     y: float
+    trans_x: float
+    trans_y: float
     theta: float
     width: float
     wheelbase: float
     ftheta: float
-    border: int
+    border_plc: int
+    border_display: int
     error: str
-    def __init__(self, x: _Optional[float] = ..., y: _Optional[float] = ..., theta: _Optional[float] = ..., width: _Optional[float] = ..., wheelbase: _Optional[float] = ..., ftheta: _Optional[float] = ..., border: _Optional[int] = ..., error: _Optional[str] = ...) -> None: ...
+    def __init__(self, x: _Optional[float] = ..., y: _Optional[float] = ..., trans_x: _Optional[float] = ..., trans_y: _Optional[float] = ..., theta: _Optional[float] = ..., width: _Optional[float] = ..., wheelbase: _Optional[float] = ..., ftheta: _Optional[float] = ..., border_plc: _Optional[int] = ..., border_display: _Optional[int] = ..., error: _Optional[str] = ...) -> None: ...
 
 class ResFrame(_message.Message):
     __slots__ = ["images", "clouds", "measure_info"]
@@ -89,3 +156,33 @@ class ResFrame(_message.Message):
     clouds: ResCloud
     measure_info: MeasureInfo
     def __init__(self, images: _Optional[_Union[ResImage, _Mapping]] = ..., clouds: _Optional[_Union[ResCloud, _Mapping]] = ..., measure_info: _Optional[_Union[MeasureInfo, _Mapping]] = ...) -> None: ...
+
+class Boundary(_message.Message):
+    __slots__ = ["radius", "left", "right", "buttom", "minAngle", "maxAngle", "fwheelAngle"]
+    RADIUS_FIELD_NUMBER: _ClassVar[int]
+    LEFT_FIELD_NUMBER: _ClassVar[int]
+    RIGHT_FIELD_NUMBER: _ClassVar[int]
+    BUTTOM_FIELD_NUMBER: _ClassVar[int]
+    MINANGLE_FIELD_NUMBER: _ClassVar[int]
+    MAXANGLE_FIELD_NUMBER: _ClassVar[int]
+    FWHEELANGLE_FIELD_NUMBER: _ClassVar[int]
+    radius: float
+    left: float
+    right: float
+    buttom: float
+    minAngle: float
+    maxAngle: float
+    fwheelAngle: float
+    def __init__(self, radius: _Optional[float] = ..., left: _Optional[float] = ..., right: _Optional[float] = ..., buttom: _Optional[float] = ..., minAngle: _Optional[float] = ..., maxAngle: _Optional[float] = ..., fwheelAngle: _Optional[float] = ...) -> None: ...
+
+class Limit(_message.Message):
+    __slots__ = ["plc_limit", "display_limit", "maxWidth", "maxWheelBase"]
+    PLC_LIMIT_FIELD_NUMBER: _ClassVar[int]
+    DISPLAY_LIMIT_FIELD_NUMBER: _ClassVar[int]
+    MAXWIDTH_FIELD_NUMBER: _ClassVar[int]
+    MAXWHEELBASE_FIELD_NUMBER: _ClassVar[int]
+    plc_limit: Boundary
+    display_limit: Boundary
+    maxWidth: float
+    maxWheelBase: float
+    def __init__(self, plc_limit: _Optional[_Union[Boundary, _Mapping]] = ..., display_limit: _Optional[_Union[Boundary, _Mapping]] = ..., maxWidth: _Optional[float] = ..., maxWheelBase: _Optional[float] = ...) -> None: ...

+ 62 - 29
Viewer/def_pb2_grpc.py

@@ -24,11 +24,6 @@ class StreamServerStub(object):
                 request_serializer=def__pb2.RequestCmd.SerializeToString,
                 response_deserializer=def__pb2.MeasureInfo.FromString,
                 )
-        self.Detect = channel.unary_unary(
-                '/JetStream.StreamServer/Detect',
-                request_serializer=def__pb2.RequestCmd.SerializeToString,
-                response_deserializer=def__pb2.ResFrame.FromString,
-                )
         self.CloseImageStream = channel.unary_unary(
                 '/JetStream.StreamServer/CloseImageStream',
                 request_serializer=def__pb2.RequestCmd.SerializeToString,
@@ -49,6 +44,16 @@ class StreamServerStub(object):
                 request_serializer=def__pb2.RequestCmd.SerializeToString,
                 response_deserializer=def__pb2.ResImage.FromString,
                 )
+        self.setTofTransformation = channel.unary_unary(
+                '/JetStream.StreamServer/setTofTransformation',
+                request_serializer=def__pb2.RequestCmd.SerializeToString,
+                response_deserializer=def__pb2.Response.FromString,
+                )
+        self.saveTofTransformation = channel.unary_unary(
+                '/JetStream.StreamServer/saveTofTransformation',
+                request_serializer=def__pb2.RequestCmd.SerializeToString,
+                response_deserializer=def__pb2.Response.FromString,
+                )
 
 
 class StreamServerServicer(object):
@@ -66,31 +71,37 @@ class StreamServerServicer(object):
         context.set_details('Method not implemented!')
         raise NotImplementedError('Method not implemented!')
 
-    def Detect(self, request, context):
+    def CloseImageStream(self, request, context):
         """Missing associated documentation comment in .proto file."""
         context.set_code(grpc.StatusCode.UNIMPLEMENTED)
         context.set_details('Method not implemented!')
         raise NotImplementedError('Method not implemented!')
 
-    def CloseImageStream(self, request, context):
+    def CloseMeasureDataStream(self, request, context):
         """Missing associated documentation comment in .proto file."""
         context.set_code(grpc.StatusCode.UNIMPLEMENTED)
         context.set_details('Method not implemented!')
         raise NotImplementedError('Method not implemented!')
 
-    def CloseMeasureDataStream(self, request, context):
+    def GetCloud(self, request, context):
         """Missing associated documentation comment in .proto file."""
         context.set_code(grpc.StatusCode.UNIMPLEMENTED)
         context.set_details('Method not implemented!')
         raise NotImplementedError('Method not implemented!')
 
-    def GetCloud(self, request, context):
+    def GetImage(self, request, context):
         """Missing associated documentation comment in .proto file."""
         context.set_code(grpc.StatusCode.UNIMPLEMENTED)
         context.set_details('Method not implemented!')
         raise NotImplementedError('Method not implemented!')
 
-    def GetImage(self, request, context):
+    def setTofTransformation(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def saveTofTransformation(self, request, context):
         """Missing associated documentation comment in .proto file."""
         context.set_code(grpc.StatusCode.UNIMPLEMENTED)
         context.set_details('Method not implemented!')
@@ -109,11 +120,6 @@ def add_StreamServerServicer_to_server(servicer, server):
                     request_deserializer=def__pb2.RequestCmd.FromString,
                     response_serializer=def__pb2.MeasureInfo.SerializeToString,
             ),
-            'Detect': grpc.unary_unary_rpc_method_handler(
-                    servicer.Detect,
-                    request_deserializer=def__pb2.RequestCmd.FromString,
-                    response_serializer=def__pb2.ResFrame.SerializeToString,
-            ),
             'CloseImageStream': grpc.unary_unary_rpc_method_handler(
                     servicer.CloseImageStream,
                     request_deserializer=def__pb2.RequestCmd.FromString,
@@ -134,6 +140,16 @@ def add_StreamServerServicer_to_server(servicer, server):
                     request_deserializer=def__pb2.RequestCmd.FromString,
                     response_serializer=def__pb2.ResImage.SerializeToString,
             ),
+            'setTofTransformation': grpc.unary_unary_rpc_method_handler(
+                    servicer.setTofTransformation,
+                    request_deserializer=def__pb2.RequestCmd.FromString,
+                    response_serializer=def__pb2.Response.SerializeToString,
+            ),
+            'saveTofTransformation': grpc.unary_unary_rpc_method_handler(
+                    servicer.saveTofTransformation,
+                    request_deserializer=def__pb2.RequestCmd.FromString,
+                    response_serializer=def__pb2.Response.SerializeToString,
+            ),
     }
     generic_handler = grpc.method_handlers_generic_handler(
             'JetStream.StreamServer', rpc_method_handlers)
@@ -179,7 +195,7 @@ class StreamServer(object):
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
 
     @staticmethod
-    def Detect(request,
+    def CloseImageStream(request,
             target,
             options=(),
             channel_credentials=None,
@@ -189,14 +205,14 @@ class StreamServer(object):
             wait_for_ready=None,
             timeout=None,
             metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/JetStream.StreamServer/Detect',
+        return grpc.experimental.unary_unary(request, target, '/JetStream.StreamServer/CloseImageStream',
             def__pb2.RequestCmd.SerializeToString,
-            def__pb2.ResFrame.FromString,
+            def__pb2.Response.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
 
     @staticmethod
-    def CloseImageStream(request,
+    def CloseMeasureDataStream(request,
             target,
             options=(),
             channel_credentials=None,
@@ -206,14 +222,14 @@ class StreamServer(object):
             wait_for_ready=None,
             timeout=None,
             metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/JetStream.StreamServer/CloseImageStream',
+        return grpc.experimental.unary_unary(request, target, '/JetStream.StreamServer/CloseMeasureDataStream',
             def__pb2.RequestCmd.SerializeToString,
             def__pb2.Response.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
 
     @staticmethod
-    def CloseMeasureDataStream(request,
+    def GetCloud(request,
             target,
             options=(),
             channel_credentials=None,
@@ -223,14 +239,14 @@ class StreamServer(object):
             wait_for_ready=None,
             timeout=None,
             metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/JetStream.StreamServer/CloseMeasureDataStream',
+        return grpc.experimental.unary_unary(request, target, '/JetStream.StreamServer/GetCloud',
             def__pb2.RequestCmd.SerializeToString,
-            def__pb2.Response.FromString,
+            def__pb2.ResCloud.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
 
     @staticmethod
-    def GetCloud(request,
+    def GetImage(request,
             target,
             options=(),
             channel_credentials=None,
@@ -240,14 +256,14 @@ class StreamServer(object):
             wait_for_ready=None,
             timeout=None,
             metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/JetStream.StreamServer/GetCloud',
+        return grpc.experimental.unary_unary(request, target, '/JetStream.StreamServer/GetImage',
             def__pb2.RequestCmd.SerializeToString,
-            def__pb2.ResCloud.FromString,
+            def__pb2.ResImage.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
 
     @staticmethod
-    def GetImage(request,
+    def setTofTransformation(request,
             target,
             options=(),
             channel_credentials=None,
@@ -257,8 +273,25 @@ class StreamServer(object):
             wait_for_ready=None,
             timeout=None,
             metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/JetStream.StreamServer/GetImage',
+        return grpc.experimental.unary_unary(request, target, '/JetStream.StreamServer/setTofTransformation',
             def__pb2.RequestCmd.SerializeToString,
-            def__pb2.ResImage.FromString,
+            def__pb2.Response.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def saveTofTransformation(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/JetStream.StreamServer/saveTofTransformation',
+            def__pb2.RequestCmd.SerializeToString,
+            def__pb2.Response.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)

+ 1 - 5
Viewer/main.py

@@ -1,13 +1,9 @@
 
 import sys
-from PyQt5.QtWidgets import QWidget, QApplication,QMainWindow,QLabel
-from PyQt5.QtCore import Qt
+from PyQt5.QtWidgets import  QApplication
 import MainWnd as mw
 import GrpcClient as Stream
 
-ip='192.168.2.45'
-port=9876
-
 if __name__=="__main__":
 
     app = QApplication(sys.argv)

+ 0 - 0
Viewer/proto.sh