import sys import platform from PySide6.QtWidgets import QApplication, QMainWindow, QLabel from PySide6.QtCore import Qt from PySide6.QtGui import QImage, QPixmap from PySide6.QtCore import QTimer import numpy as np import ctypes from lib.camera.mvsdk import * from lib.camera import mvsdk class MindVisionCamera: def __init__(self, sn): self.sn = sn # 相机序列号 self.hCamera = None # 相机句柄 self.FrameBufferSize = None # 帧缓冲区大小 self.pFrameBuffer = None # 帧缓冲区指针 self.monoCamera = None # 是否为单色相机标志 self.cap = None # 相机能力参数 # Initialize camera self._initialize_camera() def _initialize_camera(self): # Enumerate cameras DevList = CameraEnumerateDevice() nDev = len(DevList) if nDev < 1: print("No camera was found!") return for i, DevInfo in enumerate(DevList): # 检索指定sn相机 if DevInfo.GetSn() == self.sn: print(f"Found camera with SN: {self.sn}") break else: print(f"Camera with SN: {self.sn} not found!") return # Open camera try: self.hCamera = CameraInit(DevInfo, -1, -1) except CameraException as e: print("CameraInit Failed({}): {}".format(e.error_code, e.message)) return # 获取相机参数 self.cap = CameraGetCapability(self.hCamera) # 判断是否为单色相机 self.monoCamera = self.cap.sIspCapacity.bMonoSensor != 0 if self.monoCamera: CameraSetIspOutFormat(self.hCamera, CAMERA_MEDIA_TYPE_MONO8) CameraSetTriggerMode(self.hCamera, 0) # 设置触发模式为连续采集 CameraSetAeState(self.hCamera, 1) # 关闭自动曝光 # CameraSetExposureTime(self.hCamera, 30 * 1000) # 设置曝光时间为30ms CameraPlay(self.hCamera) # 开始采集 # 分配帧缓冲区 self.FrameBufferSize = ( self.cap.sResolutionRange.iWidthMax * self.cap.sResolutionRange.iHeightMax * (1 if self.monoCamera else 3) ) self.pFrameBuffer = CameraAlignMalloc(self.FrameBufferSize, 16) def capture(self): try: # 从相机获取图像数据,2000ms超时,返回原始数据指针和帧头信息 pRawData, FrameHead = CameraGetImageBuffer(self.hCamera, 2000) CameraImageProcess(self.hCamera, pRawData, self.pFrameBuffer, FrameHead) # 反转 if platform.system() == "Windows": mvsdk.CameraFlipFrameBuffer(self.pFrameBuffer, FrameHead, 1) # 此时图片已经存储在pFrameBuffer中, 对于彩色相机pFrameBuffer=RGB数据, 黑白相机pFrameBuffer=8位灰度数据 # 将图像数据转换为OpenCV格式 image_array = (mvsdk.c_ubyte * FrameHead.uBytes).from_address( self.pFrameBuffer ) if self.monoCamera: image_np = np.array(image_array).reshape( FrameHead.iHeight, FrameHead.iWidth ) else: image_np = np.array(image_array).reshape( FrameHead.iHeight, FrameHead.iWidth, 3 ) # Convert to OpenCV format if FrameHead.uiMediaType == CAMERA_MEDIA_TYPE_MONO8: image = np.frombuffer(image_np, dtype=np.uint8).reshape( FrameHead.iHeight, FrameHead.iWidth ) else: image = np.frombuffer(image_np, dtype=np.uint8).reshape( FrameHead.iHeight, FrameHead.iWidth, 3 ) CameraReleaseImageBuffer(self.hCamera, pRawData) return image except CameraException as e: print("CameraGetImageBuffer failed({}): {}".format(e.error_code, e.message)) return None def __del__(self): if self.hCamera: CameraUnInit(self.hCamera) if self.pFrameBuffer: CameraAlignFree(self.pFrameBuffer) # class MainWindow(QMainWindow): # def __init__(self, camera): # super().__init__() # self.setWindowTitle("MindVision Camera") # self.setGeometry(100, 100, 800, 600) # self.label = QLabel(self) # self.label.setAlignment(Qt.AlignCenter) # self.label.setScaledContents(True) # 自动缩放图像以适应标签大小 # self.camera = camera # self.timer = QTimer(self) # self.timer.timeout.connect(self.update_frame) # self.timer.start(30) # Update frame every 30ms # def closeEvent(self, event): # self.timer.stop() # self.camera.__del__() # event.accept() # def resizeEvent(self, event): # super().resizeEvent(event) # self.update_frame() # 窗口大小改变时更新图像 # def update_frame(self): # image = self.camera.capture() # if image is not None: # if self.camera.monoCamera: # qimage = QImage(image.data, image.shape[1], image.shape[0], QImage.Format_Grayscale8) # else: # qimage = QImage(image.data, image.shape[1], image.shape[0], QImage.Format_BGR888) # pixmap = QPixmap.fromImage(qimage) # self.label.setPixmap(pixmap) # self.label.resize(self.size()) # 调整标签大小以适应窗口 # if __name__ == '__main__': # app = QApplication(sys.argv) # cam = MindVisionCamera("054042423002") # window = MainWindow(cam) # window.show() # sys.exit(app.exec())