高效刷题 迎战校招
校招精选试题
2021年IT面笔经面经群内分享
Java刷题群 前端刷题群 产品运营群
红太狼 ID:vB8M+rFA 回复1

关于#STM32#与AMG8833采用双插值算法进行热成像显示不正常的问题,如何解决?

2023-06-02 02:33:36 0
登录后,才能评论哟
黄忠 ID:dyHSbNVw

用STM32F407ZGT6与AMG8833(88点阵)热成像传感器做一个热成像测试,程序采用的是csdn下载的双线性插值的算法,但在实际跑程序过程中,有如下几个问题:
1.2.8寸屏幕(240*320)刷新较慢,需要大概1秒时间才能从左扫到右,
2.最主要的问题是显示的图像仅屏幕左上角及屏幕右侧(一竖线)有不同温度色块显示且刷新,中间区域不显示不同色块且也不刷新。
以下是主程序main.c及屏幕显示截图求支招:

/**
 * AMG8833 8*8图像 双线性插值程序
 * Date:        2020/09/24
 * File Name:    main.c
 * Copyright (c) 2020, cx2008lxl@vip.qq.com All Rights Reserved.
 * @author Li Xinliang
 */
#include main.h

/*256位的温度颜色对照表*/
const uint16_t camColors[] = {0x480F,
                              0x400F,0x400F,0x400F,0x4010,0x3810,0x3810,0x3810,0x3810,0x3010,0x3010,
                              0x3010,0x2810,0x2810,0x2810,0x2810,0x2010,0x2010,0x2010,0x1810,0x1810,
                              0x1811,0x1811,0x1011,0x1011,0x1011,0x0811,0x0811,0x0811,0x0011,0x0011,
                              0x0011,0x0011,0x0011,0x0031,0x0031,0x0051,0x0072,0x0072,0x0092,0x00B2,
                              0x00B2,0x00D2,0x00F2,0x00F2,0x0112,0x0132,0x0152,0x0152,0x0172,0x0192,
                              0x0192,0x01B2,0x01D2,0x01F3,0x01F3,0x0213,0x0233,0x0253,0x0253,0x0273,
                              0x0293,0x02B3,0x02D3,0x02D3,0x02F3,0x0313,0x0333,0x0333,0x0353,0x0373,
                              0x0394,0x03B4,0x03D4,0x03D4,0x03F4,0x0414,0x0434,0x0454,0x0474,0x0474,
                              0x0494,0x04B4,0x04D4,0x04F4,0x0514,0x0534,0x0534,0x0554,0x0554,0x0574,
                              0x0574,0x0573,0x0573,0x0573,0x0572,0x0572,0x0572,0x0571,0x0591,0x0591,
                              0x0590,0x0590,0x058F,0x058F,0x058F,0x058E,0x05AE,0x05AE,0x05AD,0x05AD,
                              0x05AD,0x05AC,0x05AC,0x05AB,0x05CB,0x05CB,0x05CA,0x05CA,0x05CA,0x05C9,
                              0x05C9,0x05C8,0x05E8,0x05E8,0x05E7,0x05E7,0x05E6,0x05E6,0x05E6,0x05E5,
                              0x05E5,0x0604,0x0604,0x0604,0x0603,0x0603,0x0602,0x0602,0x0601,0x0621,
                              0x0621,0x0620,0x0620,0x0620,0x0620,0x0E20,0x0E20,0x0E40,0x1640,0x1640,
                              0x1E40,0x1E40,0x2640,0x2640,0x2E40,0x2E60,0x3660,0x3660,0x3E60,0x3E60,
                              0x3E60,0x4660,0x4660,0x4E60,0x4E80,0x5680,0x5680,0x5E80,0x5E80,0x6680,
                              0x6680,0x6E80,0x6EA0,0x76A0,0x76A0,0x7EA0,0x7EA0,0x86A0,0x86A0,0x8EA0,
                              0x8EC0,0x96C0,0x96C0,0x9EC0,0x9EC0,0xA6C0,0xAEC0,0xAEC0,0xB6E0,0xB6E0,
                              0xBEE0,0xBEE0,0xC6E0,0xC6E0,0xCEE0,0xCEE0,0xD6E0,0xD700,0xDF00,0xDEE0,
                              0xDEC0,0xDEA0,0xDE80,0xDE80,0xE660,0xE640,0xE620,0xE600,0xE5E0,0xE5C0,
                              0xE5A0,0xE580,0xE560,0xE540,0xE520,0xE500,0xE4E0,0xE4C0,0xE4A0,0xE480,
                              0xE460,0xEC40,0xEC20,0xEC00,0xEBE0,0xEBC0,0xEBA0,0xEB80,0xEB60,0xEB40,
                              0xEB20,0xEB00,0xEAE0,0xEAC0,0xEAA0,0xEA80,0xEA60,0xEA40,0xF220,0xF200,
                              0xF1E0,0xF1C0,0xF1A0,0xF180,0xF160,0xF140,0xF100,0xF0E0,0xF0C0,0xF0A0,
                              0xF080,0xF060,0xF040,0xF020,0xF800,
                             };

int main(void)
{

    u8 lcd_id[12]; //存放LCD ID字符串
    u8 temp_max[20]; //存放高温度字符串
    u8 temp_min[20]; //存放低温字符串
    HAL_Init();
    Stm32_Clock_Init(336,8,2,7);
    delay_init(168);
    uart_init(115200);

    SRAM_Init();
    my_mem_init(SRAMIN); //初始化内部内存池
    my_mem_init(SRAMEX); //初始化外部内存池
    my_mem_init(SRAMCCM); //初始化CCM内存池

    LCD_Init();
    EXIIC_Init();
    AMG8883_Init(15, 40); //设定大致温度范围,可使图像颜色差异更明显
    TIM6_Init(10000-1,8400-1); //10Khz计数频率,1秒钟中断

    //定义原图像和扩充图像大小信息
    u8 srcImgW = 8;
    u8 srcImgH = 8;
    u16 dstImgW = 240;
    u16 dstImgH = 320;

    //获取长宽比系数
    double dstAsrcKw = srcImgW/(double)dstImgW;
    double dstAsrcKh = srcImgH/(double)dstImgH;

    //申请内存空间
    u8 *srcColor = (u8 *)mymalloc(SRAMEX, srcImgW*srcImgH);
    u8 *dstColor = (u8 *)mymalloc(SRAMEX, dstImgW*dstImgH);

    u16 i, j;
    u16 srcXaxis, srcYaxis; //目标图像变换到原图像对应的坐标(浮点数)
    u16 srcXint, srcYint; //原坐标浮点数取 整数部分
    u16 srcXdou, srcYdou; //原坐标浮点数取 小数部分

    //速度优化临时变量
    u32 volatile yMUL2048;
    u32 volatile xMUL2048;
    u32 volatile xMULy;
    u32 volatile xintMULwADDy;
    sprintf((char*)lcd_id,LCD ID:%04X,lcddev.id);//将LCD ID打印到lcd_id数组。
    while(1)
    {

        //从传感器读取温度
        AMG8833_GetTemperature(AMG8833_Struct.TMat); //获取温度数据
        printf(Environment: %lf\r\n, AMG8833_GetThermistor);
        printf(OBJ: %lf\r\n,AMG8833_GetOBJT);
        MatSort(AMG8833_Struct.TMat, 64, 1);
        sprintf((char*)temp_max,Temp_MAX:%4.1f,AMG8833_Struct.TMat[0]*0.25);//将最大温度值大隐刀数组temp_max
        sprintf((char*)temp_min,Temp_MIN:%4.1f,AMG8833_Struct.TMat[30]*0.25);//最小温度值大隐刀数组temp_min

//        //范围内的温度转为0~255灰度 范围在AMG8883_Init的形参指定
        //AMG8883_Init(26, 42)即范围为26~42度,0~255的灰度值即对应26~42度
        int imgTemp = 0;
        for(i=0; isrcImgW; i++)
        {
            for(j=0; jsrcImgH; j++)
            {
                imgTemp = (u16)((AMG8833_Struct.TMat[__smlad(i,srcImgW,j)]-AMG8833_Struct.Tmin)*(255/(double)(AMG8833_Struct.Tmax-AMG8833_Struct.Tmin))+0.5); //四舍五入获取原图像灰度值(0~255)///////////////////
                if(imgTemp255) srcColor[__smlad(i,srcImgW,j)] = 255;
                else if(imgTemp0) srcColor[__smlad(i,srcImgW,j)] = 0;
                else srcColor[__smlad(i,srcImgW,j)] = imgTemp;
            }
        }
//        //双线性插值
        for(i=0; idstImgW; i++)
        {
            for(j=0; jdstImgH; j++)
            {
                //根据目的图像坐标 反推原图像坐标
                srcXaxis = ((i+0.5)*dstAsrcKw-0.5)*2046; //+-0.5为了使原图像和目标图像中心对齐
                srcYaxis = ((j+10.5)*dstAsrcKh-0.5)*2046;
                srcXint = srcXaxis11;
                srcYint = srcYaxis11;
                srcXdou = __uqsub16(srcXaxis, (srcXint11)); //速度优化。*2048即扩大2048倍后四舍五入取整
                srcYdou = __uqsub16(srcYaxis, (srcYint11)); //下面计算dstColor时,需将系数部分的1也替换为2048。最后除以2048*2048还原
//
//                // 以下方法二选一
//                //一、根据公式进行 双线性插值
                dstColor[i*dstImgW+j] = ((u32)(((2048-srcXdou)*(2048-srcYdou)*srcColor[srcXint*srcImgW+srcYint] +
                                                (2048-srcXdou)*srcYdou*srcColor[srcXint*srcImgW+(srcYint+1)] +
                                                srcXdou*(2048-srcYdou)*srcColor[(srcXint+1)*srcImgW+srcYint] +
                                                srcXdou*srcYdou*srcColor[(srcXint+1)*srcImgW+(srcYint+1)])+0.5))22;

//                //二、双线性插值 使用DSP运算速度优化
//                //2048*2048        2048*y        2048*x        x*y
//                //2048*y        x*y
//                //2048*x        x*y
//                //x*y
//                xMUL2048 = srcXdou11;
//                yMUL2048 = srcYdou11;
//                xMULy = __smuad(srcXdou,srcYdou);
//                xintMULwADDy = __smlad(srcXint,srcImgW,srcYint);
//                dstColor[__smlad(i,dstImgW,j)] = ((4194304-yMUL2048-xMUL2048+xMULy)*srcColor[xintMULwADDy] +
//                                        (yMUL2048-xMULy)*srcColor[xintMULwADDy+1] +
//                                        (xMUL2048-xMULy)*srcColor[xintMULwADDy+srcImgW] +
//                                        xMULy*srcColor[xintMULwADDy+srcImgW+1])22;


                //查表获取color进行LCD显示
                LCD_Fill(i,j,i+2,j+2,camColors[dstColor[__smlad(i,dstImgW,j)]]);
//            LCD_Fast_DrawPoint(i+40,j+100,camColors[dstColor[__smlad(i,dstImgW,j)]]);
//            LCD_ShowString(30,650,450,16,24,temp_max); //显示最大温度值
//            LCD_ShowString(30,700,450,16,32,temp_min); //显示最小温度值


            }
        }
//        ov_frame++;
//        printf(\r\n);
        //printf(\r\n\r\n);
        //delay_ms(1000);
    }
}


屏幕显示截图

2023-06-02 02:33:36
0 0