# -- coding: utf-8 --
import os,sys,time,datetime,copy,inspect,random
import ctypes,msvcrt
import threading
import numpy as np
from ctypes import *
import cv2
sys.path.append("MvImport")
from MvCameraControl_class import *
import halcon as ha
user32=ctypes.windll.user32
import win32gui,win32con,win32api,win32process
point = win32api.GetCursorPos()# 获取当前鼠标【x y】坐标
def cmd(s="pause"):
os.system(s)
def open_window(width, height,row=0,column=0,father_window=0):
if os.name == 'nt':
ha.set_system('use_window_thread', 'true')
return ha.open_window(
row=row,
column=column,
width=width,
height=height,
father_window=0,
mode='visible',
machine=''
)
def ha_2_np(image):
before = time.time()
img=ha.himage_as_numpy_array(image)
after = time.time()
time_consuming=after-before
return time_consuming,img
def np__2_ha(img):
before = time.time()
image=ha.himage_from_numpy_array(img)
after = time.time()
time_consuming=after-before
return time_consuming,image
# 是否是Mono图像
def Is_mono_data(enGvspPixelType):
if PixelType_Gvsp_Mono8 == enGvspPixelType or PixelType_Gvsp_Mono10 == enGvspPixelType \
or PixelType_Gvsp_Mono10_Packed == enGvspPixelType or PixelType_Gvsp_Mono12 == enGvspPixelType \
or PixelType_Gvsp_Mono12_Packed == enGvspPixelType:
return True
else:
return False
# 是否是彩色图像
def Is_color_data(enGvspPixelType):
if PixelType_Gvsp_BayerGR8 == enGvspPixelType or PixelType_Gvsp_BayerRG8 == enGvspPixelType \
or PixelType_Gvsp_BayerGB8 == enGvspPixelType or PixelType_Gvsp_BayerBG8 == enGvspPixelType \
or PixelType_Gvsp_BayerGR10 == enGvspPixelType or PixelType_Gvsp_BayerRG10 == enGvspPixelType \
or PixelType_Gvsp_BayerGB10 == enGvspPixelType or PixelType_Gvsp_BayerBG10 == enGvspPixelType \
or PixelType_Gvsp_BayerGR12 == enGvspPixelType or PixelType_Gvsp_BayerRG12 == enGvspPixelType \
or PixelType_Gvsp_BayerGB12 == enGvspPixelType or PixelType_Gvsp_BayerBG12 == enGvspPixelType \
or PixelType_Gvsp_BayerGR10_Packed == enGvspPixelType or PixelType_Gvsp_BayerRG10_Packed == enGvspPixelType \
or PixelType_Gvsp_BayerGB10_Packed == enGvspPixelType or PixelType_Gvsp_BayerBG10_Packed == enGvspPixelType \
or PixelType_Gvsp_BayerGR12_Packed == enGvspPixelType or PixelType_Gvsp_BayerRG12_Packed == enGvspPixelType \
or PixelType_Gvsp_BayerGB12_Packed == enGvspPixelType or PixelType_Gvsp_BayerBG12_Packed == enGvspPixelType \
or PixelType_Gvsp_YUV422_Packed == enGvspPixelType or PixelType_Gvsp_YUV422_YUYV_Packed == enGvspPixelType:
return True
else:
return False
# Mono图像转为python数组
def Mono_numpy(data, nWidth, nHeight):
data_ = np.frombuffer(data, count=int(nWidth * nHeight), dtype=np.uint8, offset=0)
data_mono_arr = data_.reshape(nHeight, nWidth)
numArray = np.zeros([nHeight, nWidth, 1], "uint8")
numArray[:, :, 0] = data_mono_arr
return numArray
# 彩色图像转为python数组
def Color_numpy(data, nWidth, nHeight):
data_ = np.frombuffer(data, count=int(nWidth * nHeight * 3), dtype=np.uint8, offset=0)
data_r = data_[0:nWidth * nHeight * 3:3]
data_g = data_[1:nWidth * nHeight * 3:3]
data_b = data_[2:nWidth * nHeight * 3:3]
data_r_arr = data_r.reshape(nHeight, nWidth)
data_g_arr = data_g.reshape(nHeight, nWidth)
data_b_arr = data_b.reshape(nHeight, nWidth)
numArray = np.zeros([nHeight, nWidth, 3], "uint8")
numArray[:, :, 0] = data_r_arr
numArray[:, :, 1] = data_g_arr
numArray[:, :, 2] = data_b_arr
return numArray
def Write_image(file_out,img,f=".jpg"):
out = cv2.imencode(f, img) # 将图像编码到内存缓冲区中。
out[1].tofile(file_out) # 将数组中的数据以二进制格式写进文件
return 0
winfun_ctype = WINFUNCTYPE
stFrameInfo = POINTER(MV_FRAME_OUT_INFO_EX)
pData = POINTER(c_ubyte)
FrameInfoCallBack = winfun_ctype(None, pData, stFrameInfo, c_void_p)
Width=1280/2
Height=1024/2
WindowHandle1 =open_window(Width, Height)
def image_callback(pData, pFrameInfo, pUser):
r"""
[callback]
"""
stFrameInfo = cast(pFrameInfo, POINTER(MV_FRAME_OUT_INFO_EX)).contents
if stFrameInfo:
nWidth = stFrameInfo.nWidth
nHeight = stFrameInfo.nHeight
nFrameNum = stFrameInfo.nFrameNum
print(f" {nWidth} {nHeight} {nFrameNum}")
b = string_at(pData, nWidth * nHeight * 1)
nparr = np.frombuffer(b, np.uint8)
nparr = nparr.reshape(nHeight, nWidth, 1)
ty,img=np__2_ha(nparr)
ha.set_part(WindowHandle1,0,0,nHeight,nWidth)
ha.disp_obj(img, WindowHandle1);
#cv2.imshow(" dst ", nparr)
#cv2.waitKey(1)
CALL_BACK_FUN = FrameInfoCallBack(image_callback)
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:
if per == 0:
break
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 = input("please input the number of the device to connect:")
if int(nConnectionNum) >= deviceList.nDeviceNum:
print ("intput error!")
sys.exit()
cam = MvCamera()# ch:创建相机实例 | en:Creat Camera Object
# 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:Register image callback
ret = cam.MV_CC_RegisterImageCallBackEx(CALL_BACK_FUN,None)
if ret != 0:
print ("register image callback fail! ret[0x%x]" % ret)
sys.exit()
# ch:开始取流 | en:Start grab image
ret = cam.MV_CC_StartGrabbing()
if ret != 0:
print ("start grabbing fail! ret[0x%x]" % ret)
sys.exit()
print ("press a key to stop grabbing.")
msvcrt.getch()
ret = cam.MV_CC_StopGrabbing()# ch:停止取流 | en:Stop grab image
if ret != 0:
print ("stop grabbing fail! ret[0x%x]" % ret)
sys.exit()
# ch:关闭设备 | Close device
ret = cam.MV_CC_CloseDevice()
if ret != 0:
print ("close deivce fail! ret[0x%x]" % ret)
sys.exit()
# ch:销毁句柄 | Destroy handle
ret = cam.MV_CC_DestroyHandle()
if ret != 0:
print ("destroy handle fail! ret[0x%x]" % ret)
sys.exit()
官方Grab_Callback 改的,因官方例子不太完善, 这里用halcon做显示.
这个只能打开灰度相机.彩色相机么
if stFrameInfo:
nWidth = stFrameInfo.nWidth ;nHeight = stFrameInfo.nHeight ;nFrameNum = stFrameInfo.nFrameNum ;
print(f" {nWidth} {nHeight} {nFrameNum} {stFrameInfo.enPixelType} ")
b = string_at(pData, nWidth * nHeight * 3)
nparr = np.frombuffer(b, np.uint8)
nparr = nparr.reshape(nHeight, nWidth, 3)
ty,img=np__2_ha(nparr)
ha.set_part(WindowHandle1,0,0,nHeight,nWidth)
ha.disp_obj(img, WindowHandle1);
# ch:注册抓图回调 | en:Register image callback
ret = cam.MV_CC_RegisterImageCallBackForBGR(CALL_BACK_FUN,None)
if ret != 0:
print ("register image callback fail! ret[0x%x]" % ret)
sys.exit()
先暂时这样吧. 能用了已经 可以打开虚拟相机和真实的物理相机