本文会介绍java对海康sdk的三个功能:
1、用代码实时抓图
2、用代码获取热成像仪21个点的坐标及其实时温度
3、针对海康热成像仪抓取的热图能够随便点击任意一个点就能获取其温度的功能。
第一个功能,抓图
抓图
在海康提供的sdk中取流后抓图调用的是
NET_DVR_RealPlay_V40命令本人jdk21一直抓图不成功,程序直接退出,后续调用
NET_DVR_RealPlay_V30抓图成功。
直接上代码
海康sdk集成到springboot中
依赖的路径
具体代码
功能二,获取21个配置点的坐标和温度
功能三,针对一张红外图点击任意一点,可以读取其温度
因为海康热成像仪只能导出最大256*192的温度矩阵,所以需要把抓到的图像素进行调整,如果你抓图是1280*960,需要把x和y除以5和256*192匹配。
功能一运行完会抓取一张红外图和一个csv的温度矩阵如图:
以上功能全部实现,海康的sdk可以去官方进行下载,我在里边做了相应的调整实现了相应的功能,如果按图不能实现欢迎各位留言,交流看到会进行回复
抓图和温度矩阵源码
import java.io.*; import java.nio.ByteBuffer; import java.text.SimpleDateFormat; import java.util.Date; import com.ydx.yemms.video.hk.NetSDKDemo.HCNetSDK; /** * Created by panting6 on 2021/2/21. */ public class JpegWithAppendData { static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE; public void jpegWithAppendData(int lUserID, int iChannelNum,String path,String newName) { boolean bRet = false; HCNetSDK.NET_DVR_JPEGPICTURE_WITH_APPENDDATA m_strJpegWithAppendData = new HCNetSDK.NET_DVR_JPEGPICTURE_WITH_APPENDDATA(); m_strJpegWithAppendData.dwSize = m_strJpegWithAppendData.size(); HCNetSDK.BYTE_ARRAY ptrJpegByte = new HCNetSDK.BYTE_ARRAY(4 * 1024 *1024); HCNetSDK.BYTE_ARRAY ptrP2PDataByte = new HCNetSDK.BYTE_ARRAY(2 * 1024 *1024); HCNetSDK.BYTE_ARRAY ptrVisiblePicByte = new HCNetSDK.BYTE_ARRAY(40*1024*1024); m_strJpegWithAppendData.pJpegPicBuff =ptrJpegByte.getPointer(); m_strJpegWithAppendData.pP2PDataBuff = ptrP2PDataByte.getPointer(); m_strJpegWithAppendData.pVisiblePicBuff = ptrVisiblePicByte.getPointer(); m_strJpegWithAppendData.dwJpegPicLen = 4 * 1024 *1024; m_strJpegWithAppendData.dwP2PDataLen = 2 * 1024 *1024; m_strJpegWithAppendData.dwVisiblePicLen = 40 * 1024 *1024; m_strJpegWithAppendData.write(); bRet=hCNetSDK.NET_DVR_CaptureJPEGPicture_WithAppendData(lUserID,iChannelNum,m_strJpegWithAppendData); if(bRet==true) { m_strJpegWithAppendData.read(); // System.out.println("NET_DVR_CaptureJPEGPicture_WithAppendData调用成功!图片和温度数据已保存在pic文件夹中,热成像有效区域:{" // + m_strJpegWithAppendData.struThermalValidRect.fX + "," + m_strJpegWithAppendData.struThermalValidRect.fY // + "," + m_strJpegWithAppendData.struThermalValidRect.fWidth + "," + m_strJpegWithAppendData.struThermalValidRect.fHeight + "},可见光有效区域:{" // + m_strJpegWithAppendData.struVisibleValidRect.fX + "," + m_strJpegWithAppendData.struVisibleValidRect.fY + "," + m_strJpegWithAppendData.struVisibleValidRect.fWidth // + "," + m_strJpegWithAppendData.struVisibleValidRect.fHeight + "}"); //测温数据 if (m_strJpegWithAppendData.dwP2PDataLen > 0) { // SimpleDateFormat sf = new SimpleDateFormat("yyyymmddHHmmss"); // String newName = sf.format(new Date()); File dir = new File(path); if (!dir.exists()){ dir.mkdir(); } FileOutputStream fout; BufferedWriter fout1; try { // fout = new FileOutputStream(".\\pic\\" + "测温" +newName+ ".data"); // ByteBuffer bufferss = m_strJpegWithAppendData.pP2PDataBuff.getByteBuffer(0, m_strJpegWithAppendData.dwP2PDataLen); // byte[] bytess = new byte[m_strJpegWithAppendData.dwP2PDataLen]; // bufferss.rewind(); // bufferss.get(bytess); // fout.write(bytess); // fout.close(); fout1 = new BufferedWriter(new FileWriter(dir+ "/" + newName + ".csv")); String tempdata =""; byte[] byTempData = new byte[4]; for (int i = 0; i < m_strJpegWithAppendData.dwJpegPicHeight; i++) { for (int j = 0; j < m_strJpegWithAppendData.dwJpegPicWidth; j++) { ByteBuffer TempDatabuffers = m_strJpegWithAppendData.pP2PDataBuff.getByteBuffer((j +i*m_strJpegWithAppendData.dwJpegPicWidth) * 4 , 4); TempDatabuffers.get(byTempData); int l; l = byTempData[0]; l &= 0xff; l |= ((long) byTempData[1] << 8); l &= 0xffff; l |= ((long) byTempData[2] << 16); l &= 0xffffff; l |= ((long) byTempData[3] << 24); //System.out.println("行数:" + i + "列数:" + j + "温度数据:" + Float.intBitsToFloat(l)); tempdata =" " + Float.intBitsToFloat(l); fout1.write(tempdata); fout1.write(","); }fout1.newLine(); }fout1.close(); } catch (FileNotFoundException e) { System.out.println("路径不存在"); } catch (IOException e) { System.out.println("异常"); } } //测温图片 if (m_strJpegWithAppendData.dwJpegPicLen > 0) { // SimpleDateFormat sf = new SimpleDateFormat("yyyymmddHHmmss"); // String newName = sf.format(new Date()); FileOutputStream pic; // FileOutputStream pic1; // FileOutputStream pic2; try { pic = new FileOutputStream(path+"/" + newName + ".jpg"); // pic1 = new FileOutputStream(".\\pic\\" + "测温_T"+newName + ".data"); // pic2 = new FileOutputStream(".\\pic\\" + "测温_V"+newName + ".jpg"); ByteBuffer buffers = m_strJpegWithAppendData.pJpegPicBuff.getByteBuffer(0, m_strJpegWithAppendData.dwJpegPicLen); ByteBuffer buffers1 = m_strJpegWithAppendData.pVisiblePicBuff.getByteBuffer(0, m_strJpegWithAppendData.dwVisiblePicLen); byte[] bytes = new byte[m_strJpegWithAppendData.dwJpegPicLen]; byte[] bytes1 = new byte[m_strJpegWithAppendData.dwVisiblePicLen]; buffers.rewind(); buffers.get(bytes); buffers1.rewind(); buffers1.get(bytes1); pic.write(bytes); // pic1.write(bytes); // pic2.write(bytes1); pic.close(); // pic1.close(); // pic2.close(); } catch (FileNotFoundException e) { System.out.println("路径不存在"); } catch (IOException e) { System.out.println("异常"); } } } else { System.out.println( "抓图叠加温度信息失败,错误码"+ hCNetSDK.NET_DVR_GetLastError()); } } }
从温度矩阵图中算出最大值和最小值和平均值
public Map<String, Object> getMaxAndMin(String csvPath) {
String filePath = csvPath;
int rows = 192; // 行数
int cols = 256; // 列数
double[][] matrix = new double[rows][cols];
double sum = 0;
// CSV文件路径
Map<String, Object> map = new HashMap<>();
File file = new File(filePath);
if (file.exists()) {
try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
String line;
int row = 0;
double max = Double.NEGATIVE_INFINITY;
double min = Double.POSITIVE_INFINITY;
while ((line = br.readLine()) != null) {
String[] values = line.split(",");
for (String value : values) {
double d = Double.parseDouble(value);
max = Math.max(max, d);
min = Math.min(min, d);
}
for (int col = 0; col < values.length; col++) {
matrix[row][col] = Double.parseDouble(values[col]);
sum += matrix[row][col];
}
row++;
}
// 计算平均值
double average = sum / (rows * cols);
map.put("max", String.format("%.1f", max).toString());
map.put("min", String.format("%.1f", min).toString());
map.put("average", String.format("%.1f", average).toString());
} catch (IOException e) {
e.printStackTrace();
}
} else {
System.out.println(filePath + "文件不存在");
}
return map;
}
}