opencv cv::convertTo()函数

bwntbbo3  于 2023-04-07  发布在  其他
关注(0)|答案(1)|浏览(154)

我正在遵循《使用OpenCV库在C++中学习OpenCV 3计算机视觉》一书中的示例,示例12-1中的以下部分让我感到困惑:

A.convertTo(dft_A_part, dft_A_part.type(), 1, -mean(A)[0]);

作为该操作的结果,我期望在从每个值中减去值mean(A)[0]之后将A的值复制到dft_A_part
不是这样的,所以我很困惑。
Acv::Mat (CV_8U)
dft_A_partcv::Mat (CV_32_F)
一些观察值:
平均值(A)[0] = 88.65
A.data[0] = 77,dft_A_part.data[0] = 136.0
A.data[1] = 77,dft_A_part.data[1] = 140.0
A.data[2] = 79,dft_A_part.data[2] = 58.0
我知道在cv::convertTo()中应用了saturation_cast<>,但这怎么会导致这些数字呢?

laawzig2

laawzig21#

dft_A_part.data是指向uchar的指针,dft_A_part的类型是float
dft_A_part.data[0]dft_A_part.data[1]dft_A_part.data[2]表示float元素的第一、第二和第三字节。
内存中float元素的值是-11.65f
float元素以IEEE 754存储为4个字节。
我们在这里得到的值是没有意义的(只是尾数的一部分)。
注意dft_A_part.data[0] = 136而不是136.0 ...
除了使用dft_A_part.data[0],我们还可以用途:dft_A_part.at<float>(0, 0)
我们也可以将data转换为浮点指针:float *data_as_float = (float*)dft_A_part.data;
代码示例:

#include <iostream>
#include "opencv2/opencv.hpp"

int main()
{
    const double meanA = 88.65; // Assume mean(A)[0] equals 88.65

    cv::Mat A = cv::Mat(1, 3, CV_8UC1); // Create new matrix with 1 row, 3 columns of type uchar.
    A.at<uchar>(0, 0) = 77;
    A.at<uchar>(0, 1) = 77;
    A.at<uchar>(0, 2) = 79;

    cv::Mat dft_A_part = cv::Mat(1, 3, CV_32FC1); //Create new matrix with 1 row, 3 columns of type float.

    A.convertTo(dft_A_part, dft_A_part.type(), 1, -meanA);  //Convert A to float and add -88.65

    //data[0], data[1], data[2] are meaningless
    //std::cout << "dft_A_part.data[0] = " << std::to_string(dft_A_part.data[0]) << std::endl;
    //std::cout << "dft_A_part.data[1] = " << std::to_string(dft_A_part.data[1]) << std::endl;
    //std::cout << "dft_A_part.data[2] = " << std::to_string(dft_A_part.data[2]) << std::endl;

    //Print 3 elements using .at function:
    std::cout << "dft_A_part.at<float>(0, 0) = " << std::to_string(dft_A_part.at<float>(0, 0)) << std::endl;
    std::cout << "dft_A_part.at<float>(0, 1) = " << std::to_string(dft_A_part.at<float>(0, 1)) << std::endl;
    std::cout << "dft_A_part.at<float>(0, 2) = " << std::to_string(dft_A_part.at<float>(0, 2)) << std::endl << std::endl; 

    //Print 3 elements using casting data to float pointer:
    float *data_as_float = (float*)dft_A_part.data;
    std::cout << "data_as_float[0] = " << std::to_string(data_as_float[0]) << std::endl;
    std::cout << "data_as_float[1] = " << std::to_string(data_as_float[1]) << std::endl;
    std::cout << "data_as_float[2] = " << std::to_string(data_as_float[2]) << std::endl;
}

输出:

dft_A_part.at<float>(0, 0) = -11.650002
dft_A_part.at<float>(0, 1) = -11.650002
dft_A_part.at<float>(0, 2) = -9.650002

data_as_float[0] = -11.650002
data_as_float[1] = -11.650002
data_as_float[2] = -9.650002

正如我们所看到的,在添加偏移量之前执行了数据转换为float(未使用saturation_cast)。

相关问题