java从红外图片提取温度,计算超过阈值的温度占总面积的百分比

灰度图是单通道图,像素只有一个值:灰度值。灰度值越高,则图像越亮。

现在我们已经知道我们看到一张灰度图是由许多不同灰度值的像素点构成,而每个像素就是一个越亮的像素,灰度值越高,最高值是255(白色),越暗的像素,灰度值越低,最低值是0(黑色)。灰度值在0~255之间的像素呈现不同程度的灰色。这样,通过不同的灰度层次,图像也就展现出来了。

        我们已经知道我们看到一张灰度图是由许多不同灰度值的像素点构成,而每个像素就是一个代表灰度值的数字,那么我们想想许多数字按照图像的形状成矩形排列,会变成什么呢?没错,学过线性代数的小伙伴一下子就猜出来了,就是——矩阵。

首先在pom中引入opencv的依赖

<dependency><groupId>org.openpnp</groupId><artifactId>opencv</artifactId><version>4.5.1-1</version>
</dependency>
<dependency><groupId>net.sourceforge.tess4j</groupId><artifactId>tess4j</artifactId><version>5.3.0</version>
</dependency><!-- 以下以opencv为例,添加你需要的库的相关依赖 -->
<dependency><groupId>org.bytedeco</groupId><artifactId>javacv-platform</artifactId><version>1.5.7</version>
</dependency>

灰度值的范围为0-255,根据灰度值的范围和红外图的右侧温度调范围21.5-124 建立线性关系

public static float map(int value, int min1, int max1, float min2, float max2) {return (float) (min2 + (value - min1) * (max2 - min2) / (max1 - min1));
}
public static double getTempture(int pixe) {double mappedValue=0.0;for (int i = 0; i <= 248; i++) {if (i==pixe){mappedValue = map(i, 0, 248, 21.5f, 124f);}}return mappedValue;
}

计算面积的完整代码如下:

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;import java.util.ArrayList;
import java.util.Collections;
import java.util.List;import static org.opencv.highgui.HighGui.imshow;
import static org.opencv.imgcodecs.Imgcodecs.imread;public class InfraredTemperature {static {System.loadLibrary(Core.NATIVE_LIBRARY_NAME);}public static float map(int value, int min1, int max1, float min2, float max2) {return (float) (min2 + (value - min1) * (max2 - min2) / (max1 - min1));}public static double getTempture(int pixe) {double mappedValue=0.0;for (int i = 0; i <= 248; i++) {if (i==pixe){mappedValue = map(i, 0, 248, 21.5f, 124f);}}return mappedValue;}public static void main(String[] args) {// 读取图像  IMREAD_GRAYSCALEMat img = Imgcodecs.imread("C:\\Users\\lenovo\\Desktop\\999.jpg", Imgcodecs.IMREAD_GRAYSCALE );// 阈值double thresholdValue = 110;// 创建一个全黑的同样大小的图片,用于存储结果Mat result = Mat.zeros(img.size(), CvType.CV_8UC1);// 计算超过阈值的面积double totalArea = img.size().height * img.size().width;double thresholdedArea = 0;double  surplusArea =0;List<Integer> listOfDoubles = new ArrayList<>();// 遍历图像中的每个像素for (int y = 0; y < img.size().height; y++) {for (int x = 0; x < img.size().width; x++) {int pixelValue =(int) Math.round(img.get(y, x)[0]) ;listOfDoubles.add(pixelValue);}}//灰度值的最大值System.out.println("count is  " + Collections.max(listOfDoubles));for (int y = 0; y < img.size().height; y++) {for (int x = 0; x < img.size().width; x++) {//该值为实际温度和最大像素值相除得来的double pixelValue = img.get(y, x)[0];double pixelValueInfo =getTempture((int) Math.round(pixelValue));if (pixelValueInfo > thresholdValue) {result.put(y, x, 248); // 将超过阈值的点设置为白色thresholdedArea++;}else {surplusArea++;}}}// 计算超过阈值的面积所占的百分比double areaFraction = thresholdedArea / totalArea;// 输出结果int countInfo=0;for (int i = 0; i < listOfDoubles.size(); i++) {if (listOfDoubles.get(i)==248){countInfo++;}}//最大灰度值出现的次数System.out.println("countInfo is " + countInfo);//超过阈值的面积System.out.println("thresholdedArea is " + thresholdedArea);//低于阈值的面积System.out.println("surplusArea is " + surplusArea);System.out.println("totalArea is " + totalArea);System.out.println("Area of pixels with temperature over " + thresholdValue + "°C: " + areaFraction);// 如果需要可视化结果,可以显示result图片Imgcodecs.imwrite("C:\\Users\\lenovo\\Desktop\\888.jpg", result);// 释放资源img.release();result.release();}}

其中还有获取红外图右侧温度条的逻辑

即用java调用ocr库实现红外图上文本的获取,代码如下

<dependency><groupId>net.sourceforge.tess4j</groupId><artifactId>tess4j</artifactId><version>5.3.0</version>
</dependency>
import com.spire.ocr.OcrScanner;
import org.apache.commons.io.FileUtils;import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;public class InfraredTemperatureExtractor {public static void main(String[] args) throws Exception {BufferedImage image = ImageIO.read(new File("D:\\13.jpg"));// 获取图片的宽度和高度int width = image.getWidth();int height = image.getHeight();//         创建一个新的图片,保留原来的类型和颜色空间
//        *     x: 裁剪起点横坐标
//                *     y: 裁剪起点纵坐标
//                *     w: 需要裁剪的宽度
//                *     h: 需要裁剪的高度BufferedImage croppedImage = image.getSubimage(width / 2, 0, width / 2, height);try {// 写入新图片ImageIO.write(croppedImage, "jpg", new File("D:\\13_1.jpg"));//指定依赖文件的路径String dependencies = System.getProperty("user.dir") + "\\dependencies";//指定要需要扫描的图片的路径String imageFile = "D:\\13_1.jpg";
//            RandomAccessFile raf = new RandomAccessFile(imageFile, "rw");//创建OcrScanner对象,并设置其依赖文件路径OcrScanner scanner = new OcrScanner();scanner.setDependencies(dependencies);//扫描指定的图像文件scanner.scan(imageFile);//获取扫描的文本内容String scannedText = scanner.getText().toString();List<Double> numbers = new ArrayList<>();// 分割字符串// 将每行转换为整数并添加到列表中String[] lines = scannedText.split("\n");for (int i = 0; i < lines.length; i++) {if (i != lines.length - 1) {numbers.add(Double.parseDouble(lines[i]));}}System.out.println(numbers);} catch (Exception e) {e.printStackTrace();}File imageFileInfo = new File("D:\\13_1.jpg");try {boolean fileDeletable = imageFileInfo.canWrite();System.out.println("文件是否可以删除" +fileDeletable);//回收System.gc();imageFileInfo.delete();
//            FileUtils.forceDelete(imageFileInfo);} catch (Exception e) {e.printStackTrace();}}//    public static void delete(File imageFileInfo) {
//        boolean s=false;
//        try {
//            System.gc();
//              FileUtils.forceDelete(imageFileInfo);
//        } catch (IOException e) {
//            throw new RuntimeException(e);
//        }
//    }
}

//指定依赖文件的路径 String dependencies = System.getProperty("user.dir") + "\\dependencies";

安装包可以自行下载,和项目放在指定目录下即可

还有一个坑 OcrScanner scanner = new OcrScanner();没有关闭流的操作,在删除剪裁好的文件时可能出现无法删除的现象,这个时候可以用System.gc();回收程序对图片的占用,从而达到删除剪裁好的图片的效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/28706.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQL server with方法修改

SQL server with方法修改&#xff0c;SQL 2008 不支持 with方法 需要改写下&#xff1a; WITH MonthsCTE AS ( 4 SELECT StartDate AS MonthStart 5 UNION ALL 6 SELECT DATEADD(month, -1, MonthStart) 7 FROM MonthsCTE 8 WHERE MonthStart > EndDate 9 ) 10 11 IN…

Latex的参考文献中显示三个问号???——解决办法

1、问题描述 在使用spring模板&#xff0c;并引用book时&#xff0c;末尾的引文地方出现三个???由于使用的bibtex是直接从谷歌学术中导出来的&#xff0c;其中仅包含作者&#xff0c;书名&#xff0c;出版社&#xff0c;年份等&#xff0c;缺少了重要的信息。结果导致在出版…

什么!没有Starter的阿里云OSS也能集成到SpringBoot?

实际上&#xff0c;我们在Maven存储库中尝试搜索阿里云OSS。在此过程中&#xff0c;我们会发现阿里云官方未提供一种集成Spring Boot的模式&#xff0c;即xxx-Springboot-Starter&#xff0c;显然&#xff0c;这是一个需要自行定制的组件。然而&#xff0c;如今许多企业在研发过…

LeetCode | 520.检测大写字母

这道题直接分3种情况讨论&#xff1a;1、全部都为大写&#xff1b;2、全部都为小写&#xff1b;3、首字母大写其余小写。这里我借用了一个全是大写字母的串和一个全为小写字母的串进行比较 class Solution(object):def detectCapitalUse(self, word):""":type …

【机器学习】计算机图形和深度学习模型NeRF详解(1)

1.引言 1.1.1. NeRF研究的背景 人们在拍照的时候&#xff0c;往往会中各个角度进行拍摄&#xff0c;以呈现出物体的全貌和美丽。下图的照片&#xff0c;拍摄的是一架楼梯&#xff0c;但是拍摄的角度完全不同&#xff1a; 我们可以看到这些图片都是楼梯的照片&#xff0c;但拍…

JavaScript语法糖:让代码更甜的10个技巧

JavaScript语法糖&#xff1a;让代码更甜的10个技巧 在JavaScript编程的世界里&#xff0c;“语法糖”&#xff08;Syntactic Sugar&#xff09;是一个亲切的术语&#xff0c;用于描述那些让代码更加简洁、可读性强的语法特性&#xff0c;而这些特性并不会增加语言的功能性&am…

Training language models to follow instructions with human feedback 论文阅读

论文原文&#xff1a;https://arxiv.org/pdf/2203.02155 论文简介 语言模型越大并不意味着它能更好的理解用户的意图&#xff0c;因此在这篇论文中&#xff0c;展示了根据人的反馈对模型进行微调&#xff0c;使得语言模型能够在各种人物上更好的理解用户的意图。在评估中&…

树莓派4B学习笔记11:PC端网线SSH连接树莓派

今日继续学习树莓派4B 4G&#xff1a;&#xff08;Raspberry Pi&#xff0c;简称RPi或RasPi&#xff09; 本人所用树莓派4B 装载的系统与版本如下: 版本可用命令 (lsb_release -a) 查询: Opencv 版本是4.5.1&#xff1a; 今日学习使用网线连接树莓派&#xff0c;网线可以提供更…

云端数据保护的挑战与对策

云端数据保护的挑战与对策 挑战 云端数据保护面临的挑战主要包括技术、管理和法律三个方面。技术方面的挑战主要是数据加密与密钥管理、多租户数据隔离、数据备份与恢复等。管理方面的挑战包括如何确保云服务提供商的安全措施到位、如何处理内部威胁和外部攻击等。法律方面的…

使用 C# 学习面向对象编程:第 8 部分

抽象方法 亲爱的读者&#xff0c;本文是 OOP 的第四大支柱&#xff0c;也是最后一大支柱。对于 OOP 初学者来说&#xff0c;这很容易让人困惑。因此&#xff0c;我们用非常简单的语言提供了一个示例。 “抽象用于管理复杂性。无法创建抽象类的对象。抽象类用于继承。” 例如…

降噪领夹麦克风哪个牌子好?揭秘无线领夹麦克风哪个降噪好

相信很多新手视频创作者都有一个疑问&#xff1a;为什么别人的视频或者直播音质这么清晰&#xff0c;几乎没什么噪音呢&#xff1f;其实最主要的就是麦克风的原因&#xff0c;相机或手机内置的麦克风是无法提供高质量的音频记录以及很好的指向性的。 想要拍摄出来的视频作品拥有…

LeetCode 验证二叉搜索树

//&#xff08;lower&#xff0c;upper&#xff09;这是一个不断更新维护的区间&#xff0c;为什么要更新维护 //为了保证二叉搜索树的正确性&#xff0c;需要根节点左子树的所有值都小于根节点&#xff0c;右子树的所有节点的值呀大于根节点 //lower维护的是当…

C#类库打包支持多个版本的类库

修改csproj <Project Sdk"Microsoft.NET.Sdk"><PropertyGroup><TargetFrameworks>netcoreapp3.1;net5.0;net6.0;net7.0;net8.0</TargetFrameworks><PackageId>xxxx</PackageId><Version>1.0.0</Version><Author…

每一个男人都曾有一个机器人的梦想

每一个男人都曾有一个机器人的梦想 我也有 每一个男人都曾有一个机器人的梦想。对于我来说&#xff0c;这个梦想始于童年时代&#xff0c;那时变形金刚风靡一时&#xff0c;几乎所有80后的孩子都为之疯狂。我是80后中的一员&#xff0c;那时候的科技还远没有如今这般发达&#…

《现代通信原理与技术》码间串扰和​​​​​​​无码间串扰的眼图对比实验报告

实 验&#xff1a;码间串扰和无码间串扰的眼图对比实验报告 摘 要&#xff1a; 在数字通信系统中&#xff0c;码间串扰&#xff08;Inter-Symbol Interference, ISI&#xff09;是影响信号质量和系统性能的重要因素之一。本实验通过MATLAB软件生成并对比了受码间串扰影响和未…

【测试相关工作】

1.测试对象及意义 测试对象&#xff1a;每个公司都有自己的产品&#xff08;软硬件&#xff09;&#xff0c;针对这一产品开展的一系列工作。 虽然每个公司产品都不一样&#xff0c;但测试的工作和流程都大同小异啦&#xff5e;都是为了让自己的产品符合甲方需求。人活着就是…

PHP框架有哪些,以及具体对比优缺点

PHP框架有很多&#xff0c;每个框架都有其特定的优势和劣势&#xff0c;适用于不同的开发场景和需求。以下是一些流行的PHP框架及其优缺点的对比&#xff1a; Laravel 优点&#xff1a; 优雅的语法和丰富的功能。强大的ORM&#xff08;Eloquent&#xff09;简化数据库交互。拥…

数据驱动和vue的双向绑定有何异同

相同点 数据驱动&#xff1a; 小程序和Vue都采用了数据驱动的方式&#xff0c;即数据的变化会直接导致视图的变化。这是现代前端框架的一个重要特性&#xff0c;它允许开发者更加关注数据本身&#xff0c;而不是手动去操作DOM。自动同步&#xff1a; 当数据发生变化时&#xf…

华为昇腾异构计算架构CANN及AI芯片简介

异构计算架构CANN 异构计算架构CANN&#xff08;Compute Architecture for Neural Networks&#xff09;是华为针对AI场景推出的异构计算架构&#xff0c;向上支持多种AI框架&#xff0c;包括MindSpore、PyTorch、TensorFlow等&#xff0c;向下服务AI处理器与编程&#xff0c;…

Open To Buy(OTB)计划:零售业者的库存管理利器

在当今快速变化的服装市场中&#xff0c;如何高效、精准地进行商品管理成为了服装企业竞争的关键。OTB&#xff08;Open-to-Buy&#xff09;作为一种有效的商品管理方法&#xff0c;在企业管理中扮演着至关重要的角色。它基于预算、商品计划以及市场需求等多维度因素&#xff0…