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

时间:2016-04-21 18:15:55

标签: c++ opencv type-conversion

即使我的输入图像是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时,我做错了什么,这正在改变价值观?

1 个答案:

答案 0 :(得分:0)

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

您可以使用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,因此您可以这样写channel

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