海康工业相机对接彩色视频流
This commit is contained in:
@@ -10,7 +10,7 @@ import top.wms.admin.controller.weighManage.ah.ScaleWebSocketHandler;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSocket
|
||||
public class webSocket implements WebSocketConfigurer {
|
||||
public class WebSocketConfig implements WebSocketConfigurer {
|
||||
|
||||
@Autowired
|
||||
private CameraWebSocketHandler cameraWebSocketHandler;
|
||||
@@ -19,7 +19,7 @@ public class webSocket implements WebSocketConfigurer {
|
||||
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
|
||||
// 注册WebSocket端点,允许所有跨域请求
|
||||
registry.addHandler(new ScaleWebSocketHandler(), "/ws/scale").setAllowedOrigins("*");
|
||||
// 注册海康相机WebSocket端点
|
||||
// 注册海康相机1 WebSocket端点
|
||||
registry.addHandler(cameraWebSocketHandler, "/ws/camera").setAllowedOrigins("*");
|
||||
}
|
||||
}
|
||||
@@ -76,8 +76,6 @@ public class CameraService {
|
||||
if (null == stDeviceInfo) {
|
||||
continue;
|
||||
}
|
||||
log.info("[camera {}}", i++);
|
||||
printDeviceInfo(stDeviceInfo);
|
||||
}
|
||||
|
||||
// 默认选择第一个设备
|
||||
@@ -110,6 +108,15 @@ public class CameraService {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 设置Bayer转换质量,用于彩色相机
|
||||
log.info("Setting Bayer convert quality...");
|
||||
nRet = MvCameraControl.MV_CC_SetBayerCvtQuality(hCamera, 1);
|
||||
if (MV_OK != nRet) {
|
||||
log.error("Set Bayer convert quality fail! nRet [0x{0}]", Integer.toHexString(nRet));
|
||||
closeCamera();
|
||||
return false;
|
||||
}
|
||||
|
||||
log.info("Camera initialized successfully");
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
@@ -140,7 +147,6 @@ public class CameraService {
|
||||
int nRet = MvCameraControl.MV_CC_RegisterImageCallBack(hCamera, new CameraImageCallBack() {
|
||||
@Override
|
||||
public int OnImageCallBack(byte[] bytes, MV_FRAME_OUT_INFO mv_frame_out_info) {
|
||||
printFrameInfo(mv_frame_out_info);
|
||||
processImage(bytes, mv_frame_out_info);
|
||||
return 0;
|
||||
}
|
||||
@@ -226,6 +232,7 @@ public class CameraService {
|
||||
|
||||
/**
|
||||
* 处理图像数据
|
||||
*
|
||||
* @param bytes 原始图像数据
|
||||
* @param frameInfo 帧信息
|
||||
*/
|
||||
@@ -242,13 +249,37 @@ public class CameraService {
|
||||
}
|
||||
lastFrameTime = currentTime;
|
||||
|
||||
// 打印帧信息,以便调试
|
||||
printFrameInfo(frameInfo);
|
||||
int dataSizeForRGB = frameInfo.width * frameInfo.height * 3; // RGB每个像素3字节
|
||||
byte[] pDataForRGB = new byte[dataSizeForRGB];
|
||||
|
||||
// 对于黑白相机(MV-CE050-30GM),数据是单通道灰度格式
|
||||
// 将原始灰度数据转换为BufferedImage
|
||||
BufferedImage image = new BufferedImage(frameInfo.width, frameInfo.height, BufferedImage.TYPE_BYTE_GRAY);
|
||||
image.getRaster().setDataElements(0, 0, frameInfo.width, frameInfo.height, bytes);
|
||||
// 初始化像素转换参数
|
||||
MV_CC_PIXEL_CONVERT_PARAM_EX stConvertParam = new MV_CC_PIXEL_CONVERT_PARAM_EX();
|
||||
|
||||
// 使用实际的width和height,避免ExtendHeight为0的问题
|
||||
stConvertParam.width = frameInfo.width;
|
||||
stConvertParam.height = frameInfo.height;
|
||||
stConvertParam.srcData = bytes;
|
||||
stConvertParam.srcDataLen = frameInfo.frameLen;
|
||||
stConvertParam.srcPixelType = frameInfo.pixelType;
|
||||
stConvertParam.dstPixelType = MvGvspPixelType.PixelType_Gvsp_RGB8_Packed;
|
||||
stConvertParam.dstBuffer = pDataForRGB;
|
||||
stConvertParam.dstBufferSize = dataSizeForRGB;
|
||||
|
||||
// 尝试进行像素格式转换
|
||||
int nRet = MvCameraControl.MV_CC_ConvertPixelTypeEx(hCamera, stConvertParam);
|
||||
if (MV_OK != nRet) {
|
||||
log.error("Convert PixelType fail, errCode: {}, srcPixelType: {}, width: {}, height: {}",
|
||||
Integer.toHexString(nRet),
|
||||
frameInfo.pixelType.getnValue(),
|
||||
frameInfo.width,
|
||||
frameInfo.height);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 将RGB数据转换为BufferedImage
|
||||
BufferedImage image = new BufferedImage(frameInfo.width, frameInfo.height, BufferedImage.TYPE_3BYTE_BGR);
|
||||
image.getRaster().setDataElements(0, 0, frameInfo.width, frameInfo.height, pDataForRGB);
|
||||
|
||||
// 压缩图像为JPEG格式
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
@@ -256,8 +287,8 @@ public class CameraService {
|
||||
byte[] compressedData = baos.toByteArray();
|
||||
baos.close();
|
||||
|
||||
log.debug("Original size: {} bytes, Compressed size: {} bytes, Compression ratio: {:.2f}%",
|
||||
bytes.length, compressedData.length, (1 - (double)compressedData.length / bytes.length) * 100);
|
||||
log.debug("Original size: {} bytes, Converted size: {} bytes, Compressed size: {} bytes, Compression ratio: {:.2f}%",
|
||||
bytes.length, pDataForRGB.length, compressedData.length, (1 - (double) compressedData.length / bytes.length) * 100);
|
||||
|
||||
// 创建包含图像尺寸信息和压缩数据的消息
|
||||
// 消息格式: [width(4 bytes)][height(4 bytes)][image data]
|
||||
@@ -346,59 +377,4 @@ public class CameraService {
|
||||
return isRunning;
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印设备信息
|
||||
* @param stDeviceInfo 设备信息
|
||||
*/
|
||||
private void printDeviceInfo(MV_CC_DEVICE_INFO stDeviceInfo) {
|
||||
if (null == stDeviceInfo) {
|
||||
log.error("stDeviceInfo is null");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((stDeviceInfo.transportLayerType == MV_GIGE_DEVICE) || (stDeviceInfo.transportLayerType == MV_GENTL_GIGE_DEVICE)) {
|
||||
log.info("\tCurrentIp: {}", stDeviceInfo.gigEInfo.currentIp);
|
||||
log.info("\tModel: {}", stDeviceInfo.gigEInfo.modelName);
|
||||
log.info("\tUserDefinedName: {}", stDeviceInfo.gigEInfo.userDefinedName);
|
||||
} else if (stDeviceInfo.transportLayerType == MV_USB_DEVICE) {
|
||||
log.info("\tUserDefinedName: {}", stDeviceInfo.usb3VInfo.userDefinedName);
|
||||
log.info("\tSerial Number: {}", stDeviceInfo.usb3VInfo.serialNumber);
|
||||
log.info("\tDevice Number: {}", stDeviceInfo.usb3VInfo.deviceNumber);
|
||||
} else if (stDeviceInfo.transportLayerType == MV_GENTL_CAMERALINK_DEVICE) {
|
||||
log.info("\tUserDefinedName: {}", stDeviceInfo.cmlInfo.userDefinedName);
|
||||
log.info("\tSerial Number: {}", stDeviceInfo.cmlInfo.serialNumber);
|
||||
log.info("\tDevice Number: {}", stDeviceInfo.cmlInfo.DeviceID);
|
||||
} else if (stDeviceInfo.transportLayerType == MV_GENTL_CXP_DEVICE) {
|
||||
log.info("\tUserDefinedName: {}", stDeviceInfo.cxpInfo.userDefinedName);
|
||||
log.info("\tSerial Number: {}", stDeviceInfo.cxpInfo.serialNumber);
|
||||
log.info("\tDevice Number: {}", stDeviceInfo.cxpInfo.DeviceID);
|
||||
} else if (stDeviceInfo.transportLayerType == MV_GENTL_XOF_DEVICE) {
|
||||
log.info("\tUserDefinedName: {}", stDeviceInfo.xofInfo.userDefinedName);
|
||||
log.info("\tSerial Number: {}", stDeviceInfo.xofInfo.serialNumber);
|
||||
log.info("\tDevice Number: {}", stDeviceInfo.xofInfo.DeviceID);
|
||||
} else {
|
||||
log.error("Device is not supported! ");
|
||||
}
|
||||
|
||||
log.info("\tAccessible: {}", MvCameraControl.MV_CC_IsDeviceAccessible(stDeviceInfo, MV_ACCESS_Exclusive));
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印帧信息
|
||||
* @param stFrameInfo 帧信息
|
||||
*/
|
||||
private void printFrameInfo(MV_FRAME_OUT_INFO stFrameInfo) {
|
||||
if (null == stFrameInfo) {
|
||||
log.error("stFrameInfo is null");
|
||||
return;
|
||||
}
|
||||
|
||||
StringBuilder frameInfo = new StringBuilder("");
|
||||
frameInfo.append(("\tFrameNum[" + stFrameInfo.frameNum + "]"));
|
||||
frameInfo.append("\tWidth[" + stFrameInfo.width + "]");
|
||||
frameInfo.append("\tHeight[" + stFrameInfo.height + "]");
|
||||
frameInfo.append(String.format("\tPixelType[%#x]", stFrameInfo.pixelType.getnValue()));
|
||||
|
||||
log.debug(frameInfo.toString());
|
||||
}
|
||||
}
|
||||
@@ -140,35 +140,19 @@ public class ConvertPixelType
|
||||
// Choose a device to operate
|
||||
int camIndex = -1;
|
||||
|
||||
while (true)
|
||||
{
|
||||
System.out.print("Please input camera index:");
|
||||
if (scanner.hasNextInt())
|
||||
{
|
||||
try
|
||||
{
|
||||
camIndex = scanner.nextInt();
|
||||
if ((camIndex >= 0 && camIndex < stDeviceList.size()) || -1 == camIndex)
|
||||
{
|
||||
while (true) {
|
||||
try {
|
||||
camIndex = 0;
|
||||
if ((camIndex >= 0 && camIndex < stDeviceList.size()) || -1 == camIndex) {
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
System.out.println("Input error: " + camIndex + " Over Range:( 0 - " + (stDeviceList.size() - 1) + " )");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
} catch (Exception e) {
|
||||
System.out.println("Input not number.");
|
||||
camIndex = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
camIndex = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
if (-1 == camIndex) {
|
||||
@@ -328,7 +312,7 @@ public class ConvertPixelType
|
||||
System.err.printf("set Bayer convert quality fail! nRet [0x%x]\n", nRet);
|
||||
break;
|
||||
}
|
||||
|
||||
System.out.println("临时日志: frameInfo.width = " + stImageInfo.width + ", frameInfo.height = " + stImageInfo.height + ", frameInfo.ExtendWidth = " + stImageInfo.ExtendWidth + ", frameInfo.ExtendHeight = " + stImageInfo.ExtendHeight + ", frameInfo.frameLen = " + stImageInfo.frameLen + ", frameInfo.pixelType = " + stImageInfo.pixelType);
|
||||
int dataSizeForRGB = stImageInfo.width * stImageInfo.height * 3; // every RGB pixel takes 3 bytes
|
||||
byte[] pDataForRGB = new byte[dataSizeForRGB];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user