• opencv图像像素类型转换与归一化


    opencv图像像素类型转换与归一化

    1、为什么对图像像素类型转换与归一化
    • 数据一致性:不同的图像可能使用不同的像素类型来表示图像数据,如8位无符号整数、16位无符号整数、32位浮点数等。在某些情况下,为了进行后续处理或者与其他图像进行比较,需要确保所有图像使用相同的数据类型,因此需要进行像素类型转换,以使它们的数据类型一致。
    • 算法需求:某些图像处理算法对输入图像的数据类型有特定的要求。例如,某些滤波器或变换可能需要输入为浮点数图像,因此需要将图像像素类型从整数转换为浮点数。
    • 增强对比度:归一化是将像素值映射到特定范围内,通常是[0, 1]或[0, 255]。这可以用来增强图像的对比度,使亮度范围更易于可视化或用于后续处理。
    • 避免溢出和截断:在进行一些图像操作时,像素值可能会超出特定范围(如255对于8位无符号整数图像)。归一化可以确保像素值在有效范围内,避免溢出或截断。
    • 数据处理和机器学习:在机器学习和深度学习中,通常需要将输入数据进行标准化或归一化,以便模型的训练和性能更好。图像像素值的归一化可以是这个过程的一部分。
    • 显示和可视化:有时候,将图像像素值归一化到合适的范围可以更好地显示图像或将其可视化,使图像更容易理解和分析。
    2、在OpenCV中,convertTo()normalize() 是两个常用的图像处理函数,用于图像像素类型转换和归一化;
    • 图像的像素类型就是cv::Mat元素的数据类型
    • cv::Mat的元素类型决定了它可以存储的数据的种类,比如8位无符号整数(CV_8U)、16位无符号整数(CV_16U)、32位浮点数(CV_32F)等等。不同的元素类型决定了图像的颜色深度、精度以及可以表达的范围。
    (1)convertTo() 函数用于将一个 cv::Mat 对象的像素类型转换为另一种类型。它的基本用法如下:
    void cv::Mat::convertTo(
        OutputArray m,
        int rtype,
        double alpha = 1,
        double beta = 0
    ) const;
    
    参数解释:
    m:输出的目标图像;
    rtype:目标图像的数据类型(可以使用 OpenCV 提供的常量如CV_8U、CV_16U、CV_32F等);
    alpha:缩放因子,用于线性变换。默认为1; 
    beta:偏移量,用于线性变换。默认为0
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    示例:

    cv::Mat img = cv::imread("input.jpg");
    cv::Mat new_img;
    img.convertTo(new_img, CV_32F); // 将图像转换为32位浮点数类型
    
    • 1
    • 2
    • 3
    (2)normalize() 函数用于将图像的像素值归一化到指定的范围内,通常是 [0, 1] 或 [0, 255]。
    void cv::normalize(
        InputArray src,  
        OutputArray dst,   
        double alpha = 0,  
        double beta = 255,    
        int norm_type = NORM_L2,   
        int dtype = -1,           
        InputArray mask = noArray()   
    );
    
    参数解释:
    src:输入图像;
    dst:输出归一化后的图像;
    alpha:归一化的下界; 
    beta:归一化的上界; 
    norm_type:归一化类型,默认为NORM_L2(
    	NORM_MINMAX
    	NORM_INF
    	NORM_L1
    	NORM_L2
    )
    dtype:输出图像的数据类型(默认值-1,如果为负数,将使用输入图像的数据类型) ;
    mask:掩码,可选参数; 
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    示例:

    cv::Mat img = cv::imread("input.jpg", cv::IMREAD_GRAYSCALE);
    cv::Mat normalized_img;
    cv::normalize(img, normalized_img, 0, 255, cv::NORM_MINMAX, CV_8U);
    
    在这个示例中,normalize() 函数将图像的像素值归一化到 [0, 255] 的范围内,并将结果保存在 normalized_img 中。
    
    • 1
    • 2
    • 3
    • 4
    • 5

    总的来说,convertTo() 用于更改图像的数据类型,而 normalize() 用于将像素值归一化到指定范围内。这两个函数在图像处理中经常会用到,可以根据具体的需求来选择使用。

    3、代码实例说明:
    (1)图像像素类型转换:
    #include 
    #include 
    
    int main() {
        // 读取图像
        cv::Mat img = cv::imread("input.jpg");
    
        if (img.empty()) {
            std::cerr << "Could not read the image." << std::endl;
            return -1;
        }
        // 转换前的像素数据类型CV_8UC3
        std::cout << img.type() << std::endl;
        // 将图像从当前类型转换为新的类型CV_32FC3
        cv::Mat new_img;
        img.convertTo(new_img, CV_32F); // 这里将图像转换为32位浮点数类型,可以使用 CV_8U、CV_16U、CV_32F 等来选择不同的目标类型
        // 转换后的像素数据类型
        std::cout << new_img.type() << std::endl;
    
        // 进一步处理 new_img ...
    
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    (2)图像归一化:将图像像素的值映射到一个特定的范围内,通常是[0, 1]或者[0, 255]。
    convertTo() 函数

    将像素值归一化到[0, 1]范围:

    #include 
    #include 
    
    int main() {
        // 读取灰度图像
        cv::Mat img = cv::imread("input.jpg", cv::IMREAD_GRAYSCALE);
    
        if (img.empty()) {
            std::cerr << "Could not read the image." << std::endl;
            return -1;
        }
    
        // 将像素值转换为浮点数类型并归一化
        cv::Mat normalized_img;
        img.convertTo(normalized_img, CV_32F);
        normalized_img /= 255.0;
    
        // 进一步处理 normalized_img ...
    
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    将像素值归一化到[0, 255]范围:

    #include 
    #include 
    
    int main() {
        // 读取灰度图像
        cv::Mat img = cv::imread("input.jpg", cv::IMREAD_GRAYSCALE);
    
        if (img.empty()) {
            std::cerr << "Could not read the image." << std::endl;
            return -1;
        }
    
        // 将像素值转换为整数类型并归一化
        cv::Mat normalized_img;
        img.convertTo(normalized_img, CV_8U);
        normalized_img *= 255;
    
        // 进一步处理 normalized_img ...
    
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    normalize() 函数

    将像素值归一化到[0, 1]范围:

    #include 
    #include 
    
    int main() {
        // 读取灰度图像
        cv::Mat img = cv::imread("input.jpg", cv::IMREAD_GRAYSCALE);
    
        if (img.empty()) {
            std::cerr << "Could not read the image." << std::endl;
            return -1;
        }
    
        // 将像素值转换为浮点数类型并归一化
        cv::Mat normalized_img;
        cv::normalize(img, normalized_img, 0.0, 1.0, cv::NORM_MINMAX, CV_32F);
    
        // 进一步处理 normalized_img ...
    
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    将像素值归一化到[0, 255]范围:

    #include 
    #include 
    
    int main() {
        // 读取灰度图像
        cv::Mat img = cv::imread("input.jpg", cv::IMREAD_GRAYSCALE);
    
        if (img.empty()) {
            std::cerr << "Could not read the image." << std::endl;
            return -1;
        }
    
        // 将像素值归一化到[0, 255]范围
        cv::Mat normalized_img;
        cv::normalize(img, normalized_img, 0, 255, cv::NORM_MINMAX, CV_8U);
    
        // 进一步处理 normalized_img ...
    
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    convertTo()normalize() 这两个函数都可以用来对图像进行归一化,但它们的具体用途略有不同:

    • convertTo() 函数用于将一个 cv::Mat 对象的像素类型转换为另一种类型,它可以用于进行不同类型之间的转换,包括归一化。例如,可以将图像从8位无符号整数转换为32位浮点数类型,也可以将像素值映射到特定范围内。
    • normalize() 函数专门用于将图像的像素值归一化到指定的范围内,通常是 [0, 1] 或 [0, 255]。这是一种特定于归一化的函数,通常用于数据预处理等情况。

    两者可以根据实际需要来选择使用,但请注意它们的不同用途和参数。如果你只需要进行简单的归一化操作,那么 normalize() 可能更为直观和方便。如果需要进行更复杂的类型转换,包括将图像从一种类型转换为另一种类型,那么 convertTo() 可能更为适合。

  • 相关阅读:
    黑马Java热门面试题Redis(九)
    Positive Technologies 利用 PT Cloud Application Firewall 保护中小型企业的网络资源
    Spring Cloud OpenFeign系列:简介和使用
    ssm教务系统网站毕业设计源码290915
    @JSONField注解的使用
    为保障小程序安全,安装SSL证书是必要的选择
    C++ PrimerPlus 复习 第三章 处理数据
    AtCoder abc137
    读《山本》
    我的Qt作品(15)使用Qt+OpenCV实现一个卡尺工具,具备找线和找圆的功能
  • 原文地址:https://blog.csdn.net/qq_33867131/article/details/132991294