opencv mat 类型转换 CV_32FC1--CV_8U

g++ arry_cv.cpp `pkg-config opencv --cflags --libs`
 

原文链接

 

我试图使用imshow功能显示CV_32F类型的图像,但它显示一个WHITE图像。在Documentation中,它给出的浮点图像将映射到0-255并显示,但它只显示一个白色图像。我尝试将其转换为CV_8U使用

Mat A=Mat::ones(300,300,CV_32FC1)*1000;

do some processing – assigning float values to pixels in A

……

Mat B;

A.convertTo(B,CV_8U)

当我看到’B’我得到一个黑色&白色的图像,没有灰色的阴影。 A中的浮点像素是否正确映射到0-255?我做错了什么?

A中的一些浮点数在处理过程中被分配,A中的几个值都是初始化的1000。

-------------------------------------------------------------------------------------------------------------------------------------------------------------

最佳答案

在OpenCV中,如果图像是浮点类型,那么只有这些像素可以使用imshow进行可视化,imshow的值从0.0到1.0,如果该值大于1.0,它将显示为一个白色像素,如果小于0.0,它将显示为黑色像素。
为了可视化浮点图像,将其值缩放到范围0.0-1.0。

对于转换部分….当与默认参数一起使用时,cv :: Mat :: convertTo函数只创建一个指定类型的矩阵,然后从源矩阵中复制值,然后将其舍入到最接近的可能目标数据类型的值。
如果值超出范围,则将其钳制到最小值或最大值。

在imshow的文档中,它写成:

If the image is 32-bit floating-point, the pixel values are multiplied
by 255. That is, the value range [0,1] is mapped to [0,255].

这意味着只有0.0到1.0范围内的值将被映射到0到25​​5.如果一个值大于1.0,并且乘以255,它将变得大于255.比它将被钳位到CV_8U的范围最终也将成为255。

在您的示例中,所有值为1000的值将在目标矩阵中变为255,因为目标类型为CV_8U,最大可能值为255.所有浮点值都将被放置。没有自动映射完成。

为了适当地将值映射到CV_8U的范围,请使用函数cv :: Mat :: convertTo的第3和第4个参数,以便在转换完成之前对这些值进行缩放。

假设矩阵A具有最小和最大值Min和Max,其中Min!= Max。

要正确地将值从0缩放到255,您可以执行以下操作:

if (Min!=Max){ 
    A -= Min;
    A.convertTo(B,CV_8U,255.0/(Max-Min));
}

您也可以直接这样做:

if (Min!=Max)
    A.convertTo(B,CV_8U,255.0/(Max-Min),-255.0*Min/(Max-Min));

 编译命令 :g++ arry_cv.cpp `pkg-config opencv --cflags --libs`

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include 
#include 

using namespace std;
using namespace cv;

void InitMat(Mat& m,float(*p)[255])
{
 for(int i=0;i(i,j)=*(*(p+i)+j);
}

int main()
{
	float a[255][255] = {0};
	for(int i = 0; i < 255; i++)
	{
		//0cout << "第 " << i << "行  " << endl;
		for(int j = 0; j < 255; j++)
		{
			a[i][j] = j;
			//cout << a[i][j];
		}
		//cout << endl;
	}
	//Mat temp(255, 255, CV_8UC1, a);
	Mat temp(255,255,CV_32FC1);
	InitMat(temp,a);
	Mat B;
	temp.convertTo(B, CV_8U, 255.0/255);//映射到0-255
	imshow("a", B);
	cout << "temp" << temp << endl;
	waitKey();
	return 0;
}

 

你可能感兴趣的:(Opencv,C++)