对图像调用cv::distanceTransform 做距离变换,直接显示,结果是一片惨白。
对输出的结果矩阵调用cv::normalize 做归一化后再显示就正常了。
为什么呢?
既然是开源软件,去看源码吧,答案尽在源码中。
以下是OpenCV库源码片断。
void cv::imshow( const String& winname, InputArray _img )
{
......
cvShowImage(winname.c_str(), &c_img);
......
}
CV_IMPL void
cvShowImage( const char* name, const CvArr* arr )
{
......
convertToShow(cv::cvarrToMat(image), dst, false);
......
}
inline void convertToShow(const cv::Mat &src, cv::Mat &dst, bool toRGB = true)
{
const int src_depth = src.depth();
CV_Assert(src_depth != CV_16F && src_depth != CV_32S);
cv::Mat tmp;
switch(src_depth)
{
case CV_8U:
tmp = src;
break;
case CV_8S:
cv::convertScaleAbs(src, tmp, 1, 127);
break;
case CV_16S:
cv::convertScaleAbs(src, tmp, 1/255., 127);
break;
case CV_16U:
cv::convertScaleAbs(src, tmp, 1/255.);
break;
case CV_32F:
case CV_64F: // assuming image has values in range [0, 1)
cv::convertScaleAbs(src, tmp, 256.);
break;
}
cv::cvtColor(tmp, dst, toRGB ? cv::COLOR_BGR2RGB : cv::COLOR_BGRA2BGR, dst.channels());
}
这里看的很清楚,对于CV_32F 和CV_64F 是被假定为已经归一化了来处理的。
上面distanceTransform 出来的矩阵类型是CV_32F,观察数据的话可以发现是1,2,3,4,5。。这些代表距离的原始数据。
归一化后,再观察数据在[0, 1) 区间内分布。
imshow 内部对这种CF_32F 类型的矩阵调用cv::convertScaleAbs 进行调整之后就正常显示了。