海康工业相机MVS最新更新了4.0.1版本自带的SDK里面,BasicDemo
具体我没相机我也不能确定能不能行的通。不过按照我之前使用其他厂商的数据来说,一般这种都可以转成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()
上一节简述了读写缓存策略的主要思想,在这一节,结合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,读不到会报错。
pip install opencv-python
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())