package com.netsdk.demo.customize.radiometry; import com.netsdk.lib.ImageAlgLib; import com.netsdk.lib.NetSDKLib; import com.netsdk.lib.ToolKits; import com.netsdk.lib.structure.NET_IN_RADIOMETRY_RANDOM_REGION_TEMPER; import com.netsdk.lib.structure.NET_OUT_RADIOMETRY_RANDOM_REGION_TEMPER; import com.sun.jna.Pointer; import com.sun.jna.ptr.IntByReference; import javax.swing.*; import javax.swing.border.Border; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.File; import java.util.Arrays; class RadiometryDataParseFrame extends Frame { private static final long serialVersionUID = 1L; static NetSDKLib netsdkApi = NetSDKLib.NETSDK_INSTANCE; static NetSDKLib configsdkApi = NetSDKLib.CONFIG_INSTANCE; static ImageAlgLib imageAlgApi = ImageAlgLib.imageAlgApi; //登陆参数 private String m_strIp = "10.35.248.168"; private int m_nPort = 37777; private String m_strUser = "admin"; private String m_strPassword = "admin123"; private String m_channel = "1"; //图片数据缓存 private static NetSDKLib.NET_RADIOMETRY_DATA picBufMen = new NetSDKLib.NET_RADIOMETRY_DATA(); private static int nWidthMen = 0; private static int nHeightMen = 0; //设备信息 private static NetSDKLib.NET_DEVICEINFO_Ex m_stDeviceInfo = new NetSDKLib.NET_DEVICEINFO_Ex(); // 对应CLIENT_LoginEx2 private static NetSDKLib.LLong m_hLoginHandle = new NetSDKLib.LLong(0); // 登陆句柄 private NetSDKLib.LLong m_hAttachHandle = new NetSDKLib.LLong(0); // 智能订阅句柄 private NetSDKLib.LLong m_hRealPlayHandle = new NetSDKLib.LLong(0); // 实时预句柄 // 登录组件 private LoginPanel loginPanel; private JButton loginBtn; private JButton logoutBtn; private JLabel ipLabel; private JLabel nameLabel; private JLabel passwordLabel; private JLabel portLabel; private JLabel channelLabel; private JTextField ipTextArea; private JTextField portTextArea; private JTextField nameTextArea; private JTextField channelTextArea; private JPasswordField passwordTextArea; // 文本区域 private static JTextArea textArea; private JScrollPane scrollPane; private JButton getRandomRegionTemperBtn; private JButton attachBtn; private JButton fetchBtn; private JButton radiometryDataParseBtn; //////////////////SDK相关信息/////////////////////////// //NetSDK 库初始化 private boolean bInit = false; private boolean bLogopen = false; private DisConnect disConnect = new DisConnect(); //设备断线通知回调 private HaveReConnect haveReConnect = new HaveReConnect(); //网络连接恢复 //设备断线回调: 通过 CLIENT_Init 设置该回调函数,当设备出现断线时,SDK会调用该函数 public class DisConnect implements NetSDKLib.fDisConnect { public void invoke(NetSDKLib.LLong m_hLoginHandle, String pchDVRIP, int nDVRPort, Pointer dwUser) { System.out.printf("Device[%s] Port[%d] DisConnect!\n", pchDVRIP, nDVRPort); } } //网络连接恢复,设备重连成功回调 // 通过 CLIENT_SetAutoReconnect 设置该回调函数,当已断线的设备重连成功时,SDK会调用该函数 public class HaveReConnect implements NetSDKLib.fHaveReConnect { public void invoke(NetSDKLib.LLong m_hLoginHandle, String pchDVRIP, int nDVRPort, Pointer dwUser) { System.out.printf("ReConnect Device[%s] Port[%d]\n", pchDVRIP, nDVRPort); } } // 登陆前,设备初始化 public boolean init() { bInit = netsdkApi.CLIENT_Init(disConnect, null); if(!bInit) { System.out.println("Initialize SDK failed"); return false; } //打开日志,可选 NetSDKLib.LOG_SET_PRINT_INFO setLog = new NetSDKLib.LOG_SET_PRINT_INFO(); File path = new File("."); String logPath = path.getAbsoluteFile().getParent() + "\\sdk_log\\FaceRecognition_" + System.currentTimeMillis() + ".log"; setLog.bSetFilePath = 1; System.arraycopy(logPath.getBytes(), 0, setLog.szLogFilePath, 0, logPath.getBytes().length); setLog.bSetPrintStrategy = 1; setLog.nPrintStrategy = 0; bLogopen = netsdkApi.CLIENT_LogOpen(setLog); if(!bLogopen ) { System.err.println("Failed to open NetSDK log"); } // 设置断线重连回调接口,设置过断线重连成功回调函数后,当设备出现断线情况,SDK内部会自动进行重连操作 // 此操作为可选操作,但建议用户进行设置 netsdkApi.CLIENT_SetAutoReconnect(haveReConnect, null); //设置登录超时时间和尝试次数,可选 int waitTime = 5000; //登录请求响应超时时间设置为5S int tryTimes = 3; //登录时尝试建立链接3次 netsdkApi.CLIENT_SetConnectTime(waitTime, tryTimes); // 设置更多网络参数,NET_PARAM的nWaittime,nConnectTryNum成员与CLIENT_SetConnectTime // 接口设置的登录设备超时时间和尝试次数意义相同,可选 NetSDKLib.NET_PARAM netParam = new NetSDKLib.NET_PARAM(); netParam.nConnectTime = 10000; //登录时尝试建立链接的超时时间 netsdkApi.CLIENT_SetNetworkParam(netParam); return true; } // 关闭工程前,清除环境,释放内存 public void cleanup() { if(bLogopen) { netsdkApi.CLIENT_LogClose(); } if(bInit) { netsdkApi.CLIENT_Cleanup(); } } public RadiometryDataParseFrame() { init(); setTitle("RadiometryDataParse"); setSize(950, 500); setLayout(new BorderLayout()); setLocationRelativeTo(null); setVisible(true); loginPanel = new LoginPanel(); // 登陆面板 // 操作面板 GroupPanel groupPanel = new GroupPanel(); // 文本框 TextPanel textPanel = new TextPanel(); add(loginPanel, BorderLayout.NORTH); add(groupPanel, BorderLayout.WEST); add(textPanel, BorderLayout.CENTER); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.out.println("Window Closing"); //登出 logout(); cleanup(); dispose(); } }); } /*********************************************************************************************** * 界面布局面板 * ***********************************************************************************************/ //设置边框 private void setBorderEx(JComponent object, String title, int width) { Border innerBorder = BorderFactory.createTitledBorder(title); Border outerBorder = BorderFactory.createEmptyBorder(width, width, width, width); object.setBorder(BorderFactory.createCompoundBorder(outerBorder, innerBorder)); } //登录面板 public class LoginPanel extends JPanel { /** * */ private static final long serialVersionUID = 1L; public LoginPanel() { loginBtn = new JButton("登录"); logoutBtn = new JButton("登出"); nameLabel = new JLabel("用户名"); passwordLabel = new JLabel("密码"); nameTextArea = new JTextField(m_strUser, 6); passwordTextArea = new JPasswordField(m_strPassword, 6); ipLabel = new JLabel("设备地址"); portLabel = new JLabel("端口号"); ipTextArea = new JTextField(m_strIp, 8); portTextArea = new JTextField(String.valueOf(m_nPort), 4); setLayout(new FlowLayout()); setBorderEx(this, "登录", 10); add(ipLabel); add(ipTextArea); add(portLabel); add(portTextArea); add(nameLabel); add(nameTextArea); add(passwordLabel); add(passwordTextArea); add(loginBtn); add(logoutBtn); logoutBtn.setEnabled(false); //登录按钮,监听事件 loginBtn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if(login()) { loginBtn.setEnabled(false); logoutBtn.setEnabled(true); getRandomRegionTemperBtn.setEnabled(true); attachBtn.setEnabled(true); fetchBtn.setEnabled(true); radiometryDataParseBtn.setEnabled(true); } } }); //登出按钮,监听事件 logoutBtn.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { if(logout()) { loginBtn.setEnabled(true); logoutBtn.setEnabled(false); getRandomRegionTemperBtn.setEnabled(false); attachBtn.setEnabled(false); fetchBtn.setEnabled(false); radiometryDataParseBtn.setEnabled(false); } } }); } } // 操作面板 public class GroupPanel extends JPanel { public GroupPanel(){ setBorderEx(this, "操作面板", 10); Dimension dim = this.getPreferredSize(); dim.height = 10; dim.width = 400; this.setPreferredSize(dim); setLayout(new GridLayout(6,1,10,10)); JPanel panel1 = new JPanel();//写个单行panel JPanel panel2 = new JPanel();//写个单行panel JPanel panel3 = new JPanel();//写个单行panel JPanel panel4 = new JPanel();//写个单行panel JPanel panel5 = new JPanel();//写个单行panel channelLabel = new JLabel("Channel(通道号):"); channelTextArea = new JTextField(m_channel, 6); getRandomRegionTemperBtn = new JButton("GetRandomRegionTemper"); attachBtn = new JButton("Attach(订阅)"); fetchBtn = new JButton("Fetch(获取热图数据)"); radiometryDataParseBtn = new JButton("RadiometryDataParse"); getRandomRegionTemperBtn.setPreferredSize(new Dimension(200, getRandomRegionTemperBtn.getPreferredSize().height)); attachBtn.setPreferredSize(new Dimension(200, attachBtn.getPreferredSize().height)); fetchBtn.setPreferredSize(new Dimension(200, fetchBtn.getPreferredSize().height)); radiometryDataParseBtn.setPreferredSize(new Dimension(200, radiometryDataParseBtn.getPreferredSize().height)); panel1.add(channelLabel); panel1.add(channelTextArea); panel2.add(getRandomRegionTemperBtn); panel3.add(attachBtn); panel4.add(fetchBtn); panel5.add(radiometryDataParseBtn); add(panel1); add(panel2); add(panel3); add(panel4); add(panel5); getRandomRegionTemperBtn.setEnabled(false); attachBtn.setEnabled(false); fetchBtn.setEnabled(false); radiometryDataParseBtn.setEnabled(false); //订阅温度分布数据(热图) getRandomRegionTemperBtn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { radiometryGetRandomRegionTemper(); } }); //Attach(订阅) attachBtn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if(m_hAttachHandle.longValue() != 0){ radiometryDetach(); }else { radiometryAttach(); } } }); //Fetch(获取热图数据) fetchBtn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { radiometryFetch(); } }); //radiometryDataParse 解析图片数据 radiometryDataParseBtn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { radiometryDataParse(); } }); } } //文本框 public class TextPanel extends JPanel { public TextPanel(){ GridBagLayout layout = new GridBagLayout(); GridBagConstraints constraints = new GridBagConstraints(); constraints.fill = GridBagConstraints.BOTH; // 填充整个可用空间 constraints.weightx = 1.0; // 设置水平拉伸权重为1.0 constraints.weighty = 1.0; // 设置垂直拉伸权重为1.0 setLayout(layout); setBorderEx(this, "文本框", 10); scrollPane = new JScrollPane();//创建滚动条面板 //分别设置水平和垂直滚动条自动出现 (默认是这种) scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); textArea = new JTextArea(10,10); textArea.setLineWrap(true); //设置文本域自动换行 textArea.setBounds(500, 200, 500, 200); textArea.setLayout(layout); scrollPane.setViewportView(textArea);//(这是关键!不是用add)把text1组件放到滚动面板里 add(scrollPane,constraints); } } /*********************************************************************************************** * 具体功能的接口实现 * ***********************************************************************************************/ // 登录按钮事件 private boolean login() { m_strIp = ipTextArea.getText(); m_nPort = Integer.parseInt(portTextArea.getText()); m_strUser = nameTextArea.getText(); m_strPassword = new String(passwordTextArea.getPassword()); textArea.append("设备地址:" + m_strIp + "\n端口号:" + m_nPort + "\n用户名:" + m_strUser + "\n密码:" + m_strPassword + "\n"); int nSpecCap = NetSDKLib.EM_LOGIN_SPAC_CAP_TYPE.EM_LOGIN_SPEC_CAP_TCP; //=0 IntByReference nError = new IntByReference(0); m_hLoginHandle = netsdkApi.CLIENT_LoginEx2(m_strIp, m_nPort, m_strUser, m_strPassword, nSpecCap, null, m_stDeviceInfo, nError); if(m_hLoginHandle.longValue() == 0) { System.err.printf("Login Device[%s] Port[%d]Failed.\n", m_strIp, m_nPort, ToolKits.getErrorCode()); JOptionPane.showMessageDialog(this, "Login Failed,Error :" + ToolKits.getErrorCode()); return false; } else { textArea.append("Login Success [ " + m_strIp + " ]\n"); } return true; } // 登出按钮事件 private boolean logout() { if(m_hLoginHandle.longValue() != 0) { textArea.append("Logout Button Action\n"); if(netsdkApi.CLIENT_Logout(m_hLoginHandle)) { textArea.append("Logout Success [ " + m_strIp + " ]\n"); m_hLoginHandle.setValue(0); return true; } } return false; } /** * 获取测温区域 */ public void radiometryGetRandomRegionTemper(){ NetSDKLib.LLong loginHandle = m_hLoginHandle; int channel = Integer.parseInt(channelTextArea.getText()); NET_IN_RADIOMETRY_RANDOM_REGION_TEMPER stIn = new NET_IN_RADIOMETRY_RANDOM_REGION_TEMPER(); NET_OUT_RADIOMETRY_RANDOM_REGION_TEMPER stOut = new NET_OUT_RADIOMETRY_RANDOM_REGION_TEMPER(); stIn.nChannel = channel; stIn.nPointNum = 1; stIn.stuPolygon[0].nx = 100; stIn.stuPolygon[0].ny = 100; stIn.write(); stOut.write(); boolean bet = netsdkApi.CLIENT_RadiometryGetRandomRegionTemper(loginHandle,stIn.getPointer(),stOut.getPointer(), 3000); stIn.read(); stOut.read(); if(bet) { textArea.append("GetRandomRegionTemper success\n"); switch (stOut.stuRegionTempInfo.emTemperatureUnit) { case 0:{ textArea.append("温度单位:摄氏度\n"); break; } case 1:{ textArea.append("温度单位:华氏度\n"); break; } case 2:{ textArea.append("温度单位:开尔文\n"); break; } default:{ textArea.append("温度单位:未知\n"); break; } } textArea.append("平均温度:" + new Float(stOut.stuRegionTempInfo.nTemperAver)/100 + "\n"); textArea.append("最高温度:" + new Float(stOut.stuRegionTempInfo.nTemperMax)/100 + "\n"); textArea.append("最低温度:" + new Float(stOut.stuRegionTempInfo.nTemperMin)/100 + "\n"); textArea.append("最高温坐标:" + stOut.stuRegionTempInfo.stuTemperMaxPoint.nx + ":" + stOut.stuRegionTempInfo.stuTemperMaxPoint.ny + "\n"); textArea.append("最低温坐标:" + stOut.stuRegionTempInfo.stuTemperMinPoint.nx + ":" + stOut.stuRegionTempInfo.stuTemperMinPoint.ny + "\n\n"); }else { textArea.append("GetRandomRegionTemper fail. reason:" + ToolKits.getErrorCode() + "\n"); System.err.println("获取测温区域的参数值失败," + ToolKits.getErrorCode()+ "\n"); } } /** * 订阅温度分布数据 */ public void radiometryAttach() { // 登录句柄 NetSDKLib.LLong loginHandle = m_hLoginHandle; // 通道号 int channel = Integer.parseInt(channelTextArea.getText()); /* * 入参 */ NetSDKLib.NET_IN_RADIOMETRY_ATTACH stIn = new NetSDKLib.NET_IN_RADIOMETRY_ATTACH(); stIn.nChannel = channel; // 通道号 stIn.cbNotify = RadiometryAttachCB.getInstance(); // 回调函数 /* * 出参 */ NetSDKLib.NET_OUT_RADIOMETRY_ATTACH stOut = new NetSDKLib.NET_OUT_RADIOMETRY_ATTACH(); m_hAttachHandle = netsdkApi.CLIENT_RadiometryAttach(loginHandle, stIn, stOut, 3000); if(m_hAttachHandle.longValue() != 0) { textArea.append("Attach success!\n\n"); attachBtn.setText("Detach(退订)"); } else { textArea.append("Attach fail! reason" + ToolKits.getErrorCode() + "\n\n"); } // 滚动到最新的追加内容 textArea.setCaretPosition(textArea.getDocument().getLength()); } /** * 获取热图数据 */ String[] status = {"未知", "空闲", "获取热图中"}; public void radiometryFetch() { // 登录句柄 NetSDKLib.LLong loginHandle = m_hLoginHandle; // 通道号 int channel = Integer.parseInt(channelTextArea.getText()); /* * 入参 */ NetSDKLib.NET_IN_RADIOMETRY_FETCH stIn = new NetSDKLib.NET_IN_RADIOMETRY_FETCH(); stIn.nChannel = channel; // 通道号 /* * 出参 */ NetSDKLib.NET_OUT_RADIOMETRY_FETCH stOut = new NetSDKLib.NET_OUT_RADIOMETRY_FETCH(); if(netsdkApi.CLIENT_RadiometryFetch(loginHandle, stIn, stOut, 3000)) { textArea.append("RadiometryFetch success\n"); textArea.append("开始获取热图数据, 状态 : " + status[stOut.nStatus] + "\n\n"); }else { textArea.append("RadiometryFetch fail.reason:" + ToolKits.getErrorCode() + "\n\n"); } // 滚动到最新的追加内容 textArea.setCaretPosition(textArea.getDocument().getLength()); } /** * 订阅回调 */ private static class RadiometryAttachCB implements NetSDKLib.fRadiometryAttachCB { private RadiometryAttachCB() {} private static class RadiometryAttachCBHolder { private static RadiometryAttachCB instance = new RadiometryAttachCB(); } public static RadiometryAttachCB getInstance() { return RadiometryAttachCB.RadiometryAttachCBHolder.instance; } @Override public void invoke(NetSDKLib.LLong lAttachHandle, final NetSDKLib.NET_RADIOMETRY_DATA pBuf, int nBufLen, Pointer dwUser) { /*new Thread() { final NET_RADIOMETRY_DATA stuData = pBuf; public void run() { try { sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } dealRadiometryData(stuData); // 此处同步处理,如需异步,需要拷贝pBuf }; }.start();*/ dealRadiometryData(pBuf); // 此处同步处理,如需异步,需要拷贝pBuf } } /** * 处理回调数据(热图) */ private static void dealRadiometryData(NetSDKLib.NET_RADIOMETRY_DATA pBuf) { picBufMen = pBuf; int nWidth = pBuf.stMetaData.nWidth; nWidthMen = nWidth; int nHeight = pBuf.stMetaData.nHeight; nHeightMen = nHeight; int nChannel = pBuf.stMetaData.nChannel; NetSDKLib.NET_TIME stTime = pBuf.stMetaData.stTime; int nLength = pBuf.stMetaData.nLength; String szSensorType = new String(pBuf.stMetaData.szSensorType); textArea.append("Height:" + nHeight + "\n"); textArea.append("Width:" + nWidth + "\n"); textArea.append("nChannel:" + nChannel + "\n"); textArea.append("stTime:" + stTime.toStringTime()+ "\n"); textArea.append("nLength:" + nLength + "\n"); textArea.append("szSensorType:" + szSensorType + "\n"); textArea.append("解析完成\n\n"); // 滚动到最新的追加内容 textArea.setCaretPosition(textArea.getDocument().getLength()); } /** * 取消订阅温度分布区域 */ public void radiometryDetach() { if(m_hAttachHandle.longValue() != 0) { netsdkApi.CLIENT_RadiometryDetach(m_hAttachHandle); m_hAttachHandle.setValue(0); } attachBtn.setText("Attach(订阅)"); textArea.append("detach success!\n\n"); textArea.setCaretPosition(textArea.getDocument().getLength()); } /** * 解析热图数据 */ public void radiometryDataParse(){ short[] pGrayImg = new short[nWidthMen * nHeightMen]; float[] pTempForPixels = new float[nWidthMen * nHeightMen]; if(netsdkApi.CLIENT_RadiometryDataParse(picBufMen, pGrayImg, pTempForPixels)) { byte[] pYData = new byte[nWidthMen*nHeightMen*2]; imageAlgApi.drcTable(pGrayImg, (short)nWidthMen, (short)nHeightMen, 0, pYData, null); ToolKits.savePicture(pYData, "./RAW.yuv"); Arrays.sort(pTempForPixels); textArea.append("radiometryDataParse success\n\n"); textArea.append("最低温度:" + pTempForPixels[0] + "\n"); textArea.append("最高温度:" + pTempForPixels[nWidthMen * nHeightMen-1] + "\n\n"); } else { textArea.append("radiometryDataParse fail.reason:\n\n" + ToolKits.getLastError()); return; } } } public class RadiometryDataParse { public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { RadiometryDataParseFrame demo = new RadiometryDataParseFrame(); demo.setVisible(true); } }); } }