# 红外热成像测温app **Repository Path**: kangchang/thermography ## Basic Information - **Project Name**: 红外热成像测温app - **Description**: 红外 热成像 测温 温度矩阵 无线测温 远程测温 - **Primary Language**: Dart - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 24 - **Forks**: 0 - **Created**: 2020-11-17 - **Last Updated**: 2026-01-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ### 以下算法均为自研 ### 8.实时识别并标记算法
### 1.调试演示所用传感器为8×8像素(IR64) ``` 本次红外传感器比较小只有64个像素,无法准备描绘出物体轮廓,所以才需要插值提升像素。分辨率较高的传感器也可以插值锐化边缘,抗锯齿。 ``` ### 2.移动端显示 ``` 本次测试使用的是5Hz,传感器每秒发送5次数据,移动端每秒渲染5次热成像画面。实时度高的场景可以增加频率。 ``` ### 3.温度数组转为温度矩阵算法 ``` 由于红外传感器上报给服务器的数据是一维数组,要想显示图像就需要将数据转为二维数组矩阵 //传感器横轴像素 int sourcePixelRowCount = 8; int len = temperatureList.length; //传感器纵轴像素 int lineNum = len % sourcePixelRowCount == 0 ? (len ~/ sourcePixelRowCount).toInt() : ((len / sourcePixelRowCount) + 1).floor(); for (var i = 0; i < lineNum; i++) { int startIndex = i * sourcePixelRowCount; //截取数组指定长度后生成新数组 Iterable range = temperatureList.getRange(startIndex ,startIndex + sourcePixelRowCount); temperature.add(range.toList()); } ``` ### 4.画面镜像翻转,矩阵重新排序 ``` 如果不进行镜像翻转,显示的画面将和实际的画面是相反的,左右相反 ``` ### 5.双三次多项式插值提升像素算法 ``` 插值提升像素,锐化边缘后,提升后像素为32×32,看下图片基本可以看到物体轮廓了。 //计算权重 static dynamic getCubicWeight(double v) { double a = -0.5; // 取整 int nv = v.floor(); // 坐标差值集合 List xList = new List(4); // 坐标集合 List xs = new List(4); // 最近的4个坐标差值 xList[0] = nv - v - 1; xList[1] = nv - v; xList[2] = nv - v + 1; xList[3] = nv - v + 2; // xs[0] = nv - 1; xs[1] = nv; xs[2] = nv + 1; xs[3] = nv + 2; // 计算权重 List ws = List(4); for (int i = 0; i < 4; i++) { double val = xList[i].abs(); double w = 0; // 基于BiCubic基函数的双三次插值 if (val <= 1) { w = (a + 2) * val * val * val - (a + 3) * val * val + 1; } else if (val < 2) { w = a * val * val * val - 5 * a * val * val + 8 * a * val - 4 * a; } ws[i] = w; } return {'weight': ws, 'coordinate': xs}; } ``` ### 6.温度数值转为RGB色彩编码算法,想要色阶越多可以用255/色阶数,我用的4 ``` //将温度转为RGB,用64将颜色分为4个区间,可以分为更多区间比如51(自研) RGB grayToPseColor(int grayValue) { if (grayValue > 255) { return RGB(255, 0, 0); } if (grayValue < 0) { return RGB(0, 0, 0); } if ((grayValue >= 0) && (grayValue <= 63)) { return RGB(0, 0, (grayValue / 64 * 255).round()); } else if ((grayValue >= 64) && (grayValue <= 127)) { return RGB(0, ((grayValue - 64) / 64 * 255).round(),((127 - grayValue) / 64 * 255).round()); } else if ((grayValue >= 128) && (grayValue <= 191)) { return RGB(((grayValue - 128) / 64 * 255).round(), 255, 0); } else if ((grayValue >= 192) && (grayValue <= 255)) { return RGB(255, ((255 - grayValue) / 64 * 255).round(), 0); } return RGB(0, 0, 0); } ``` ### 7.屏幕实时显示热成像画面算法,优化像素增大后渲染卡顿算法流畅丝滑 ``` //二维温度数组 List> temperatureScale; //每个像素点大小 final static double pixel; //最低温度 static double temperatureMin = 10; //最高温度 static double temperatureMax = 38; //计算最大温度差 double difference = temperatureMax - temperatureMin; @override void paint(Canvas canvas, Size size) { //创建画笔,默认颜色就是填充模式 Paint paint = Paint(); //画笔x轴位置,默认坐标为容器的左上角 double top = 0; //画笔y轴位置 double left = 0; //循环二维数组 for (var i = 0; i < temperatureScale.length; i++) { for (var j = 0; j < temperatureScale[0].length; j++) { double value = temperatureScale[i][j]; //计算温度系数 double scale = (value - temperatureMin) / difference; //将温度转为rgb颜色值 RGB rbg = grayToPseColor((255 * scale).round()); //调整画笔的颜色 paint.color = Color.fromARGB(255, rbg.R, rbg.G, rbg.B); //创建一个矩形 Rect rrect = Rect.fromLTWH(left, top, pixel, pixel); //画一个矩形到屏幕 canvas.drawRect(rrect, paint); //画笔向右移动一个像素 left = left + pixel; } left = 0; //画笔向下移动一个像素 top = top + pixel; } } ``` ### 9.移动端效果8×8图示例(优化前画面像素->优化中项画面像素->优化后画面像素)