前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >使用 BigDecimal 的正确方式

使用 BigDecimal 的正确方式

作者头像
BUG弄潮儿
发布于 2022-06-07 10:04:17
发布于 2022-06-07 10:04:17
1.3K00
代码可运行
举报
文章被收录于专栏:JAVA乐园JAVA乐园
运行总次数:0
代码可运行
  • 一、BigDecimal概述
  • 二、BigDecimal常用构造函数
  • 三、BigDecimal常用方法详解
  • 四、BigDecimal格式化
  • 五、BigDecimal常见异常
  • 六、BigDecimal总结
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import java.math.BigDecimal 
 
new BigDecimal("4.0")==new BigDecimal("4.0") //true

new BigDecimal("4.0")==new BigDecimal("4.00") //false 

BigDecimal小数比较

一、BigDecimal概述

Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数,但在实际应用中,可能需要对更大或者更小的数进行运算和处理。

BigDecimal

一般情况下,对于那些不需要准确计算精度的数字,我们可以直接使用Float和Double处理,但是Double.valueOf(String)Float.valueOf(String)会丢失精度。所以开发中,如果我们需要精确计算的结果,则必须使用BigDecimal类来操作。

BigDecimal所创建的是对象,故我们不能使用传统的+-*/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。构造器是类的特殊方法,专门用来创建对象,特别是带有参数的对象。

二、BigDecimal常用构造函数

2.1、常用构造函数

  • BigDecimal(int)

创建一个具有参数所指定整数值的对象

  • BigDecimal(double)

创建一个具有参数所指定双精度值的对象

  • BigDecimal(long)

创建一个具有参数所指定长整数值的对象

  • BigDecimal(String)

创建一个具有参数所指定以字符串表示的数值的对象

2.2、使用问题分析

使用示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
BigDecimal a =new BigDecimal(0.1);  
System.out.println("a values is:"+a);  
System.out.println("=====================");  
BigDecimal b =new BigDecimal("0.1");  
System.out.println("b values is:"+b);  

结果示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
a values is:0.1000000000000000055511151231257827021181583404541015625  
=====================  
b values is:0.1

原因分析:

  1. 参数类型为double的构造方法的结果有一定的不可预知性。有人可能认为在Java中写入newBigDecimal(0.1)所创建的BigDecimal正好等于 0.1(非标度值 1,其标度为 1),但是它实际上等于0.1000000000000000055511151231257827021181583404541015625。这是因为0.1无法准确地表示为 double(或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样,传入到构造方法的值不会正好等于 0.1(虽然表面上等于该值)。
  2. String 构造方法是完全可预知的:写入newBigDecimal(“0.1”)将创建一个BigDecimal,它正好等于预期的 0.1。因此,比较而言, 通常建议优先使用String构造方法。
  3. 当double必须用作BigDecimal的源时,请注意,此构造方法提供了一个准确转换;它不提供与以下操作相同的结果:先使用Double.toString(double)方法,然后使用BigDecimal(String)构造方法,将double转换为String。要获取该结果,请使用static valueOf(double)方法。

三、BigDecimal常用方法详解

3.1、常用方法

  • 「add(BigDecimal)」

BigDecimal对象中的值相加,返回BigDecimal对象

  • 「subtract(BigDecimal)」

BigDecimal对象中的值相减,返回BigDecimal对象

  • 「multiply(BigDecimal)」

BigDecimal对象中的值相乘,返回BigDecimal对象

  • 「divide(BigDecimal)」

BigDecimal对象中的值相除,返回BigDecimal对象

  • 「toString()」

将BigDecimal对象中的值转换成字符串

  • 「doubleValue()」

将BigDecimal对象中的值转换成双精度数

  • 「floatValue()」

将BigDecimal对象中的值转换成单精度数

  • 「longValue()」

将BigDecimal对象中的值转换成长整数

  • 「intValue()」

将BigDecimal对象中的值转换成整数

3.2、BigDecimal大小比较

java中对BigDecimal比较大小一般用的是bigdemical的compareTo方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int a = bigdemical.compareTo(bigdemical2)  

返回结果分析:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
a = -1,表示bigdemical小于bigdemical2;  
a = 0,表示bigdemical等于bigdemical2;  
a = 1,表示bigdemical大于bigdemical2;  

举例:a大于等于b。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
new bigdemica(a).compareTo(new bigdemical(b)) >= 0  

四、BigDecimal格式化

由于NumberFormat类的format()方法可以使用BigDecimal对象作为其参数,可以利用BigDecimal对超出16位有效数字的货币值,百分值,以及一般数值进行格式化控制。

以利用BigDecimal对货币和百分比格式化为例。首先,创建BigDecimal对象,进行BigDecimal的算术运算后,分别建立对货币和百分比格式化的引用,最后利用BigDecimal对象作为format()方法的参数,输出其格式化的货币值和百分比。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
NumberFormat currency = NumberFormat.getCurrencyInstance(); //建立货币格式化引用  
NumberFormat percent = NumberFormat.getPercentInstance();  //建立百分比格式化引用  
percent.setMaximumFractionDigits(3); //百分比小数点最多3位  
  
BigDecimal loanAmount = new BigDecimal("15000.48"); //贷款金额  
BigDecimal interestRate = new BigDecimal("0.008"); //利率  
BigDecimal interest = loanAmount.multiply(interestRate); //相乘  
  
System.out.println("贷款金额:\t" + currency.format(loanAmount));  
System.out.println("利率:\t" + percent.format(interestRate));  
System.out.println("利息:\t" + currency.format(interest));  

结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
贷款金额:15,000.48 利率: 0.8% 利息:120.00  

BigDecimal格式化保留2为小数,不足则补0:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class NumberFormat {  
  
    public static void main(String[] s){  
        System.out.println(formatToNumber(new BigDecimal("3.435")));  
        System.out.println(formatToNumber(new BigDecimal(0)));  
        System.out.println(formatToNumber(new BigDecimal("0.00")));  
        System.out.println(formatToNumber(new BigDecimal("0.001")));  
        System.out.println(formatToNumber(new BigDecimal("0.006")));  
        System.out.println(formatToNumber(new BigDecimal("0.206")));  
    }  
    /**  
     * @desc 1.0~1之间的BigDecimal小数,格式化后失去前面的0,则前面直接加上0。  
     * 2.传入的参数等于0,则直接返回字符串"0.00"  
     * 3.大于1的小数,直接格式化返回字符串  
     * @param obj传入的小数  
     * @return  
     */  
    public static String formatToNumber(BigDecimal obj) {  
        DecimalFormat df = new DecimalFormat("#.00");  
        if(obj.compareTo(BigDecimal.ZERO)==0) {  
            return "0.00";  
        }else if(obj.compareTo(BigDecimal.ZERO)>0&&obj.compareTo(new BigDecimal(1))<0){  
            return "0"+df.format(obj).toString();  
        }else {  
            return df.format(obj).toString();  
        }  
    }  
}  

结果为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
3.44  
0.00  
0.00  
0.00  
0.01  
0.21

五、BigDecimal常见异常

5.1、除法的时候出现异常

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result  

「原因分析:」

通过BigDecimal的divide方法进行除法时当不整除,出现无限循环小数时,就会抛异常:java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

❝divide方法设置精确的小数点,如:divide(xxxxx,2)

六、BigDecimal总结

6.1、总结

在需要精确的小数计算时再使用BigDecimal,BigDecimal的性能比double和float差,在处理庞大,复杂的运算时尤为明显。故一般精度的计算没必要使用BigDecimal。尽量使用参数类型为String的构造函数。BigDecimal都是不可变的(immutable)的, 在进行每一次四则运算时,都会产生一个新的对象 ,所以在做加减乘除运算时要记得要保存操作后的值。

6.2、工具类推荐

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.xttblog.util;  
import java.math.BigDecimal;  
  
/**  
 * 用于高精确处理常用的数学运算  
 */  
public class ArithmeticUtils {  
    //默认除法运算精度  
    private static final int DEF_DIV_SCALE = 10;  
  
    /**  
     * 提供精确的加法运算  
     *  
     * @param v1 被加数  
     * @param v2 加数  
     * @return 两个参数的和  
     */  
  
    public static double add(double v1, double v2) {  
        BigDecimal b1 = new BigDecimal(Double.toString(v1));  
        BigDecimal b2 = new BigDecimal(Double.toString(v2));  
        return b1.add(b2).doubleValue();  
    }  
  
    /**  
     * 提供精确的加法运算  
     *  
     * @param v1 被加数  
     * @param v2 加数  
     * @return 两个参数的和  
     */  
    public static BigDecimal add(String v1, String v2) {  
        BigDecimal b1 = new BigDecimal(v1);  
        BigDecimal b2 = new BigDecimal(v2);  
        return b1.add(b2);  
    }  
  
    /**  
     * 提供精确的加法运算  
     *  
     * @param v1    被加数  
     * @param v2    加数  
     * @param scale 保留scale 位小数  
     * @return 两个参数的和  
     */  
    public static String add(String v1, String v2, int scale) {  
        if (scale < 0) {  
            throw new IllegalArgumentException(  
                    "The scale must be a positive integer or zero");  
        }  
        BigDecimal b1 = new BigDecimal(v1);  
        BigDecimal b2 = new BigDecimal(v2);  
        return b1.add(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();  
    }  
  
    /**  
     * 提供精确的减法运算  
     *  
     * @param v1 被减数  
     * @param v2 减数  
     * @return 两个参数的差  
     */  
    public static double sub(double v1, double v2) {  
        BigDecimal b1 = new BigDecimal(Double.toString(v1));  
        BigDecimal b2 = new BigDecimal(Double.toString(v2));  
        return b1.subtract(b2).doubleValue();  
    }  
  
    /**  
     * 提供精确的减法运算。  
     *  
     * @param v1 被减数  
     * @param v2 减数  
     * @return 两个参数的差  
     */  
    public static BigDecimal sub(String v1, String v2) {  
        BigDecimal b1 = new BigDecimal(v1);  
        BigDecimal b2 = new BigDecimal(v2);  
        return b1.subtract(b2);  
    }  
  
    /**  
     * 提供精确的减法运算  
     *  
     * @param v1    被减数  
     * @param v2    减数  
     * @param scale 保留scale 位小数  
     * @return 两个参数的差  
     */  
    public static String sub(String v1, String v2, int scale) {  
        if (scale < 0) {  
            throw new IllegalArgumentException(  
                    "The scale must be a positive integer or zero");  
        }  
        BigDecimal b1 = new BigDecimal(v1);  
        BigDecimal b2 = new BigDecimal(v2);  
        return b1.subtract(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();  
    }  
  
    /**  
     * 提供精确的乘法运算  
     *  
     * @param v1 被乘数  
     * @param v2 乘数  
     * @return 两个参数的积  
     */  
    public static double mul(double v1, double v2) {  
        BigDecimal b1 = new BigDecimal(Double.toString(v1));  
        BigDecimal b2 = new BigDecimal(Double.toString(v2));  
        return b1.multiply(b2).doubleValue();  
    }  
  
    /**  
     * 提供精确的乘法运算  
     *  
     * @param v1 被乘数  
     * @param v2 乘数  
     * @return 两个参数的积  
     */  
    public static BigDecimal mul(String v1, String v2) {  
        BigDecimal b1 = new BigDecimal(v1);  
        BigDecimal b2 = new BigDecimal(v2);  
        return b1.multiply(b2);  
    }  
  
    /**  
     * 提供精确的乘法运算  
     *  
     * @param v1    被乘数  
     * @param v2    乘数  
     * @param scale 保留scale 位小数  
     * @return 两个参数的积  
     */  
    public static double mul(double v1, double v2, int scale) {  
        BigDecimal b1 = new BigDecimal(Double.toString(v1));  
        BigDecimal b2 = new BigDecimal(Double.toString(v2));  
        return round(b1.multiply(b2).doubleValue(), scale);  
    }  
  
    /**  
     * 提供精确的乘法运算  
     *  
     * @param v1    被乘数  
     * @param v2    乘数  
     * @param scale 保留scale 位小数  
     * @return 两个参数的积  
     */  
    public static String mul(String v1, String v2, int scale) {  
        if (scale < 0) {  
            throw new IllegalArgumentException(  
                    "The scale must be a positive integer or zero");  
        }  
        BigDecimal b1 = new BigDecimal(v1);  
        BigDecimal b2 = new BigDecimal(v2);  
        return b1.multiply(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();  
    }  
  
    /**  
     * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到  
     * 小数点以后10位,以后的数字四舍五入  
     *  
     * @param v1 被除数  
     * @param v2 除数  
     * @return 两个参数的商  
     */  
  
    public static double div(double v1, double v2) {  
        return div(v1, v2, DEF_DIV_SCALE);  
    }  
  
    /**  
     * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指  
     * 定精度,以后的数字四舍五入  
     *  
     * @param v1    被除数  
     * @param v2    除数  
     * @param scale 表示表示需要精确到小数点以后几位。  
     * @return 两个参数的商  
     */  
    public static double div(double v1, double v2, int scale) {  
        if (scale < 0) {  
            throw new IllegalArgumentException("The scale must be a positive integer or zero");  
        }  
        BigDecimal b1 = new BigDecimal(Double.toString(v1));  
        BigDecimal b2 = new BigDecimal(Double.toString(v2));  
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();  
    }  
  
    /**  
     * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指  
     * 定精度,以后的数字四舍五入  
     *  
     * @param v1    被除数  
     * @param v2    除数  
     * @param scale 表示需要精确到小数点以后几位  
     * @return 两个参数的商  
     */  
    public static String div(String v1, String v2, int scale) {  
        if (scale < 0) {  
            throw new IllegalArgumentException("The scale must be a positive integer or zero");  
        }  
        BigDecimal b1 = new BigDecimal(v1);  
        BigDecimal b2 = new BigDecimal(v1);  
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).toString();  
    }  
  
    /**  
     * 提供精确的小数位四舍五入处理  
     *  
     * @param v     需要四舍五入的数字  
     * @param scale 小数点后保留几位  
     * @return 四舍五入后的结果  
     */  
    public static double round(double v, int scale) {  
        if (scale < 0) {  
            throw new IllegalArgumentException("The scale must be a positive integer or zero");  
        }  
        BigDecimal b = new BigDecimal(Double.toString(v));  
        return b.setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();  
    }  
  
    /**  
     * 提供精确的小数位四舍五入处理  
     *  
     * @param v     需要四舍五入的数字  
     * @param scale 小数点后保留几位  
     * @return 四舍五入后的结果  
     */  
    public static String round(String v, int scale) {  
        if (scale < 0) {  
            throw new IllegalArgumentException(  
                    "The scale must be a positive integer or zero");  
        }  
        BigDecimal b = new BigDecimal(v);  
        return b.setScale(scale, BigDecimal.ROUND_HALF_UP).toString();  
    }  
  
    /**  
     * 取余数  
     *  
     * @param v1    被除数  
     * @param v2    除数  
     * @param scale 小数点后保留几位  
     * @return 余数  
     */  
    public static String remainder(String v1, String v2, int scale) {  
        if (scale < 0) {  
            throw new IllegalArgumentException(  
                    "The scale must be a positive integer or zero");  
        }  
        BigDecimal b1 = new BigDecimal(v1);  
        BigDecimal b2 = new BigDecimal(v2);  
        return b1.remainder(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();  
    }  
  
    /**  
     * 取余数  BigDecimal  
     *  
     * @param v1    被除数  
     * @param v2    除数  
     * @param scale 小数点后保留几位  
     * @return 余数  
     */  
    public static BigDecimal remainder(BigDecimal v1, BigDecimal v2, int scale) {  
        if (scale < 0) {  
            throw new IllegalArgumentException(  
                    "The scale must be a positive integer or zero");  
        }  
        return v1.remainder(v2).setScale(scale, BigDecimal.ROUND_HALF_UP);  
    }  
  
    /**  
     * 比较大小  
     *  
     * @param v1 被比较数  
     * @param v2 比较数  
     * @return 如果v1 大于v2 则 返回true 否则false  
     */  
    public static boolean compare(String v1, String v2) {  
        BigDecimal b1 = new BigDecimal(v1);  
        BigDecimal b2 = new BigDecimal(v2);  
        int bj = b1.compareTo(b2);  
        boolean res;  
        if (bj > 0)  
            res = true;  
        else  
            res = false;  
        return res;  
    }  
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-05-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 BUG弄潮儿 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
丰田研究院:自监督单目图像深度估计,数据和代码已开源
计算机视觉是人工智能的一个领域,它使计算机能够表示视觉世界。由于神经网络可以从数据中学习如何做出准确的预测,深度学习已经彻底改变了这个领域。最近的进展有望使汽车更加安全,通过自动驾驶车辆增加自由时间,以及为残疾人和我们迅速老龄化的全球人口提供机器人援助。
McGL
2021/05/28
1.6K0
丰田研究院:自监督单目图像深度估计,数据和代码已开源
单目深度估计方法综述
深度估计,就是获取图像中场景里的每个点到相机的距离信息,这种距离信息组成的图我们称之为深度图,英文叫Depth map。
3D视觉工坊
2021/12/01
2.9K0
单目深度估计方法综述
单目图像和稀疏雷达数据深度估计
标题:Depth Estimation from Monocular Images and Sparse Radar Data
3D视觉工坊
2020/11/19
1.4K0
单目图像和稀疏雷达数据深度估计
AAAI-2024 | Mono3DVG:首个基于单目RGB图像实现3D Visual Grounding的方法
本文分享论文Mono3DVG: 3D Visual Grounding in Monocular Images,该论文已被 AAAI 2024 接收,数据集和代码已开源。
CV君
2024/01/23
7060
AAAI-2024 | Mono3DVG:首个基于单目RGB图像实现3D Visual Grounding的方法
计算机视觉最新进展概览(2021年7月4日到2021年7月10日)
1、Faster-LTN: a neuro-symbolic, end-to-end object detection architecture 图像对象之间的语义关系的检测是图像解释的基本挑战之一。 神经符号技术,如逻辑张量网络(LTNs),允许结合语义知识表示和推理的能力,有效地学习典型的神经网络的例子。 我们在这里提出Faster-LTN,一种由卷积主干和LTN组成的目标检测器。 据我们所知,这是在端到端训练设置中结合这两种框架的第一次尝试。 这个体系结构是通过优化一个有根据的理论来训练的,这个理论以逻辑公理的形式将标记的实例与先验知识结合起来。 实验对比表明,与传统的Faster R-CNN架构相比,该架构具有竞争力的性能。 2、Semi-supervised Learning for Dense Object Detection in Retail Scenes 零售场景的每幅图像通常包含密集的高数量的目标。 标准的目标检测技术使用完全监督的训练方法。 这是非常昂贵的,因为注释一个大型密集的零售目标检测数据集需要比标准数据集多一个数量级的工作。 因此,我们提出了半监督学习来有效地利用零售领域中大量的未标记数据。 我们采用一种流行的自监督方法,即噪声学生最初提出的目标分类的任务,密集的目标检测。 我们表明,使用无标记数据与嘈杂的学生训练方法,我们可以提高在密集的零售场景中精确检测目标的技术水平。 我们还表明,随着未标记数据数量的增加,模型的性能也会增加。 3、On Model Calibration for Long-Tailed Object Detection and Instance Segmentation 普通的目标检测模型和实例分割模型在长尾设置中存在检测频繁目标的严重偏差。 现有的方法主要在训练期间解决这个问题,例如,通过重新抽样或重新加权。 在本文中,我们调查了一个很大程度上被忽视的方法——置信度的后处理校准。 我们提出了NorCal,归一化校准用于长尾目标检测和实例分割,这是一种简单而直接的方法,通过训练样本大小重新衡量每个类的预测分数。 我们表明,单独处理后台类和对每个建议的类上的分数进行规范化是实现卓越性能的关键。 在LVIS数据集上,NorCal可以有效地改进几乎所有的基线模型,不仅在罕见类上,而且在普通类和频繁类上。 最后,我们进行了广泛的分析和消融研究,以提供我们方法的各种建模选择和机制的见解。 4、Neighbor-Vote: Improving Monocular 3D Object Detection through Neighbor Distance Voting 随着摄像头在自动驾驶等新的应用领域的不断应用,对单目图像进行三维目标检测成为视觉场景理解的重要任务。 单眼三维目标检测的最新进展主要依赖于“伪激光雷达”生成,即进行单眼深度估计并将二维像素点提升为伪三维点。 但单目图像深度估计精度不高,导致伪激光雷达点在目标内不可避免地发生位置偏移。 因此,预测的边界框位置不准确,形状变形。 在本文中,我们提出了一种新的邻域投票方法,结合邻域预测来改善严重变形的伪激光雷达点云的目标检测。 具体来说,物体周围的每个特征点形成各自的预测,然后通过投票实现“共识”。 这样可以有效地将邻居预测与局部预测相结合,实现更准确的三维检测。 为了进一步放大前景感兴趣区域(foreground region of interest, ROI)伪激光雷达点与背景点之间的差异,我们还将二维前景像素的ROI预测得分编码为相应的伪激光雷达点。 我们在KITTI基准上进行了大量的实验,以验证我们提出的方法的优点。 我们的鸟瞰图检测结果在很大程度上超过了最先进的性能,特别是“硬”水平检测。 5、VIN: Voxel-based Implicit Network for Joint 3D Object Detection and Segmentation for Lidars 提出了一种统一的神经网络结构用于三维目标检测和点云分割。 我们利用丰富的监督,从检测和分割标签,而不是只使用其中之一。 此外,基于隐式函数在三维场景和物体理解中的广泛应用,提出了一种基于单级目标检测器的扩展方法。 扩展分支以目标检测模块的最终特征图为输入,生成隐式函数,为每个点对应体素中心生成语义分布。 我们在一个大型户外数据集nuScenes-lidarseg上演示了我们的结构的性能。 我们的解决方案在三维目标检测和点云分割方面取得了与先进方法相竞争的结果,与目标检测解决方案相比,我们的附加计算负荷很小。 实验结果表明,该方法具有较好的弱监督语义切分能力。
狼啸风云
2021/07/14
9390
基于整合IMU运动动力学的无监督单目深度估计
虽然近年来无监督单目深度学习取得了很大的进展,但仍然存在一些基本问题。首先,目前的方法存在尺度模糊性问题,因为反推过程对于深度和平移来说相当于任意尺度因子。其次,光度误差对照明变化和移动物体敏感。此外,尽管在无监督学习框架下已经为光度误差图引入了不确定性,但自我运动的不确定性度量仍然是重要的。在2022 ECCV论文"Towards Scale-Aware, Robust, and Generalizable Unsupervised Monocular Depth Estimation by Integrating IMU Motion Dynamics",作者提出了一种感知框架,通过集成视觉和IMU来进行真实尺度估计,算法已经开源。
BBuf
2022/09/28
9870
基于整合IMU运动动力学的无监督单目深度估计
60项基于深度学习的SLAM顶会开源方案汇总(上篇)
深度学习结合SLAM是近年来很热门的研究方向,也因此诞生了很多开源方案。笔者最近在阅读SLAM综述论文“A Survey on Deep Learning for Localization and Mapping: Towards the Age of Spatial Machine Intelligence”,该综述参考了255篇SLAM领域的顶会顶刊论文,并且涵盖了VO、建图、特征提取、定位、描述子提取、BA优化、回环、数据集等多个方向,非常全面。也因此,笔者一直想整理下文章中出现的开源项目,用于在后续工作中进行对比。
3D视觉工坊
2023/04/29
1.6K0
60项基于深度学习的SLAM顶会开源方案汇总(上篇)
点云分割训练哪家强?监督,弱监督,无监督还是半监督?
近年来,自动驾驶领域的各项下游任务基本上都要求了对场景的语义理解,比如自动驾驶车辆要能够理解哪个是路面、哪个是交通灯、哪个是行人、哪个是树木,因此点云分割的作用就不言而喻。
3D视觉工坊
2023/04/29
9940
点云分割训练哪家强?监督,弱监督,无监督还是半监督?
基于深度学习的单目深度估计综述
文章:Monocular Depth Estimation Based On Deep Learning: An Overview
3D视觉工坊
2020/12/11
2.7K0
基于深度学习的单目深度估计综述
SLAM综述(3)-视觉与惯导,视觉与深度学习SLAM
视觉SLAM的稳定性是一项技术挑战。因为基于单目的视觉SLAM需要初始化、尺度的不确定性和尺度漂移等问题[1]。尽管立体相机和RGB-D相机可以解决初始化和缩放的问题,但也存在一些不容忽视的问题,如运动速度快、视角小、计算量大、遮挡、特征丢失、动态场景和光照变换等。针对以上这些问题传感器的融合方案逐渐流行起来,IMU与相机融合的视觉里程计成为研究热点。
点云PCL博主
2020/05/19
3K0
thinktwice:用于端到端自动驾驶的可扩展解码器(已开源)
题目:Think Twice before Driving: Towards Scalable Decoders for End-to-End Autonomous Driving
BBuf
2023/08/22
3730
thinktwice:用于端到端自动驾驶的可扩展解码器(已开源)
单目深度估计思路
2. 之后在2016年,Laina依靠更深层次的网络和一个“novel”的逆卷积结构再加上一个"novel"的loss来得到结果。其实我认为这篇文章的贡献点不是很大,主要是pretrain的ResNet-50帮了很大的忙。这个方法被他们组改进然后用到了之后CVPR2017用来重建SLAM的文章中。
3D视觉工坊
2020/11/19
7930
单目深度估计思路
单摄像头+深度学习实现伪激光雷达,代码已开源
上次介绍了双目摄像头如何估计深度的方案。老板表示两个摄像头还是有点贵呀,只用一个能不能做?嗯,没问题!
McGL
2020/09/27
1.2K0
【计算摄影】先拍照后对焦,浅析基于深度估计的景深编辑与背景虚化
大家好,这是专栏《计算摄影》的第四篇文章,这一个专栏来自于计算机科学与摄影艺术的交叉学科。今天我们讨论的问题是关于深度估计和景深编辑。
用户1508658
2020/11/19
1.3K0
【计算摄影】先拍照后对焦,浅析基于深度估计的景深编辑与背景虚化
动态场景的无监督单目深度图学习 (附FB和华盛顿大学SIGGRAPH论文)
来源丨https://zhuanlan.zhihu.com/p/273038523
3D视觉工坊
2020/11/11
1.1K0
动态场景的无监督单目深度图学习 (附FB和华盛顿大学SIGGRAPH论文)
ICCV2023 室内场景自监督单目深度估计
本文方法是一种自监督的单目深度估计框架,名为GasMono,专门设计用于室内场景。本方法通过应用多视图几何的方式解决了室内场景中帧间大旋转和低纹理导致自监督深度估计困难的挑战。GasMono首先利用多视图几何方法获取粗糙的相机姿态,然后通过旋转和平移/尺度优化来进一步优化这些姿态。为了减轻低纹理的影响,该框架将视觉Transformer与迭代式自蒸馏机制相结合。通过在多个数据集上进行实验,展示了GasMono框架在室内自监督单目深度估计方面的最先进性能。
BBuf
2023/10/26
9670
ICCV2023 室内场景自监督单目深度估计
最新综述:基于深度学习方式的单目物体姿态估计与跟踪
原文:Deep Learning on Monocular Object Pose Detection and Tracking: A Comprehensive Overview
计算机视觉
2021/07/05
1.3K0
基于深度学习的单目深度估计综述
深度估计是计算机视觉领域的一个基础性问题,其可以应用在机器人导航、增强现实、三维重建、自动驾驶等领域。而目前大部分深度估计都是基于二维RGB图像到RBG-D图像的转化估计,主要包括从图像明暗、不同视角、光度、纹理信息等获取场景深度形状的Shape from X方法,还有结合SFM(Structure from motion)和SLAM(Simultaneous Localization And Mapping)等方式预测相机位姿的算法。其中虽然有很多设备可以直接获取深度,但是设备造价昂贵。也可以利用双目进行深度估计,但是由于双目图像需要利用立体匹配进行像素点对应和视差计算,所以计算复杂度也较高,尤其是对于低纹理场景的匹配效果不好。而单目深度估计则相对成本更低,更容易普及。
计算机视觉
2021/03/17
2K0
基于深度学习的单目深度估计综述
8 篇论文深入学习深度估计:深度预测;自我运动学习;观看冰雪奇缘了解移动人物深度
原文标题:Research Guide for Depth Estimation with Deep Learning
AI科技评论
2019/10/31
2.3K0
8 篇论文深入学习深度估计:深度预测;自我运动学习;观看冰雪奇缘了解移动人物深度
谷歌AI:根据视频生成深度图,效果堪比激光雷达
目前自动驾驶的核心技术是LiDAR(激光雷达),一种运用雷达原理,采用光和激光作为主要传感器的汽车视觉系统。LiDAR传感器赋予了自动驾驶汽车能够看到周边环境的“双眼”,激光雷达技术越先进,视觉感知的精准程度越高,这是自动驾驶得以实现的底层技术基础。
新智元
2019/05/08
1.3K0
谷歌AI:根据视频生成深度图,效果堪比激光雷达
推荐阅读
相关推荐
丰田研究院:自监督单目图像深度估计,数据和代码已开源
更多 >
LV.0
腾讯
目录
  • 一、BigDecimal概述
  • 二、BigDecimal常用构造函数
    • 2.1、常用构造函数
    • 2.2、使用问题分析
  • 三、BigDecimal常用方法详解
    • 3.1、常用方法
    • 3.2、BigDecimal大小比较
  • 四、BigDecimal格式化
  • 五、BigDecimal常见异常
    • 5.1、除法的时候出现异常
  • 六、BigDecimal总结
    • 6.1、总结
    • 6.2、工具类推荐
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档