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