使用MLX90640自制红外热像仪(三):图像插值、图像彩色编码

99 篇文章 105 订阅

  经过上一节,已经把MLX90640的32x24个像素点读出来了,可是使用32x24直接显示在屏幕上,显示区域显示太小了,于是就需要对图像就行放大。

图像插值

  常见的插值算法可以分为两类:自适应和非自适应。 自适应的方法可以根据插值的内容来改变(尖锐的边缘或者是平滑的纹理),非自适应的方法对所有的像素点都进行同样的处理。 非自适应算法包括:最近邻,双线性,双三次,样条,sinc,lanczos等。 由于其复杂度, 这些插值的时候使用从0 to 256 (or more) 邻近像素。 包含越多的邻近像素,他们越精确,但是花费的时间也越长。这些算法可以用来扭曲和缩放照片。
在这里插入图片描述

  具体实现可以参考这两篇文章,他们已经说得很详细了:图像插值算法总结双线性内插值算法
  插补后的效果如下:
在这里插入图片描述

图像彩色编码

  现在把32x24像素点放大了10倍,得到了320x240像素点,但是这些像素点还都是-40度到300度的温度值,要怎么转换成彩色来显示呢?
  其实都已经有转换规范了,而且还有很多种方案:
在这里插入图片描述
  温度转颜色的方法
(1)首先假设温度范围的上下限并将实际的温度数据转换为 0~255 之间的数值
(2)使用转换后的数值代入下面的伪彩编码计算函数,生成伪彩色

//伪彩 1
#define abs(x)      ((x)>0?(x):-(x))
void GrayToPseColor(uint8_t grayValue, uint8_t *colorR,uint8_t *colorG,uint8_t *colorB)
{
    *colorR=abs(0-grayValue);
    *colorG=abs(127-grayValue);
    *colorB=abs(255-grayValue);
}

伪彩 2、金属、彩虹、灰度编码的转换函数为:

void GrayToPseColor(uint8_t converMethod,uint8_t grayValue, uint8_t *colorR,uint8_t *colorG,uint8_t *colorB)  //灰度-伪彩色变换
{
	switch(converMethod)
	{
		case GCM_Pseudo1:
			*colorR=abs(0-grayValue);
			*colorG=abs(127-grayValue);
			*colorB=abs(255-grayValue);		
			break;
			
		case GCM_Pseudo2:	
			if( (grayValue>=0) && (grayValue<=63) )  
			{
				*colorR=0;
				*colorG=0;
				*colorB=round(grayValue/64*255);
			}
			else if( (grayValue>=64) && (grayValue<=127) )  
			{
				*colorR=0;
				*colorG=round((grayValue-64)/64*255);
				*colorB=round((127-grayValue)/64*255);
			}
			else if( (grayValue>=128) && (grayValue<=191) )  
			{
				*colorR=round((grayValue-128)/64*255);
				*colorG=255;
				*colorB=0;
			}
			else if( (grayValue>=192) && (grayValue<=255) )  
			{
				*colorR=255;
				*colorG=round((255-grayValue)/64*255);
				*colorB=0;
			}		
			break;

		case GCM_Metal1:	
			if( (grayValue>=0) && (grayValue<=63) )  
			{
				*colorR=0;
				*colorG=0;
				*colorB=round(grayValue/64*255);
			}
			else if( (grayValue>=64) && (grayValue<=95) )  
			{
				*colorR=round((grayValue-63)/32*127);
				*colorG=round((grayValue-63)/32*127);
				*colorB=255;
			}
			else if( (grayValue>=96) && (grayValue<=127) )  
			{
				*colorR=round((grayValue-95)/32*127)+128;
				*colorG=round((grayValue-95)/32*127)+128;
				*colorB=round((127-grayValue)/32*255);
			}
			else if( (grayValue>=128) && (grayValue<=191) )  
			{
				*colorR=255;
				*colorG=255;
				*colorB=0;
			}
			else if( (grayValue>=192) && (grayValue<=255) )  
			{
				*colorR=255;
				*colorG=255;
				*colorB=round((grayValue-192)/64*255);
			}
			break;
			
		case GCM_Metal2:	
			*colorR=0;*colorG=0;*colorB=0;
			if( (grayValue>=0) && (grayValue<=16) )  
			{
				*colorR=0;
			}
			else if( (grayValue>=17) && (grayValue<=140) )  
			{
				*colorR=round((grayValue-16)/(140-16)*255);
			}
			else if( (grayValue>=141) && (grayValue<=255) )  
			{
				*colorR=255;
			}

			if( (grayValue>=0) && (grayValue<=101) )  
			{
				*colorG=0;
			}
			else if( (grayValue>=102) && (grayValue<=218) )  
			{
				*colorG=round((grayValue-101)/(218-101)*255);
			}
			else if( (grayValue>=219) && (grayValue<=255) )  
			{
				*colorG=255;
			}

			if( (grayValue>=0) && (grayValue<=91) )  
			{
				*colorB=28+round((grayValue-0)/(91-0)*100);
			}
			else if( (grayValue>=92) && (grayValue<=120) )  
			{
				*colorB=round((120-grayValue)/(120-91)*128);
			}
			else if( (grayValue>=129) && (grayValue<=214) )  
			{
				*colorB=0;
			}
			else if( (grayValue>=215) && (grayValue<=255) )  
			{
				*colorB=round((grayValue-214)/(255-214)*255);
			}
			break;		
			
		case GCM_Rainbow1:
			if( (grayValue>=0) && (grayValue<=31) )  
			{
				*colorR=0;
				*colorG=0;
				*colorB=round(grayValue/32*255);
			}
			else if( (grayValue>=32) && (grayValue<=63) )  
			{
				*colorR=0;
				*colorG=round((grayValue-32)/32*255);
				*colorB=255;
			}
			else if( (grayValue>=64) && (grayValue<=95) )  
			{
				*colorR=0;
				*colorG=255;
				*colorB=round((95-grayValue)/32*255);
			}
			else if( (grayValue>=96) && (grayValue<=127) )  
			{
				*colorR=round((grayValue-96)/32*255);
				*colorG=255;
				*colorB=0;
			}
			else if( (grayValue>=128) && (grayValue<=191) )  
			{
				*colorR=255;
				*colorG=round((191-grayValue)/64*255);
				*colorB=0;
			}
			else if( (grayValue>=192) && (grayValue<=255) )  
			{
				*colorR=255;
				*colorG=round((grayValue-192)/64*255);//0
				*colorB=round((grayValue-192)/64*255);
			}		
			break;
			
		case GCM_Rainbow2:
			if( (grayValue>=0) && (grayValue<=63) )  
			{
				*colorR=0;
				*colorG=round((grayValue-0)/64*255);
				*colorB=255;
			}
			else if( (grayValue>=64) && (grayValue<=95) )  
			{
				*colorR=0;
				*colorG=255;
				*colorB=round((95-grayValue)/32*255);
			}
			else if( (grayValue>=96) && (grayValue<=127) )  
			{
				*colorR=round((grayValue-96)/32*255);
				*colorG=255;
				*colorB=0;
			}
			else if( (grayValue>=128) && (grayValue<=191) )  
			{
				*colorR=255;
				*colorG=round((191-grayValue)/64*255);
				*colorB=0;
			}
			else if( (grayValue>=192) && (grayValue<=255) )  
			{
				*colorR=255;
				*colorG=round((grayValue-192)/64*255);
				*colorB=round((grayValue-192)/64*255);
			}
			break;
			
		case GCM_Rainbow3:
			if( (grayValue>=0) && (grayValue<=51) )  
			{
				*colorR=0;
				*colorG=grayValue*5;
				*colorB=255;
			}
			else if( (grayValue>=52) && (grayValue<=102) )  
			{
				*colorR=0;
				*colorG=255;
				*colorB=255-(grayValue-51)*5;
			}
			else if( (grayValue>=103) && (grayValue<=153) )  
			{
				*colorR=(grayValue-102)*5;
				*colorG=255;
				*colorB=0;
			}
			else if( (grayValue>=154) && (grayValue<=204) )  
			{
				*colorR=255;
				*colorG=round(255-128*(grayValue-153)/51);
				*colorB=0;
			}
			else if( (grayValue>=205) && (grayValue<=255) )  
			{
				*colorR=255;
				*colorG=round(127-127*(grayValue-204)/51);
				*colorB=0;
			}
			break;
		
		case GCM_Zhou:
			if( (grayValue>=0) && (grayValue<=63) )  
			{
				*colorR=0;
				*colorG=round((64-grayValue)/64*255);
				*colorB=255;
			}
			else if( (grayValue>=64) && (grayValue<=127) )  
			{
				*colorR=0;
				*colorG=round((grayValue-64)/64*255);
				*colorB=round((127-grayValue)/64*255);
			}
			else if( (grayValue>=128) && (grayValue<=191) )  
			{
				*colorR=round((grayValue-128)/64*255);
				*colorG=255;
				*colorB=0;
			}
			else if( (grayValue>=192) && (grayValue<=255) )  
			{
				*colorR=255;
				*colorG=round((255-grayValue)/64*255);
				*colorB=0;
			}		
			break;
			
		case GCM_Ning:
			if ((grayValue>=0) && (grayValue<=63))  
			{
				*colorR=0;
				*colorG=254-4*grayValue;
				*colorB=255;
			}
			else if ((grayValue>=64) && (grayValue<=127))  
			{
				*colorR=0;
				*colorG=4*grayValue-254;
				*colorB=510-4*grayValue;
			}
			else if ((grayValue>=128) && (grayValue<=191))  
			{
				*colorR=4*grayValue-510;
				*colorG=255;
				*colorB=0;
			}
			else if ((grayValue>=192) && (grayValue<=255))  
			{
				*colorR=255;
				*colorG=1022-4*grayValue;
				*colorB=0;
			}
			break;
			
		case GCM_Gray:	
			*colorR=grayValue;
			*colorG=grayValue;
			*colorB=grayValue;
			break;
			
		default:
			break;
	}
}
  • 13
    点赞
  • 142
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

【ql君】qlexcel

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值