为什么我无法正确转换为 8UC3?

Why can't I convert to 8UC3 correctly?

本文关键字:转换 8UC3 为什么      更新时间:2023-10-16
即使

我的输入图像是 16 位,我也想以 8 位执行轮廓。给定 raw 类型的 16UC3 的输入图像,我找到每个通道的最小值/最大值

double min, max;
double min0, max0;
double min1, max1;
double min2, max2;
cv::minMaxLoc(raw, &min, &max);
cv::minMaxLoc(channel(raw,0), &min0, &max0);
cv::minMaxLoc(channel(raw,1), &min1, &max1);
cv::minMaxLoc(channel(raw,2), &min2, &max2);
fprintf(stderr, "max = %f %f %f %f!n", max, max0, max1, max2);

其中channel

cv::Mat channel(cv::Mat A, int ich) {
    cv::Mat C[3];
    for(int i = 0; i < 3; i++) {
        C[i] = cv::Mat::zeros( cv::Size(A.rows, A.cols), A.type());
    }   
    cv::split(A, C); 
    return C[ich];
}

然后,我尝试创建一个 8 位图像

cv::Mat raw256(raw.clone());
raw.convertTo(raw256, CV_8UC3);

但是当我打印出相同的信息时:

cv::minMaxLoc(raw256, &min, &max);
cv::minMaxLoc(channel(raw256,0), &min0, &max0);
cv::minMaxLoc(channel(raw256,1), &min1, &max1);
cv::minMaxLoc(channel(raw256,2), &min2, &max2);

我得到非常不同的结果,如图所示:

max = 29952.000000 0.000000 29952.000000 26880.000000!
max = 255.000000 0.000000 255.000000 255.000000!

这也会导致我的程序后面出现段错误。我在构建正在改变价值观的raw256中做错了什么?

convertTo将使>255255的所有值饱和。这就是为什么你会看到那些奇怪的价值观。

您可以将convertTo与适当的缩放一起使用:

raw.convertTo(raw256, CV_8U, 1. / 256.);

实际上,这将首先将raw值转换为范围[0, 255],然后安全地将它们转换为CV_8U

请注意,您还可以使用 normalize

normalize(raw, raw256, 0, 255, NORM_MINMAX);

这将使 raw 中的最小值变为 0,最高值变为 255 ,其他值将相应地缩放。


附带说明一下,您不需要预先分配OutputArray s,因此您可以像这样编写channel

cv::Mat channel(cv::Mat A, int ich) {
    cv::Mat C[3];
    cv::split(A, C); 
    return C[ich];
}