当前位置:首页 > 消费电子 > 消费电子
[导读]投影仪自动对焦和梯形校正看着像图像算法题,落地到嵌入式Linux其实是“取帧—评价—驱马达”和“顶点检测—单应矩阵—几何变换”两条管线。算法不难,难的是别让OpenCV默认管线把CPU吃满,也别每帧重算矩阵。


投影仪自动对焦和梯形校正看着像图像算法题,落地到嵌入式Linux其实是“取帧—评价—驱马达”和“顶点检测—单应矩阵—几何变换”两条管线。算法不难,难的是别让OpenCV默认管线把CPU吃满,也别每帧重算矩阵。

一、自动对焦:清晰度评价+爬山搜索

反差式对焦本质就一句:镜头动一下,算一帧图的高频能量,找峰值位置。

嵌入式平台别一上来用Tenengrad全图卷积,先降分辨率再截ROI:

/* Brenner梯度,算力紧张首选 */

uint32_t focus_value(uint8_t*y, int w, int h){

   uint32_t s=0;

   for(int i=0;i<h;i++){

       uint8_t*row=y+i*w;

       for(int j=0;j<w-2;j++){

           int d=row[j+2]-row[j];

           s+=(uint32_t)(d*d);

       }

   }

   return s;

}

ARM Linux够用就换Tenengrad/Sobel,峰更尖;低端MIPS用Brenner就行。

主循环别阻塞式“移动→等稳→采图→算分”,马达运动和评分异步:

typedef struct {

   int step;

   uint32_t best_val;

   int best_step;

   int dir;

} af_fsm_t;


void af_step(af_fsm_t*f, uint32_t val){

   if(val > f->best_val){

       f->best_val = val;

       f->best_step = f->step;

   }else if(f->dir==1 && val < f->best_val*0.8){

       motor_goto(f->best_step);   // 峰值过了,回最佳位

       af_done();

   }

   f->step += f->dir? +COARSE : -FINE;

   motor_move(f->step);

}

粗扫大步找峰、细扫小步精修,曝光和增益必须锁死,否则自动曝光一变评分曲线就抖。

二、梯形校正:四角单应矩阵

梯形校正不是仿射拉伸能解决的,必须用完整射影变换(单应矩阵H),否则斜投校正完还是歪。

摄像头拍到投影画面四角 (src),目标矩形四角 (dst),解H:

/* 伪代码:4组对应点 -> 3x3 H */

homography_solve(src[4], dst[4], &H);

校正时用反向映射:遍历输出矩形每个像素,乘H逆矩阵找原图坐标,双线性采样。正向映射会留空洞。

void keystone_remap(uint8_t*dst, uint8_t*src, Mat3 Hinv, int W,int H){

   for(int y=0;y<H;y++){

       for(int x=0;x<W;x++){

           float px=(Hinv.a*x+Hinv.b*y+Hinv.c);

           float py=(Hinv.d*x+Hinv.e*y+Hinv.f);

           float pw=(Hinv.g*x+Hinv.h*y+1.0f);

           int sx=(int)(px/pw), sy=(int)(py/pw);

           dst[y*W+x]= bilinear(src,sx,sy);

       }

   }

}

顶点来源三条路:

摄像头识别投影画面边界

ToF+陀螺仪算姿态角直接推四角

用户手动拖四角(四点校正UI)

三、嵌入式移植关键点

1. V4L2 MMAP取帧,别用cv::VideoCapture默认后端

ARM板直接cv2.VideoCapture(0)常采不到正确格式,走V4L2设YUYV/MJPEG,取Y分量做灰度,省去BGR转换。

2. 分辨率砍到算法够用

对焦取320×240足矣;梯形校正原图也不用全4K跑,缩放后算H再回全分辨率渲染。

3. 零拷贝降带宽

V4L2 MMAP或dma-buf直接给算法,别内核态拷一份到用户态再拷给OpenCV,1080p每多一次拷贝就是6MB。

4. 矩阵缓存,不每帧重算

姿态没变就沿用上一次H,存Param区;只有开机、移动、用户校正才重算。

5. 校正放显示前级

视频解码 → 单应变换 → DRM/KMS上屏。软解用CPU做<30ms还行,大角度侧投走RGA/FPGA硬解,否则延迟和发热都扛不住。

6. 顶点限位防出界

算出的src坐标超出原图,填黑边;目标矩形别超出投影芯片有效区,不然边缘裁掉。

四、落坑清单

自动曝光开着跑对焦→评分曲线漂移

全图Tenengrad→低算力平台卡成幻灯片

马达移动和评分同步等→对焦慢一倍

正向映射做校正→画面空洞

用仿射代替单应→斜投校不直

每帧重算H→CPU空转

校正角过大不裁黑边→画面溢出

OpenCV默认VideoCapture→嵌入式采图花屏

对焦ROI选背景墙→无纹理评分失效

五、落地顺序

V4L2打通取帧,锁曝光

对焦:中心ROI+Brenner/Tenengrad评分

马达驱动异步化,粗扫+细扫

摄像头拍投影画面,提四角

解单应矩阵H,反向映射校正

校正管线接显示前级,dma-buf零拷贝

H缓存+姿态变化才重算

四点手动校正兜底

投影仪这两件事拆开看都不复杂:对焦是“高频能量爬山”,校正是“四角单应变换”。移植到嵌入式Linux的真正工作量在取帧零拷贝、ROI降分辨率、马达/顶点状态机解耦——算法本身抄OpenCV都能跑,但照搬桌面写法板子一定烫、帧率一定掉。对焦锁曝光+粗细分步,校正用反向映射+矩阵缓存,家用微投基本就稳了;大角度侧投再考虑RGA/FPGA硬解分担。



本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
关闭