海康SDK,python版BasicDemo

海康工业相机MVS最新更新了4.0.1版本自带的SDK里面,BasicDemo

img


用了这个接口显示,看不太懂,哪位能帮忙改成opencv显示吗,其他不要变,只改显示,相机型号CA060谢谢了

img

具体我没相机我也不能确定能不能行的通。不过按照我之前使用其他厂商的数据来说,一般这种都可以转成numpy格式。
举个例子来说,stDisplayParam这个看做一个结构体的话,那么按照他命名的含义来看
st.nWidth相当于图片的宽度,nHeight为图片的长度。那么剩下的就比较好办了,pixelType为图片的数据类型,pdata为图片指针,dataLen为指针长度。有了这些信息,那就可以根据他的这个结构体转成numpy格式的数组。
类似下面这样。当然,实际操作过程不一定可以用,还要考虑他的enPixelType是不是np支持的格式,如果不支持要怎么转换到np的数据类型,
pData指针是二进制的指针还是类似一个列表,如果是二进制的指针需要用类似np.fromstring()之类的转成二进制,然后使用opencv的imdecode函数转换等等。
而如果是c++的接口会更好转,这个结构体一看就清楚,只要知道他的各个的参数的定义就行了,python没有参数数据类型就比较繁琐一些。
以下为默认pData指针为一个列表,enPixelType为np.uint8,单通道图片就可以用这种方法来转换:


img=np.array(stDisplayParam.pData,dtype=stDisplayParam.enPixelType).reshape((stDisplayParam.nHeight,stDisplayParam.nWidth))

用摄像头捕获图像显示?

import cv2
cap = cv2.VideoCapture(0)
if not cap.isOpened():
    print("无法打开摄像头")
    exit()
while True:
    ret, frame = cap.read()
    if not ret:
        print("无法读取摄像头")
        break
    cv2.imshow('frame', frame)

    if cv2.waitKey(1) == 27:
        break
cap.release()
cv2.destroyAllWindows()


  • 这篇博客: 海康工业相机SDK + OpenCV实例(5):相机双线程读写缓存策略中的 三、相机双线程读写缓存策略 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 上一节简述了读写缓存策略的主要思想,在这一节,结合OpenCV的Mat矩阵与相机SDK,使用两个线程分别进行相机的取图与缓存区的读出。实例如下:

    //define buffer region
    cv::Mat srcImageA, srcImageB;
    mutex mutexBufferA, mutexBufferB;
    atomic_bool bufferAFull = false;
    atomic_bool bufferBFull = false;
    atomic_bool bufferRefreshA = false;
    bool CameraGrabImage()
    {
        nRet = MV_CC_GetImageBuffer(handle, &stImageInfo, 20000);
        if (nRet == MV_OK)
        {
        }
        else
        {
            printf("No data[0x%x]\n", nRet);
            return false;
        }
        if (bufferAFull == false)
        {
            mutexBufferA.lock();
            srcImageA = cv::Mat(stImageInfo.stFrameInfo.nHeight, stImageInfo.stFrameInfo.nWidth, CV_8UC1, stImageInfo.pBufAddr).clone();
            bufferRefreshA = false;
            bufferAFull = true;
            mutexBufferA.unlock();
        }
        else
        {
            if (bufferBFull == false)
            {
                mutexBufferB.lock();
                srcImageB = cv::Mat(stImageInfo.stFrameInfo.nHeight, stImageInfo.stFrameInfo.nWidth, CV_8UC1, stImageInfo.pBufAddr).clone();
                bufferRefreshA = true;
                bufferBFull = true;
                mutexBufferB.unlock();
            }
            else
            {
                if (bufferRefreshA)
                {
                    bufferAFull == false;
                    mutexBufferA.lock();
                    srcImageA = cv::Mat(stImageInfo.stFrameInfo.nHeight, stImageInfo.stFrameInfo.nWidth, CV_8UC1, stImageInfo.pBufAddr).clone();
                    bufferRefreshA = false;
                    bufferAFull = true;
                    mutexBufferA.unlock();
                }
                else
                {
                    bufferBFull == false;
                    mutexBufferB.lock();
                    srcImageB = cv::Mat(stImageInfo.stFrameInfo.nHeight, stImageInfo.stFrameInfo.nWidth, CV_8UC1, stImageInfo.pBufAddr).clone();
                    bufferRefreshA = true;
                    bufferBFull = true;
                    mutexBufferB.unlock();
                }
            }
        }
        nRet = MV_CC_FreeImageBuffer(handle, &stImageInfo);
        return true;
    
    }
    bool  ReadBuffer(cv::Mat &srcImage)
    {
        int waitTimeCount = 0;
    	while (true)
    	{
    		if (bufferAFull == true)
    		{
    			mutexBufferA.lock();
                srcImage = srcImageA;
    			bufferAFull = false;
    			mutexBufferA.unlock();
                break;
    		}
    		else
    		{
    			if (bufferBFull == true)
    			{
    				mutexBufferB.lock();
                    srcImage = srcImageB;
                    bufferBFull = false;
    				mutexBufferB.unlock();
                    break;
    			}
    			else
    			{
    				Sleep(10);
                    waitTimeCount++;
                    if (waitTimeCount == 100)
                    {
                        printf("ReadBuffer Over Time, waiting........\n");
                        return false;
                    }
    			}
    		}
    	}
        return true;
    }
    

    (1)MV_CC_GetImageBuffer从相机缓存取图。
    (2)相机缓存节点获取图像后,首先转化为mat格式,并写入本地缓存区域。
    (3)srcImageA与srcImageB是两个缓存区域,都是OpenCV的Mat格式。
    (4)readBuffer会等待1s,读不到会报错。


以下回答参考GPT,并由JoseKe整理完成,希望您能采纳:
根据问题描述,可以看出该问题是关于海康相机SDK的Python版BasicDemo的修改问题,需要将显示方式改成opencv显示。

首先,需要安装opencv库,可以使用以下命令进行安装:

pip install opencv-python

然后,在修改BasicDemo代码时,只需要将显示部分的代码改成使用opencv库来显示即可。具体代码修改如下:
python
from mvIMPACT import acquire, acquire_enumerations, acquire_submodules
import numpy as np
import cv2

if __name__ == "__main__":
devMgr = acquire.DeviceManager()
devCnt = devMgr.deviceCount()
if devCnt == 0:
print("No cameras found, exiting.")
exit(0)

dev = devMgr.getDevice(0)
dev.open()
requestFactory = acquire.getRequestFactory()
req = requestFactory.createRequest(dev, acquire_enumerations.TRequestType.eCapture)
devCtrl = acquire_submodules.DeviceControl(dev)
t = devCtrl ExposureTime_us

width = dev.getDataStream(0).info().width()
height = dev.getDataStream(0).info().height()
img = np.zeros((height, width), dtype=np.uint8)

devCtrl.ExposureTime_us = 10000
dev.startAcquisitionContinuous()
while True:
if dev.isDataAcquisitionRunning():
devCtrl.ExposureTime_us = t
devCtrl.autoGainControl = acquire_enumerations.TAutoGainControlMode.agcOff
devCtrl.gain_dB = 0
devCtrl.balanceWhiteAuto = acquire_enumerations.TWhiteBalanceAutoControlMode.wbacmOff
devCtrl.balanceRatioSelector = acquire_enumerations.TBalanceRatioSelector.wbbsRed
devCtrl.balanceRatio = 1.0
devCtrl.balanceRatioSelector = acquire_enumerations.TBalanceRatioSelector.wbbsGreen
devCtrl.balanceRatio = 1.0
devCtrl.balanceRatioSelector = acquire_enumerations.TBalanceRatioSelector.wbbsBlue
devCtrl.balanceRatio = 1.0
devCtrl.ExposureTime_us = t
devCtrl.triggerSoftware.Execute()
req.wait_for(5000)

if req.isOK:
dev.getImage(img.ctypes.data, img.size, acquire.FORMAT_MONO8, 1)
cv2.imshow('image', img)
cv2.waitKey(1)
else:
print("Error: ", req.errorCode(), req.errorDescription())

其中,cv2.imshow()和cv2.waitKey()两个函数就是用来显示图像的,将其放在循环内即可持续显示图像。需要注意的是,由于opencv的显示不支持单通道图像,因此需要将显示的原始图像数据类型设置为np.uint8。

在修改完成代码后,就可以通过运行该程序来使用opencv显示海康相机SDK的BasicDemo了。