Python 调用海康机器人工业相机

这篇具有很好参考价值的文章主要介绍了Python 调用海康机器人工业相机。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、前期准备

1、python环境搭建

2、安装MVS软件

3、网上博客参考
1)RTSP(Runtime Stream Protocol)协议方向
(很遗憾,此路不通!!!)
因为我们用的 海康机器人工业相机 MV-CU060-10GM 这款相机,不支持 RTSP 协议。

如下博客适用于 海康威视摄像头,并不适用于 海康工业相机,如果是使用海康威视摄像头的小伙伴可以参考下。

参考博客:海康威视摄像头对接SDK实时预览功能和抓拍功能,懒癌福利,可直接CV

2)Java实现方向
(不能完全满足客户需求,此路不全通!!!)

使用Java目前参考官网的示例,实现了图片抓取,并上传的功能,但是没有实现视频流的实时获取和显示的功能。

如果需求只是获取图片,不要求视频流实时显示,可以通过Java就可以实现。

3)Python实现方向
(目前,网上没有直接能完全满足上述三个需求的,本人通过借鉴、整合,结合Flask框架实现的。)

参考博客如下:
python语言下使用opencv接口cv2.VideoCapture()接口调用海康机器人工业相机 (此篇博文可以重点看!!!)

通过python调用海康威视工业摄像头并进行图像存储,同时使用opencv实时图像显示(数据流问题已解决)

python调用海康工业相机并用opencv显示(整体实现)(此篇博文可以重点看!!!)

pyQT5 学习使用 笔记 六 pyQt5+opencv 显示海康GIGE相机动态视频流 (该方式虽然实现了视频的实时显示,但是,无法被给前端直接调用)

web实时显示摄像头图像(python) (此篇博文可以重点看!!!)

4)Flask 的相关教程和博客
https://www.w3cschool.cn/flask/
https://dormousehole.readthedocs.io/en/latest/
https://blog.csdn.net/weixin_44239541/article/details/89390139
https://zhuanlan.zhihu.com/p/104273184
https://blog.csdn.net/tulan_xiaoxin/article/details/79132214

二、Python 代码实现

1、测试代码

1)抓取图片测试代码

前提条件:将 *C:\Program Files (x86)\MVS\Development\Samples\Python* 目录下的 MvImport 目录,copy到自己的工程目录下,创建测试文件 TestGrabImage.py

代码如下:

# -- coding: utf-8 --
import cv2
import sys
import copy
import msvcrt
import numpy as np

from ctypes import *

sys.path.append("./MvImport")
from MvCameraControl_class import *

if __name__ == "__main__":

    deviceList = MV_CC_DEVICE_INFO_LIST()
    tlayerType = MV_GIGE_DEVICE | MV_USB_DEVICE

    # ch:枚举设备 | en:Enum device
    ret = MvCamera.MV_CC_EnumDevices(tlayerType, deviceList)
    if ret != 0:
        print ("enum devices fail! ret[0x%x]" % ret)
        sys.exit()

    if deviceList.nDeviceNum == 0:
        print ("find no device!")
        sys.exit()

    print ("find %d devices!" % deviceList.nDeviceNum)

    for i in range(0, deviceList.nDeviceNum):
        mvcc_dev_info = cast(deviceList.pDeviceInfo[i], POINTER(MV_CC_DEVICE_INFO)).contents
        if mvcc_dev_info.nTLayerType == MV_GIGE_DEVICE:
            print ("\ngige device: [%d]" % i)
            strModeName = ""
            for per in mvcc_dev_info.SpecialInfo.stGigEInfo.chModelName:
                strModeName = strModeName + chr(per)
            print ("device model name: %s" % strModeName)

            nip1 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0xff000000) >> 24)
            nip2 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x00ff0000) >> 16)
            nip3 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x0000ff00) >> 8)
            nip4 = (mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x000000ff)
            print ("current ip: %d.%d.%d.%d\n" % (nip1, nip2, nip3, nip4))
        elif mvcc_dev_info.nTLayerType == MV_USB_DEVICE:
            print ("\nu3v device: [%d]" % i)
            strModeName = ""
            for per in mvcc_dev_info.SpecialInfo.stUsb3VInfo.chModelName:
                if per == 0:
                    break
                strModeName = strModeName + chr(per)
            print ("device model name: %s" % strModeName)

            strSerialNumber = ""
            for per in mvcc_dev_info.SpecialInfo.stUsb3VInfo.chSerialNumber:
                if per == 0:
                    break
                strSerialNumber = strSerialNumber + chr(per)
            print ("user serial number: %s" % strSerialNumber)

    nConnectionNum = 0

    if int(nConnectionNum) >= deviceList.nDeviceNum:
        print ("intput error!")
        sys.exit()

    # ch:创建相机实例 | en:Creat Camera Object
    cam = MvCamera()

    # ch:选择设备并创建句柄 | en:Select device and create handle
    stDeviceList = cast(deviceList.pDeviceInfo[int(nConnectionNum)], POINTER(MV_CC_DEVICE_INFO)).contents

    ret = cam.MV_CC_CreateHandle(stDeviceList)
    if ret != 0:
        print ("create handle fail! ret[0x%x]" % ret)
        sys.exit()

    # ch:打开设备 | en:Open device
    ret = cam.MV_CC_OpenDevice(MV_ACCESS_Exclusive, 0)
    if ret != 0:
        print ("open device fail! ret[0x%x]" % ret)
        sys.exit()

    # ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera)
    if stDeviceList.nTLayerType == MV_GIGE_DEVICE:
        nPacketSize = cam.MV_CC_GetOptimalPacketSize()
        if int(nPacketSize) > 0:
            ret = cam.MV_CC_SetIntValue("GevSCPSPacketSize", nPacketSize)
            if ret != 0:
                print ("Warning: Set Packet Size fail! ret[0x%x]" % ret)
        else:
            print ("Warning: Get Packet Size fail! ret[0x%x]" % nPacketSize)

    # ch:设置触发模式为off | en:Set trigger mode as off
    ret = cam.MV_CC_SetEnumValue("TriggerMode", MV_TRIGGER_MODE_OFF)
    if ret != 0:
        print ("set trigger mode fail! ret[0x%x]" % ret)
        sys.exit()

    # ch:获取数据包大小 | en:Get payload size
    stParam = MVCC_INTVALUE()
    memset(byref(stParam), 0, sizeof(MVCC_INTVALUE))

    ret = cam.MV_CC_GetIntValue("PayloadSize", stParam)
    if ret != 0:
        print ("get payload size fail! ret[0x%x]" % ret)
        sys.exit()
        
    nPayloadSize = stParam.nCurValue

    # ch:开始取流 | en:Start grab image
    ret = cam.MV_CC_StartGrabbing()
    if ret != 0:
        print ("start grabbing fail! ret[0x%x]" % ret)
        sys.exit()

    stDeviceList = MV_FRAME_OUT_INFO_EX()
    memset(byref(stDeviceList), 0, sizeof(stDeviceList))
    data_buf = (c_ubyte * nPayloadSize)()

    ret = cam.MV_CC_GetOneFrameTimeout(byref(data_buf), nPayloadSize, stDeviceList, 1000)
    if ret == 0:
        print ("get one frame: Width[%d], Height[%d], nFrameNum[%d]" % (stDeviceList.nWidth, stDeviceList.nHeight, stDeviceList.nFrameNum))

        nRGBSize = stDeviceList.nWidth * stDeviceList.nHeight * 3
        stConvertParam=MV_SAVE_IMAGE_PARAM_EX()
        stConvertParam.nWidth = stDeviceList.nWidth
        stConvertParam.nHeight = stDeviceList.nHeight
        stConvertParam.pData = data_buf
        stConvertParam.nDataLen = stDeviceList.nFrameLen
        stConvertParam.enPixelType = stDeviceList.enPixelType
        stConvertParam.nImageLen = stConvertParam.nDataLen
        stConvertParam.nJpgQuality = 70
        stConvertParam.enImageType = MV_Image_Jpeg
        stConvertParam.pImageBuffer = (c_ubyte * nRGBSize)()
        stConvertParam.nBufferSize = nRGBSize
        # ret = cam.MV_CC_ConvertPixelType(stConvertParam)
        print(stConvertParam.nImageLen)
        ret = cam.MV_CC_SaveImageEx2(stConvertParam)
        if ret != 0:
            print ("convert pixel fail ! ret[0x%x]" % ret)
            del data_buf
            sys.exit()
        file_path = "AfterConvert_RGB2.jpg"
        file_open = open(file_path.encode('ascii'), 'wb+')
        img_buff = (c_ubyte * stConvertParam.nImageLen)()
        cdll.msvcrt.memcpy(byref(img_buff), stConvertParam.pImageBuffer, stConvertParam.nImageLen)
        file_open.write(img_buff)
    print ("Save Image succeed!")


    # ch:停止取流 | en:Stop grab image
    ret = cam.MV_CC_StopGrabbing()
    if ret != 0:
        print ("stop grabbing fail! ret[0x%x]" % ret)
        del data_buf
        sys.exit()

    # ch:关闭设备 | Close device
    ret = cam.MV_CC_CloseDevice()
    if ret != 0:
        print ("close deivce fail! ret[0x%x]" % ret)
        del data_buf
        sys.exit()

    # ch:销毁句柄 | Destroy handle
    ret = cam.MV_CC_DestroyHandle()
    if ret != 0:
        print ("destroy handle fail! ret[0x%x]" % ret)
        del data_buf
        sys.exit()

    del data_buf

2)Python+Qt 实现视频流实时显示测试代码
前提条件:将 *C:\Program Files (x86)\MVS\Development\Samples\Python* 目录下的 MvImport 目录,copy到自己的工程目录下,创建测试文件 TestVideoStream.py

代码如下:

# -- coding: utf-8 --
import cv2
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtGui import *
import numpy as np
 
#from CameraControl_header import MV_CC_DEVICE_INFO_LIST
#from mainWindow import Ui_MainWindow  # 导入创建的GUI类
import sys
import threading
import msvcrt
from ctypes import *

sys.path.append("./MvImport")
from MvCameraControl_class import *
from Ui_MainWindow  import *
from CameraParams_header import *
 
class mywindow(QtWidgets.QMainWindow, Ui_MainWindow):
    sendAddDeviceName = pyqtSignal() #定义一个添加设备列表的信号。
    deviceList = MV_CC_DEVICE_INFO_LIST()
    g_bExit = False
    # ch:创建相机实例 | en:Creat Camera Object
    cam = MvCamera()
 
    def connect_and_emit_sendAddDeviceName(self):
        # Connect the sendAddDeviceName signal to a slot.
        self.sendAddDeviceName.connect(self.SelectDevice)
        # Emit the signal.
        self.sendAddDeviceName.emit()
 
    def __init__(self):
        super(mywindow, self).__init__()
        self.setupUi(self)
        self.connect_and_emit_sendAddDeviceName()
        self.butopenCam.clicked.connect(lambda:self.openCam(self.camSelect.currentData()))
        self.butcloseCam.clicked.connect(self.closeCam)
 
        # setting main window geometry
        desktop_geometry = QtWidgets.QApplication.desktop()  # 获取屏幕大小
        main_window_width = desktop_geometry.width()  # 屏幕的宽
        main_window_height = desktop_geometry.height()  # 屏幕的高
        rect = self.geometry()  # 获取窗口界面大小
        window_width = rect.width()  # 窗口界面的宽
        window_height = rect.height()  # 窗口界面的高
        x = (main_window_width - window_width) // 2  # 计算窗口左上角点横坐标
        y = (main_window_height - window_height) // 2  # 计算窗口左上角点纵坐标
        self.setGeometry(x, y, window_width, window_height)  # 设置窗口界面在屏幕上的位置
        # 无边框以及背景透明一般不会在主窗口中用到,一般使用在子窗口中,例如在子窗口中显示gif提示载入信息等等
       # self.setWindowFlags(Qt.FramelessWindowHint)
       # self.setAttribute(Qt.WA_TranslucentBackground)
 
    #打开摄像头。
    def openCam(self,camid):
        self.g_bExit = False
        # ch:选择设备并创建句柄 | en:Select device and create handle
        stDeviceList = cast(self.deviceList.pDeviceInfo[int(camid)], POINTER(MV_CC_DEVICE_INFO)).contents
        ret = self.cam.MV_CC_CreateHandle(stDeviceList)
        if ret != 0:
            print("create handle fail! ret[0x%x]" % ret)
            sys.exit()
        # ch:打开设备 | en:Open device
 
        ret = self.cam.MV_CC_OpenDevice(MV_ACCESS_Exclusive, 0)
        if ret != 0:
            print("open device fail! ret[0x%x]" % ret)
            sys.exit()
 
        # ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera)
        if stDeviceList.nTLayerType == MV_GIGE_DEVICE:
            nPacketSize = self.cam.MV_CC_GetOptimalPacketSize()
            if int(nPacketSize) > 0:
                ret = self.cam.MV_CC_SetIntValue("GevSCPSPacketSize", nPacketSize)
                if ret != 0:
                    print("Warning: Set Packet Size fail! ret[0x%x]" % ret)
            else:
                print("Warning: Get Packet Size fail! ret[0x%x]" % nPacketSize)
 
        # ch:设置触发模式为off | en:Set trigger mode as off
        ret = self.cam.MV_CC_SetEnumValue("TriggerMode", MV_TRIGGER_MODE_OFF)
        if ret != 0:
            print("set trigger mode fail! ret[0x%x]" % ret)
            sys.exit()
            # ch:获取数据包大小 | en:Get payload size
        stParam = MVCC_INTVALUE()
        memset(byref(stParam), 0, sizeof(MVCC_INTVALUE))
 
        ret = self.cam.MV_CC_GetIntValue("PayloadSize", stParam)
        if ret != 0:
            print("get payload size fail! ret[0x%x]" % ret)
            sys.exit()
        nPayloadSize = stParam.nCurValue
 
        # ch:开始取流 | en:Start grab image
        ret = self.cam.MV_CC_StartGrabbing()
        if ret != 0:
            print("start grabbing fail! ret[0x%x]" % ret)
            sys.exit()
 
        data_buf = (c_ubyte * nPayloadSize)()
 
        try:
            hThreadHandle = threading.Thread(target=self.work_thread, args=(self.cam, data_buf, nPayloadSize))
            hThreadHandle.start()
        except:
            print("error: unable to start thread")
 
    #关闭相机
    def closeCam(self):
        self.g_bExit=True
        # ch:停止取流 | en:Stop grab image
        ret = self.cam.MV_CC_StopGrabbing()
        if ret != 0:
            print("stop grabbing fail! ret[0x%x]" % ret)
            sys.exit()
 
        # ch:关闭设备 | Close device
        ret = self.cam.MV_CC_CloseDevice()
        if ret != 0:
            print("close deivce fail! ret[0x%x]" % ret)
 
        # ch:销毁句柄 | Destroy handle
        ret = self.cam.MV_CC_DestroyHandle()
        if ret != 0:
            print("destroy handle fail! ret[0x%x]" % ret)
 
    def work_thread(self,cam=0, pData=0, nDataSize=0):
        stFrameInfo = MV_FRAME_OUT_INFO_EX()
        memset(byref(stFrameInfo), 0, sizeof(stFrameInfo))
        while True:
            QIm = np.asarray(pData)  # 将c_ubyte_Array转化成ndarray得到(3686400,)
            QIm = QIm.reshape((2048, 3072, 1))  # 根据自己分辨率进行转化
                # print(temp)
                # print(temp.shape)
            QIm = cv2.cvtColor(QIm, cv2.COLOR_BGR2RGB)  # 这一步获取到的颜色不对,因为默认是BRG,要转化成RGB,颜色才正常
            pyrD1=cv2.pyrDown(QIm) #向下取样
            pyrD2 = cv2.pyrDown(pyrD1)  # 向下取样
            image_height, image_width, image_depth = pyrD2.shape  # 读取图像高宽深度
            pyrD3 = QImage(pyrD2, image_width, image_height,  image_width * image_depth,QImage.Format_RGB888)
            self.label.setPixmap(QPixmap.fromImage(pyrD3))
            #cv2.namedWindow("result", cv2.WINDOW_AUTOSIZE)
            #cv2.imshow("result", temp)
            #if cv2.waitKey(1) & 0xFF == ord('q'):
            #    break
 
            ret = cam.MV_CC_GetOneFrameTimeout(pData, nDataSize, stFrameInfo, 1000)
            if ret == 0:
                print("get one frame: Width[%d], Height[%d], nFrameNum[%d]" % (
                    stFrameInfo.nWidth, stFrameInfo.nHeight, stFrameInfo.nFrameNum))
            else:
                print("no data[0x%x]" % ret)
            if self.g_bExit == True:
                del pData
                break
 
 
    #获得所有相机的列表存入cmbSelectDevice中
    def SelectDevice(self):
        '''选择所有能用的相机到列表中,
             gige相机需要配合 sdk 得到。
        '''
        #得到相机列表
 
        tlayerType = MV_GIGE_DEVICE | MV_USB_DEVICE
    # ch:枚举设备 | en:Enum device
        ret = MvCamera.MV_CC_EnumDevices(tlayerType, self.deviceList)
        if ret != 0:
            print("enum devices fail! ret[0x%x]" % ret)
            sys.exit()
        if self.deviceList.nDeviceNum == 0:
            print("find no device!")
            sys.exit()
 
        print("Find %d devices!" % self.deviceList.nDeviceNum)
        for i in range(0, self.deviceList.nDeviceNum):
            mvcc_dev_info = cast(self.deviceList.pDeviceInfo[i], POINTER(MV_CC_DEVICE_INFO)).contents
            if mvcc_dev_info.nTLayerType == MV_GIGE_DEVICE:
                print("\ngige device: [%d]" % i)
                strModeName = ""
                for per in mvcc_dev_info.SpecialInfo.stGigEInfo.chModelName:
                    strModeName = strModeName + chr(per)
                print("device model name: %s" % strModeName)
                self.camSelect.addItem(strModeName,i) #写入设备列表。
 
    def pushbutton_function(self):
        #do some things
        Img=cv2.imread('JP1.JPG') #通过opencv读入一张图片
        image_height, image_width, image_depth=Img.shape #读取图像高宽深度
        QIm=cv2.cvtColor(Img,cv2.COLOR_BGR2RGB)
        QIm=QImage(QIm.data, image_width, image_height,  image_width * image_depth,QImage.Format_RGB888)
        self.label.setPixmap(QPixmap.fromImage(QIm))
 
if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    window = mywindow()
    window.show()
    sys.exit(app.exec_())

上述代码中用到的 Ui_MainWindow.py,放到 MvImport 目录下。

代码如下:

# -*- coding: utf-8 -*-
 
# Form implementation generated from reading ui file 'mainWindow.ui'
#
# Created by: PyQt5 UI code generator 5.15.0
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.
 
 
from PyQt5 import QtCore, QtGui, QtWidgets
 
 
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(589, 530)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName("verticalLayout")
        self.camSelect = QtWidgets.QComboBox(self.centralwidget)
        self.camSelect.setObjectName("camSelect")
        self.verticalLayout.addWidget(self.camSelect)
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setObjectName("label")
        self.verticalLayout.addWidget(self.label)
        self.butopenCam = QtWidgets.QPushButton(self.centralwidget)
        self.butopenCam.setObjectName("butopenCam")
        self.verticalLayout.addWidget(self.butopenCam)
        self.butcloseCam = QtWidgets.QPushButton(self.centralwidget)
        self.butcloseCam.setObjectName("butcloseCam")
        self.verticalLayout.addWidget(self.butcloseCam)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 589, 23))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
 
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
 
    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label.setText(_translate("MainWindow", "TextLabel"))
        self.butopenCam.setText(_translate("MainWindow", "打开相机"))
        self.butcloseCam.setText(_translate("MainWindow", "关闭相机"))

四、使用 Python + OpenCV + Flask 实现,可以满足视频实时获取,并返回通过GET请求返回给前端进行实时显示,也可以抓取图片,保存上传。

1、添加依赖文件
将 *C:\Program Files (x86)\MVS\Development\Samples\Python* 目录下的 MvImport 目录,copy到自己的工程目录下。

2、安装插件 DirectShow
1)进入第三方插件 DirectShow 路径

cd C:\Program Files    (x86)\MVS\Development\ThirdPartyPlatformAdapter\DirectShow\x64\MvDSS2
 


2)安装 DirectShow
使用 管理员权限 运行 InstallDSSvc_x64.bat

python调用海康工业相机,python,机器人,开发语言

0)index.html

在工程中创建 templates 目录,用于存放 index.hml

<html>
  <head>
  </head>
  <body>
      <h1>拍照预览</h1>
    <img src="{{ url_for('startPreview') }}" width="50%">
  </body>
</html>

1)JsonResponse.py

用于规范返回给前端的数据类型,代码如下:

# -- coding: utf-8 --

class JsonResponse(object):
    """
    统一的json返回格式
    """

    def __init__(self, code, msg, data):
        self.code = code
        self.msg = msg
        self.data = data

    @classmethod
    def success(cls, code=0, msg='success', data=None):
        return cls(code, msg, data)

    @classmethod
    def error(cls, code=-1, msg='error', data=None):
        return cls(code, msg, data)

    def to_dict(self):
        return {
            "code": self.code,
            "msg": self.msg,
            "data": self.data
        }

2)JsonFlask.py

用于重定义数据返回格式,代码如下:

# -- coding: utf-8 --

from flask import Flask, jsonify
from JsonResponse import *

class JsonFlask(Flask):
    def make_response(self, rv):
        """视图函数可以直接返回: list、dict、None"""
        if rv is None or isinstance(rv, (list, dict)):
            rv = JsonResponse.success(rv)

        if isinstance(rv, JsonResponse):
            rv = jsonify(rv.to_dict())

        return super().make_response(rv)

3)HikRobotCamera.py

核心代码文件,实现如下功能:
开始预览视频流停止预览视频流获取图片记录日志等功能。

代码如下

# -- coding: utf-8 --
import cv2
from flask import Flask, render_template, Response

import sys
import msvcrt
import base64
import datetime
import logging

sys.path.append("./MvImport")
from MvCameraControl_class import *
from JsonResponse import *
from JsonFlask import *

logging.basicConfig(level=logging.DEBUG,#控制台打印的日志级别
                    filename='hikrobot.log',
                    filemode='a',##模式,有w和a,w就是写模式,每次都会重新写日志,覆盖之前的日志
                    #a是追加模式,默认如果不写的话,就是追加模式
                    format=
                    '%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'
                    #日志格式
                    )

# 这里配置一下 template_folder为当前目录,不然可以找不到 index.html
app = JsonFlask(__name__, template_folder='.')

# index
@app.route('/')
def index():
    return render_template('./templates/index.html')

# 获取码流
def generate(cap):
    # 捕获异常信息
    try:
        while True:
            # 如果是关闭相机,先退出取视频流的循环
            global open
            if (not open):
                break;
            retgrab = cap.grab()
            if retgrab == True:
                logging.debug("Grab true")
            ret1, frame = cap.retrieve()
            # print(type(frame))
            if frame is None:
                logging.error("frame is None")
                continue
            ret1, jpeg = cv2.imencode('.jpg', frame)
            jpg_frame = jpeg.tobytes()
            yield (b'--frame\r\n'
                b'Content-Type: image/jpeg\r\n\r\n' + jpg_frame + b'\r\n')
    except Exception as e:
        logging.error("generate error: %s" % str(e))


# 开始预览
@app.route('/startPreview')
def startPreview():
    logging.info("======================================")
    logging.info("start to preview video stream, current_time: " + str(datetime.datetime.now()))
    # 全局变量,用于控制获取视频流的开关状态
    global open
    open = True

    # 全局变量,获取视频连接
    global cap
    cap = cv2.VideoCapture(1)

    if False == cap.isOpened():
        logging.error("can't open camera")
        quit()
    else:
        logging.info("start to open camera")

    logging.info("open camera ok")

    # 分辨率设置 3072*2048(海康机器人工业相机 MV-CU060-10GM)
    cap.set(cv2.CAP_PROP_FRAME_WIDTH, 3072)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 2048)
    # 帧率配置
    cap.set(cv2.CAP_PROP_FPS, 15)   
    return Response(generate(cap), mimetype='multipart/x-mixed-replace;boundary=frame')

# 停止预览
@app.route('/stopPreview')
def stopPreview():
    logging.info("======================================")
    logging.info("stop to preview video stream, current_time: " + str(datetime.datetime.now()))
    logging.info("start to close camera")

    # 全局变量,用于停止循环
    global open
    open = False

    logging.info("release resources start")
    # 全局变量,用于释放相机资源
    try:
        global cap
        cap.release()
        cv2.destroyAllWindows()
    except Exception as e:
        logging.error("stopPreview error: %s" % str(e))
    logging.info("release resources end")
    logging.info("camera closed successfully, current_time: " + str(datetime.datetime.now()))
    logging.info("======================================")
    return "stop to preview"


@app.route('/openAndSave')
def openAndSave():
    logging.info("======================================")
    logging.info("start to grab image, current_time: " + str(datetime.datetime.now()))
    code = 100000
    msg = "连接相机时发生错误"
    # img_base64 = None
    try:
        deviceList = MV_CC_DEVICE_INFO_LIST()
        tlayerType = MV_GIGE_DEVICE | MV_USB_DEVICE

        # ch:枚举设备 | en:Enum device
        ret = MvCamera.MV_CC_EnumDevices(tlayerType, deviceList)
        if ret != 0:
            logging.error("enum devices fail! ret[0x%x]" % ret)
            sys.exit()

        if deviceList.nDeviceNum == 0:
            logging.error("find no device!")
            sys.exit()

        logging.info("find %d devices!" % deviceList.nDeviceNum)

        for i in range(0, deviceList.nDeviceNum):
            mvcc_dev_info = cast(deviceList.pDeviceInfo[i], POINTER(MV_CC_DEVICE_INFO)).contents
            if mvcc_dev_info.nTLayerType == MV_GIGE_DEVICE:
                logging.info("\ngige device: [%d]" % i)
                strModeName = ""
                for per in mvcc_dev_info.SpecialInfo.stGigEInfo.chModelName:
                    strModeName = strModeName + chr(per)
                logging.info("device model name: %s" % strModeName)

                nip1 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0xff000000) >> 24)
                nip2 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x00ff0000) >> 16)
                nip3 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x0000ff00) >> 8)
                nip4 = (mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x000000ff)
                logging.info("current ip: %d.%d.%d.%d\n" % (nip1, nip2, nip3, nip4))
            elif mvcc_dev_info.nTLayerType == MV_USB_DEVICE:
                logging.info("\nu3v device: [%d]" % i)
                strModeName = ""
                for per in mvcc_dev_info.SpecialInfo.stUsb3VInfo.chModelName:
                    if per == 0:
                        break
                    strModeName = strModeName + chr(per)
                logging.info("device model name: %s" % strModeName)

                strSerialNumber = ""
                for per in mvcc_dev_info.SpecialInfo.stUsb3VInfo.chSerialNumber:
                    if per == 0:
                        break
                    strSerialNumber = strSerialNumber + chr(per)
                logging.info("user serial number: %s" % strSerialNumber)

        nConnectionNum = 0

        if int(nConnectionNum) >= deviceList.nDeviceNum:
            logging.error("intput error!")
            sys.exit()

        # ch:创建相机实例 | en:Creat Camera Object
        cam = MvCamera()

        # ch:选择设备并创建句柄 | en:Select device and create handle
        stDeviceList = cast(deviceList.pDeviceInfo[int(nConnectionNum)], POINTER(MV_CC_DEVICE_INFO)).contents

        ret = cam.MV_CC_CreateHandle(stDeviceList)
        if ret != 0:
            logging.error("create handle fail! ret[0x%x]" % ret)
            sys.exit()

        # ch:打开设备 | en:Open device
        ret = cam.MV_CC_OpenDevice(MV_ACCESS_Exclusive, 0)
        if ret != 0:
            logging.error("open device fail! ret[0x%x]" % ret)
            sys.exit()

        # ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera)
        if stDeviceList.nTLayerType == MV_GIGE_DEVICE:
            nPacketSize = cam.MV_CC_GetOptimalPacketSize()
            if int(nPacketSize) > 0:
                ret = cam.MV_CC_SetIntValue("GevSCPSPacketSize", nPacketSize)
                if ret != 0:
                    logging.warn("Warning: Set Packet Size fail! ret[0x%x]" % ret)
            else:
                logging.warn("Warning: Get Packet Size fail! ret[0x%x]" % nPacketSize)

        # ch:设置触发模式为off | en:Set trigger mode as off
        ret = cam.MV_CC_SetEnumValue("TriggerMode", MV_TRIGGER_MODE_OFF)
        if ret != 0:
            logging.error("set trigger mode fail! ret[0x%x]" % ret)
            sys.exit()

        # ch:获取数据包大小 | en:Get payload size
        stParam = MVCC_INTVALUE()
        memset(byref(stParam), 0, sizeof(MVCC_INTVALUE))

        ret = cam.MV_CC_GetIntValue("PayloadSize", stParam)
        if ret != 0:
            logging.error("get payload size fail! ret[0x%x]" % ret)
            sys.exit()
            
        nPayloadSize = stParam.nCurValue

        # ch:开始取流 | en:Start grab image
        ret = cam.MV_CC_StartGrabbing()
        if ret != 0:
            logging.error("start grabbing fail! ret[0x%x]" % ret)
            sys.exit()

        stDeviceList = MV_FRAME_OUT_INFO_EX()
        memset(byref(stDeviceList), 0, sizeof(stDeviceList))
        data_buf = (c_ubyte * nPayloadSize)()
        
        ret = cam.MV_CC_GetOneFrameTimeout(byref(data_buf), nPayloadSize, stDeviceList, 1000)
        if ret == 0:
            logging.info("get one frame: Width[%d], Height[%d], nFrameNum[%d]" % (stDeviceList.nWidth, stDeviceList.nHeight, stDeviceList.nFrameNum))

            nRGBSize = stDeviceList.nWidth * stDeviceList.nHeight * 3
            stConvertParam=MV_SAVE_IMAGE_PARAM_EX()
            stConvertParam.nWidth = stDeviceList.nWidth
            stConvertParam.nHeight = stDeviceList.nHeight
            stConvertParam.pData = data_buf
            stConvertParam.nDataLen = stDeviceList.nFrameLen
            stConvertParam.enPixelType = stDeviceList.enPixelType
            stConvertParam.nImageLen = stConvertParam.nDataLen
            stConvertParam.nJpgQuality = 70
            stConvertParam.enImageType = MV_Image_Jpeg
            stConvertParam.pImageBuffer = (c_ubyte * nRGBSize)()
            stConvertParam.nBufferSize = nRGBSize
            # ret = cam.MV_CC_ConvertPixelType(stConvertParam)
            logging.info("nImageLen: %d" % stConvertParam.nImageLen)
            ret = cam.MV_CC_SaveImageEx2(stConvertParam)
            if ret != 0:
                logging.error("convert pixel fail ! ret[0x%x]" % ret)
                del data_buf
                sys.exit()
            #file_path = "AfterConvert_RGB2.jpg"
            #file_open = open(file_path, 'wb+')
            #file_open = open(file_path.encode('utf8'), 'wb')
            img_buff = (c_ubyte * stConvertParam.nImageLen)()
            cdll.msvcrt.memcpy(byref(img_buff), stConvertParam.pImageBuffer, stConvertParam.nImageLen)
            #file_open.write(img_buff)
            
            # 对返回的图片进行 base64 格式转换
            img_base64 = "data:image/jpg;base64," + str(base64.b64encode(img_buff)).split("'")[1]
            code = 200
            msg = "success"
        logging.info("Save Image succeed!")

        # ch:停止取流 | en:Stop grab image
        ret = cam.MV_CC_StopGrabbing()
        if ret != 0:
            logging.error("stop grabbing fail! ret[0x%x]" % ret)
            del data_buf
            sys.exit()

        # ch:关闭设备 | Close device
        ret = cam.MV_CC_CloseDevice()
        if ret != 0:
            logging.error("close deivce fail! ret[0x%x]" % ret)
            del data_buf
            sys.exit()

        # ch:销毁句柄 | Destroy handle
        ret = cam.MV_CC_DestroyHandle()
        if ret != 0:
            logging.error("destroy handle fail! ret[0x%x]" % ret)
            del data_buf
            sys.exit()

        del data_buf
    except Exception as e:
        logging.error("openAndSave error: %s" % str(e))
    # print("openAndSave finished, current_time: " + str(datetime.datetime.now()))  
  
    return JsonResponse(code, msg, img_base64)

# 执行web服务, 端口号可自行修订
logging.info("start to run camera app, current_time: " + str(datetime.datetime.now()))
app.run(host='0.0.0.0', port=65432, debug=True, threaded=True)
# -- coding: utf-8 --
import cv2
from flask import Flask, render_template, Response

import sys
import msvcrt
import base64
import datetime
import logging

sys.path.append("./MvImport")
from MvCameraControl_class import *
from JsonResponse import *
from JsonFlask import *

logging.basicConfig(level=logging.DEBUG,#控制台打印的日志级别
                    filename='hikrobot.log',
                    filemode='a',##模式,有w和a,w就是写模式,每次都会重新写日志,覆盖之前的日志
                    #a是追加模式,默认如果不写的话,就是追加模式
                    format=
                    '%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'
                    #日志格式
                    )

# 这里配置一下 template_folder为当前目录,不然可以找不到 index.html
app = JsonFlask(__name__, template_folder='.')

# index
@app.route('/')
def index():
    return render_template('./templates/index.html')

# 获取码流
def generate(cap):
    # 捕获异常信息
    try:
        while True:
            # 如果是关闭相机,先退出取视频流的循环
            global open
            if (not open):
                break;
            retgrab = cap.grab()
            if retgrab == True:
                logging.debug("Grab true")
            ret1, frame = cap.retrieve()
            # print(type(frame))
            if frame is None:
                logging.error("frame is None")
                continue
            ret1, jpeg = cv2.imencode('.jpg', frame)
            jpg_frame = jpeg.tobytes()
            yield (b'--frame\r\n'
                b'Content-Type: image/jpeg\r\n\r\n' + jpg_frame + b'\r\n')
    except Exception as e:
        logging.error("generate error: %s" % str(e))


# 开始预览
@app.route('/startPreview')
def startPreview():
    logging.info("================== startPreview start ====================")
    logging.info("start to preview video stream, current_time: " + str(datetime.datetime.now()))
    # 全局变量,用于控制获取视频流的开关状态
    try:
        global open
        open = True

        # 全局变量,获取视频连接
        global cap
        cap = cv2.VideoCapture(1)

        if False == cap.isOpened():
            logging.error("startPreview -- can't open camera")
            quit()
        else:
            logging.info("startPreview -- start to open camera")

        logging.info("startPreview -- open camera ok")

        # 分辨率设置 3072*2048(海康机器人工业相机 MV-CU060-10GM)
        cap.set(cv2.CAP_PROP_FRAME_WIDTH, 3072)
        cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 2048)
        # 帧率配置
        cap.set(cv2.CAP_PROP_FPS, 15)   
        response = Response(generate(cap), mimetype='multipart/x-mixed-replace;boundary=frame')
    except Exception as e:
        logging.error("startPreview error: %s" % str(e))
    return response

# 停止预览
@app.route('/stopPreview')
def stopPreview():
    logging.info("================== stopPreview start ====================")
    logging.info("stop to preview video stream, current_time: " + str(datetime.datetime.now()))
    logging.info("start to close camera")

    # 全局变量,用于停止循环
    global open
    open = False

    logging.info("release resources start")
    # 全局变量,用于释放相机资源
    try:
        global cap
        cap.release()
        cv2.destroyAllWindows()
    except Exception as e:
        logging.error("stopPreview error: %s" % str(e))
    logging.info("release resources end")
    logging.info("camera closed successfully, current_time: " + str(datetime.datetime.now()))
    logging.info("=================== stopPreview end ===================")
    return "stop to preview"

# 获取base64图片
@app.route('/grabImage')
def grabImage():
    code = 100000
    msg = "连接相机时发生错误"
    # 捕获异常信息
    try:
        print("grabImage -- stopPreview start")
        stopPreview()
        print("grabImage -- stopPreview end")

        # 全局变量,获取视频连接
        global cap
        cap = cv2.VideoCapture(1)

        if False == cap.isOpened():
            logging.error("can't open camera")
            quit()
        else:
            logging.info("grabImage -- start to open camera")

        logging.info("grabImage -- open camera ok")

        # 分辨率设置 3072*2048(海康机器人工业相机 MV-CU060-10GM)
        cap.set(cv2.CAP_PROP_FRAME_WIDTH, 3072)
        cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 2048)
        # 帧率配置
        cap.set(cv2.CAP_PROP_FPS, 15)   
        
        retgrab1 = cap.grab()
        if retgrab1 == True:
            logging.debug("grabImage -- Grab true")
        ret1, frame = cap.retrieve()
        ret1, jpeg = cv2.imencode('.jpg', frame)
        img_buff = jpeg.tobytes()

        # 对返回的图片进行 base64 格式转换
        img_base64 = "data:image/jpg;base64," + str(base64.b64encode(img_buff)).split("'")[1]
        code = 200
        msg = "success"

        stopPreview()
    except Exception as e:
        logging.error("generate error: %s" % str(e))

    return JsonResponse(code, msg, img_base64)

# 获取base64图片
@app.route('/hik/openAndSave')
def openAndSave():
    code = 100000
    msg = "连接相机时发生错误"
    # 捕获异常信息
    try:
        logging.info("================= openAndSave start =====================")
        # 拍照之前,先停止预览
        stopPreview()
        logging.info("start to grab image, current_time: " + str(datetime.datetime.now()))

        # 全局变量,获取视频连接
        global cap
        cap = cv2.VideoCapture(1)

        if False == cap.isOpened():
            logging.error("openAndSave -- can't open camera")
            quit()
        else:
            logging.info("openAndSave -- start to open camera")

        logging.info("openAndSave -- open camera ok")

        # 分辨率设置 3072*2048(海康机器人工业相机 MV-CU060-10GM)
        cap.set(cv2.CAP_PROP_FRAME_WIDTH, 3072)
        cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 2048)
        # 帧率配置
        cap.set(cv2.CAP_PROP_FPS, 15)   
        
        retgrab1 = cap.grab()
        if retgrab1 == True:
            logging.debug("openAndSave -- Grab true")
        ret1, frame = cap.retrieve()
        ret1, jpeg = cv2.imencode('.jpg', frame)
        img_buff = jpeg.tobytes()

        # 对返回的图片进行 base64 格式转换
        img_base64 = "data:image/jpg;base64," + str(base64.b64encode(img_buff)).split("'")[1]
        code = 200
        msg = "success"

        stopPreview()
        logging.info("================= openAndSave end =====================")
    except Exception as e:
        logging.error("openAndSave error: %s" % str(e))

    return JsonResponse(code, msg, img_base64)

@app.route('/hik/openAndSave2')
def openAndSave2():
    # 拍照之前,先停止预览
    stopPreview()
    logging.info("======================================")
    logging.info("start to grab image, current_time: " + str(datetime.datetime.now()))
    code = 100000
    msg = "连接相机时发生错误"
    # img_base64 = None
    try:
        deviceList = MV_CC_DEVICE_INFO_LIST()
        tlayerType = MV_GIGE_DEVICE | MV_USB_DEVICE

        # ch:枚举设备 | en:Enum device
        ret = MvCamera.MV_CC_EnumDevices(tlayerType, deviceList)
        if ret != 0:
            logging.error("enum devices fail! ret[0x%x]" % ret)
            sys.exit()

        if deviceList.nDeviceNum == 0:
            logging.error("find no device!")
            sys.exit()

        logging.info("find %d devices!" % deviceList.nDeviceNum)

        for i in range(0, deviceList.nDeviceNum):
            mvcc_dev_info = cast(deviceList.pDeviceInfo[i], POINTER(MV_CC_DEVICE_INFO)).contents
            if mvcc_dev_info.nTLayerType == MV_GIGE_DEVICE:
                logging.info("\ngige device: [%d]" % i)
                strModeName = ""
                for per in mvcc_dev_info.SpecialInfo.stGigEInfo.chModelName:
                    strModeName = strModeName + chr(per)
                logging.info("device model name: %s" % strModeName)

                nip1 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0xff000000) >> 24)
                nip2 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x00ff0000) >> 16)
                nip3 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x0000ff00) >> 8)
                nip4 = (mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x000000ff)
                logging.info("current ip: %d.%d.%d.%d\n" % (nip1, nip2, nip3, nip4))
            elif mvcc_dev_info.nTLayerType == MV_USB_DEVICE:
                logging.info("\nu3v device: [%d]" % i)
                strModeName = ""
                for per in mvcc_dev_info.SpecialInfo.stUsb3VInfo.chModelName:
                    if per == 0:
                        break
                    strModeName = strModeName + chr(per)
                logging.info("device model name: %s" % strModeName)

                strSerialNumber = ""
                for per in mvcc_dev_info.SpecialInfo.stUsb3VInfo.chSerialNumber:
                    if per == 0:
                        break
                    strSerialNumber = strSerialNumber + chr(per)
                logging.info("user serial number: %s" % strSerialNumber)

        nConnectionNum = 0

        if int(nConnectionNum) >= deviceList.nDeviceNum:
            logging.error("intput error!")
            sys.exit()

        # ch:创建相机实例 | en:Creat Camera Object
        cam = MvCamera()

        # ch:选择设备并创建句柄 | en:Select device and create handle
        stDeviceList = cast(deviceList.pDeviceInfo[int(nConnectionNum)], POINTER(MV_CC_DEVICE_INFO)).contents

        ret = cam.MV_CC_CreateHandle(stDeviceList)
        if ret != 0:
            logging.error("create handle fail! ret[0x%x]" % ret)
            sys.exit()

        # ch:打开设备 | en:Open device
        ret = cam.MV_CC_OpenDevice(MV_ACCESS_Exclusive, 0)
        if ret != 0:
            logging.error("open device fail! ret[0x%x]" % ret)
            sys.exit()

        # ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera)
        if stDeviceList.nTLayerType == MV_GIGE_DEVICE:
            nPacketSize = cam.MV_CC_GetOptimalPacketSize()
            if int(nPacketSize) > 0:
                ret = cam.MV_CC_SetIntValue("GevSCPSPacketSize", nPacketSize)
                if ret != 0:
                    logging.warn("Warning: Set Packet Size fail! ret[0x%x]" % ret)
            else:
                logging.warn("Warning: Get Packet Size fail! ret[0x%x]" % nPacketSize)

        # ch:设置触发模式为off | en:Set trigger mode as off
        ret = cam.MV_CC_SetEnumValue("TriggerMode", MV_TRIGGER_MODE_OFF)
        if ret != 0:
            logging.error("set trigger mode fail! ret[0x%x]" % ret)
            sys.exit()

        # ch:获取数据包大小 | en:Get payload size
        stParam = MVCC_INTVALUE()
        memset(byref(stParam), 0, sizeof(MVCC_INTVALUE))

        ret = cam.MV_CC_GetIntValue("PayloadSize", stParam)
        if ret != 0:
            logging.error("get payload size fail! ret[0x%x]" % ret)
            sys.exit()
            
        nPayloadSize = stParam.nCurValue

        # ch:开始取流 | en:Start grab image
        ret = cam.MV_CC_StartGrabbing()
        if ret != 0:
            logging.error("start grabbing fail! ret[0x%x]" % ret)
            sys.exit()

        stDeviceList = MV_FRAME_OUT_INFO_EX()
        memset(byref(stDeviceList), 0, sizeof(stDeviceList))
        data_buf = (c_ubyte * nPayloadSize)()
        
        ret = cam.MV_CC_GetOneFrameTimeout(byref(data_buf), nPayloadSize, stDeviceList, 1000)
        if ret == 0:
            logging.info("get one frame: Width[%d], Height[%d], nFrameNum[%d]" % (stDeviceList.nWidth, stDeviceList.nHeight, stDeviceList.nFrameNum))

            nRGBSize = stDeviceList.nWidth * stDeviceList.nHeight * 3
            stConvertParam=MV_SAVE_IMAGE_PARAM_EX()
            stConvertParam.nWidth = stDeviceList.nWidth
            stConvertParam.nHeight = stDeviceList.nHeight
            stConvertParam.pData = data_buf
            stConvertParam.nDataLen = stDeviceList.nFrameLen
            stConvertParam.enPixelType = stDeviceList.enPixelType
            stConvertParam.nImageLen = stConvertParam.nDataLen
            stConvertParam.nJpgQuality = 70
            stConvertParam.enImageType = MV_Image_Jpeg
            stConvertParam.pImageBuffer = (c_ubyte * nRGBSize)()
            stConvertParam.nBufferSize = nRGBSize
            # ret = cam.MV_CC_ConvertPixelType(stConvertParam)
            logging.info("nImageLen: %d" % stConvertParam.nImageLen)
            ret = cam.MV_CC_SaveImageEx2(stConvertParam)
            if ret != 0:
                logging.error("convert pixel fail ! ret[0x%x]" % ret)
                del data_buf
                sys.exit()
            #file_path = "AfterConvert_RGB2.jpg"
            #file_open = open(file_path, 'wb+')
            #file_open = open(file_path.encode('utf8'), 'wb')
            img_buff = (c_ubyte * stConvertParam.nImageLen)()
            cdll.msvcrt.memcpy(byref(img_buff), stConvertParam.pImageBuffer, stConvertParam.nImageLen)
            #file_open.write(img_buff)
            
            # 对返回的图片进行 base64 格式转换
            img_base64 = "data:image/jpg;base64," + str(base64.b64encode(img_buff)).split("'")[1]
            code = 200
            msg = "success"
        logging.info("Save Image succeed!")

        # ch:停止取流 | en:Stop grab image
        ret = cam.MV_CC_StopGrabbing()
        if ret != 0:
            logging.error("stop grabbing fail! ret[0x%x]" % ret)
            del data_buf
            sys.exit()

        # ch:关闭设备 | Close device
        ret = cam.MV_CC_CloseDevice()
        if ret != 0:
            logging.error("close deivce fail! ret[0x%x]" % ret)
            del data_buf
            sys.exit()

        # ch:销毁句柄 | Destroy handle
        ret = cam.MV_CC_DestroyHandle()
        if ret != 0:
            logging.error("destroy handle fail! ret[0x%x]" % ret)
            del data_buf
            sys.exit()

        del data_buf
    except Exception as e:
        logging.error("openAndSave error: %s" % str(e))
    # print("openAndSave finished, current_time: " + str(datetime.datetime.now()))  
  
    return JsonResponse(code, msg, img_base64)

# 执行web服务, 端口号可自行修订
logging.info("start to run camera app, current_time: " + str(datetime.datetime.now()))
if __name__ == '__main__':
    try:
        app.run(host='0.0.0.0', port=65432, debug=True, threaded=True)
    except Exception as e:
        logging.error("app error: %s" % str(e))

6、功能验证
1)开始预览
可以将 http://127.0.0.1:65432/startPreview 在前端用 img 标签 显示视频的实时预览效果。

http://127.0.0.1:65432/startPreview


2)停止预览
由于使用的这款海康机器人工业相机(MV-CU060-10GM)只能创建一个连接,所以,当预览完实时视频,需要调用该接口释放相机资源,避免资源被长期占用。

http://127.0.0.1:65432/stopPreview


3)获取图片
返回 base64 格式 的图片,前端可以直接接收显示,调用上传接口保存。

http://127.0.0.1:65432/openAndSave


版权声明:本文为CSDN博主「龙凌云」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/aikudexiaohai/article/details/130078959文章来源地址https://www.toymoban.com/news/detail-587455.html

到了这里,关于Python 调用海康机器人工业相机的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 海康机器人工业相机 Win10+Qt+Cmake 开发环境搭建

    参考这个链接安装好MVS客户端 Qt新建一个c++项目 cmakeList中添加海康机器人的库,如下: main.cpp中添加以下代码 运行程序,出现以下内容则说明安装库成功

    2024年02月11日
    浏览(46)
  • 合肥工业大学机器人足球仿真robcup作业三(python实现)附代码有注释

    题目: 已知2个点的信息,定位自己的绝对坐标。   设图中C(0,0),P1(-52.5,-32), P2(-52.5, 32), P3(52.5,32), P4(52.5,-32), P5(0,-32), P6(0,32), P7(-30,-7), P8(-30, 7), P9(30,7), P10(30, -7),G1(-52.5,0),G2(52.5,0) 随机得到附近2点距离自己的信息(r,theta), r表示目标点距离自己的距离,theta表示以自己中心的极角.(

    2024年02月08日
    浏览(44)
  • python调用飞书机器人发送文件

    当前飞书webhook机器人还不支持发送文件类型的群消息,可以申请创建一个机器人应用来实现群发送文件消息。 创建机器人后,需要开通一系列权限,然后发布。由管理员审核通过后,才可使用。 包括如下的权限,可以获取群的chat_id。 开通权限发布应用后,可以取到两个重

    2024年02月06日
    浏览(47)
  • python 调用百度文心一言接口开发聊天机器人

    要使用Python调用百度文心一言接口开发聊天机器人,可以按照以下步骤进行: 注册百度智能云账号并创建一个API密钥。 安装Python的requests库和BeautifulSoup库。可以使用以下命令进行安装: 使用Python编写代码,通过请求百度智能云API接口,获取聊天机器人的回答。以下是一个示

    2024年02月09日
    浏览(35)
  • 怎么调用文心一言的api接口生成一个简单的聊天机器人(python代码)

    寒假在学习大模型,但也没弄出多少眉目,电脑性能还有点小问题,大模型总跑不起来,只会简单调用一下现有的大模型的接口,例如:文心一言,下面展示一下代码: 至于如何获取这其中的两个key,网上有太多文章了,大家可以去找找看,比如这篇文章:百度文心一言AP

    2024年04月09日
    浏览(71)
  • 【Python微信机器人】第三篇:使用ctypes调用进程函数和读取内存结构体

    目前的系列目录(后面会根据实际情况变动): 在windows11上编译python 将python注入到其他进程并运行 注入Python并使用ctypes主动调用进程内的函数和读取内存结构体 使用汇编引擎调用进程内的任意函数 利用beaengine反汇编引擎的c接口写一个pyd库,用于实现inline hook 利用beaengine反汇编

    2024年02月06日
    浏览(38)
  • C# 开源SDK 工业相机库 调用海康相机 大恒相机

    c# 相机库,含海康、大恒品牌2D相机的常用功能。 底层采用回调+信号量模式封装 ,最大程度减小线程资源,提高采图效率。 开源地址 :https://gitee.com/laomaogu/mgcamctrl 现只兼容了大恒和海康,都是常用的 其他相机,看我老板啥时候换品牌吧,或者换老板? 当然如果小伙伴感兴

    2024年04月26日
    浏览(42)
  • 海康威视监控相机的SDK与opencv调用(非工业相机)

    本篇主要对海康威视的监控相机的SDK回调进行研究,并于opencv结合,保存图像,以供后续其他处理,开发语言为C++ 2.1 海康SDK介绍 海康SDK下载地址 根据自身编译环境,下载对应的SDK,需要注意的是,不要和工业相机SDK相混淆,工业相机好像是MVS是什么玩意儿,现在暂时没研究

    2024年02月04日
    浏览(52)
  • C++下OPENCV驱动调用海康GigE工业相机

    第一章 Ubuntu22下OpenCV4.6.0+contrib模块编译安装 第二章 ubuntu22下C++ kdevelop环境搭建:OpenCV示例 第三章 C++下OPENCV驱动调用海康GigE工业相机 在前两章内笔者详细叙述了如何编译以及加载opencv库,本文将从opencv出发,在linux系统下利用海康工业摄像机的SDK完成基于海康工业相机的o

    2024年02月06日
    浏览(44)
  • (三)Qt+OpenCV调用海康工业相机SDK抓拍示例

    提示:这里是该系列文章的所有文章的目录 第一章: (一)Qt+OpenCV调用海康工业相机SDK示例开发 第二章: (二)Qt多线程实现海康工业相机图像实时采集 第三章: (三)Qt+OpenCV调用海康工业相机SDK抓拍示例 在这系列文章中,讲述了Qt下结合OpenCV与海康工业相机的使用,对

    2024年04月08日
    浏览(78)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包