问题描述
在嵌入式linux平台上开发QT程序时,采集和显示红外的数据。
我使用的开发环境是正点原子的imx6ull的出厂系统,红外模块是mlx90640,使用opencv将采集到的红外图像显示出来,使用opencv制作界面。
关键词:QT,linux,mlx90640,opencv
问题解决
- 获取红外图像
- 参考链接1,将链接1正确编译后挂载驱动就可以获得温度原始数据从串口中打印出来
- 使用opencv将串口原始数据填入cv ::Mat,参考链接3,再将cv:Mat转换为可以在Opencv中显示的QImage,参考链接2
- 重点修改的转换代码如下,也就是将串口打印更换为输出QImage供QT调用
QImage Mlx90640::MLX90640_Show(){
int fd = mlx90640_fd;
uint16_t double_count = 0;
uint16_t i=0,j=0;
float Ta,tr;
float emissivity=0.95;
static float mlx90640To_Temp[768];
static float mlx90640To[768];
uint16_t frame[834];
static uint16_t data[768*sizeof(float)];
cv::Mat IR_mat(32,24, CV_32FC1, data);
for(double_count = 0; double_count < 2;){
if(0x00 == MLX90640_GetFrameData(fd, frame)){
Ta = MLX90640_GetTa(frame, &mlx90640);
tr = Ta - TA_SHIFT;
printf("mlx90640 Ta:%f tr:%f\n",Ta,tr);
if(0 == double_count)
MLX90640_CalculateTo(frame, &mlx90640, emissivity, tr, mlx90640To);
else
MLX90640_CalculateTo(frame, &mlx90640, emissivity, tr, mlx90640To_Temp);
if(1 == double_count){
//merge data
for(i = 0,j = 0;i<768;i++){
if(i%32 == 0 && i != 0){
j++;
}
if(0 == j%2 && 1 == i%2){
mlx90640To[i] = mlx90640To_Temp[i-1];
}
else if(1 == j%2 && 0 == i%2){
mlx90640To[i] = mlx90640To_Temp[i+1];
}
}
for(int y = 0; y < 24; y++){
for(int x = 0; x < 32; x++){
float val = mlx90640To[32 * y + x];
IR_mat.at<float>(x,y) = val;
}
}
}
double_count++;
}
}
// Normalize the mat
cv::Mat normal_mat;
cv::normalize(IR_mat, normal_mat, 0,1.0, cv::NORM_MINMAX, CV_32FC1);
IR_mat.release();
// Convert Mat to CV_U8 to use applyColorMap
double minVal, maxVal;
cv::minMaxLoc(normal_mat, &minVal, &maxVal);
cv::Mat u8_mat;
normal_mat.convertTo(u8_mat, CV_8U, 255.0/(maxVal - minVal), -minVal);
normal_mat.release();
// Resize mat
// cv::Mat size_mat;
// cv::resize(u8_mat, size_mat, cv::Size(240,320), cv::INTER_CUBIC);
// Apply false color
cv::Mat falsecolor_mat;
// cv::applyColorMap(size_mat, falsecolor_mat, cv::COLORMAP_JET);
// size_mat.release();
cv::applyColorMap(u8_mat, falsecolor_mat, cv::COLORMAP_JET);
u8_mat.release();
const uchar *pSrc = (const uchar*)falsecolor_mat.data;
QImage qImage(pSrc,falsecolor_mat.cols, falsecolor_mat.rows,falsecolor_mat.step,
QImage::Format_RGB888);
return qImage;
}
- 将链接1中的驱动文件进行适配,嵌入到C++的工程文件,主要是将c文件改为c++文件,或者直接使用extern的方式进行c文件的引用(告知IDE要使用gcc进行编译)
extern "C"
{
#include "MLX90640_API.h"
}