1303|0

183

帖子

12

TA的资源

一粒金砂(高级)

楼主
 

【2022得捷电子创新设计大赛】我只是图像的搬运工 [复制链接]

  本帖最后由 nemon 于 2022-10-30 15:27 编辑

这次做扫码显示功能。有个camera的例程,是从摄像头得到jpeg的图,然后转换成RGB565的数组,喂给lcd屏。

首先要解决在动态图上画框、写字的问题。

字模好办,用 KEIL带的  Font_6x8_h.h。写了个函数用于提取:

const unsigned int Font_cnt = 96;
const unsigned char Font_key[] = {
	' ' ,'!' ,'"' ,'#' ,'$' ,'%' ,'&' ,'\'','(' ,')' ,'*' ,'+' ,
	',' ,'-' ,'.' ,'/' ,'0' ,'1' ,'2' ,'3' ,'4' ,'5' ,'6' ,'7' ,
	'8' ,'9' ,':' ,';' ,'<' ,'=' ,'>' ,'?' ,'@' ,'A' ,'B' ,'C' ,
	'D' ,'E' ,'F' ,'G' ,'H' ,'I' ,'J' ,'K' ,'L' ,'M' ,'N' ,'O' ,
	'P' ,'Q' ,'R' ,'S' ,'T' ,'U' ,'V' ,'W' ,'X' ,'Y' ,'Z' ,'[' ,
	'\\',']' ,'^' ,'_' ,'\'','a' ,'b' ,'c' ,'d' ,'e' ,'f' ,'g' ,
	'h' ,'i' ,'j' ,'k' ,'l' ,'m' ,'n' ,'o' ,'p' ,'q' ,'r' ,'s' ,
	't' ,'u' ,'v' ,'w' ,'x' ,'y' ,'z' ,'{' ,'|' ,'}' ,'~' ,' ' ,
};
unsigned char * Font_BMP(char c){
	unsigned int i=0;
	unsigned char * p = (unsigned char *)Font_6x8_h ;
	for(i=0;i<Font_cnt;i++){
		if(c==Font_key){
			p += i*8 ;
			return p ;
		}
	}
	return p;
}

画图遇到点小问题,例程里为了迁就lcd库,rgb565定义成了uint8_t数组。但是RGB565是16位啊,所以刚开始总是花屏乱码,后来强制(uint16_t*)rgb565就好了。

这样画图就变成了在数组里填色:


void draw_point(uint16_t* data, int y,int x,uint16_t color){
	data[ y * IMAGE_WIDTH + x ] =  color  ;
	return ;
}
void draw_rect(uint16_t* data, int y,int x,int h,int w,uint16_t color){
	int i,j;
	for(i=0;i<h;i++){
		for(j=0;j<w;j++){
			draw_point( data, y+i,x+j,color);
		}
	}
	return ;
}
void draw_rect0(uint16_t* data, int y,int x,int h,int w,uint16_t color){
	int i,j;
	for(i=0;i<h;i++){
		draw_point( data, y+i,x,color);
	}
	for(i=0;i<h;i++){
		draw_point( data, y+i,x+w-1,color);
	}
	for(j=0;j<w;j++){
		draw_point( data, y,x+j,color);
	}
	for(j=0;j<w;j++){
		draw_point( data, y+h-1,x+j,color);
	}
	return ;
}

而写字就是按字模点点儿:


void set_char_6x8(uint16_t* data, int y,int x,unsigned char font[8] ,int color_black,uint16_t color_white ){
	int i,j,h=8,w=6,v;
	for(i=0;i<h;i++){
		for(j=0;j<w;j++){
			v=  font & ( 1<<(w-j-1) ) ; 
			if(v>0){
				data[ (y+i)*IMAGE_WIDTH + x+(w-j-1)] =  color_black ;
			}else{
				data[ (y+i)*IMAGE_WIDTH + x+(w-j-1)] =  color_white ;
			}
		}
	}
	return ;
}

void show_msg_6x8(uint16_t* data, int line ,int left,char * msg ){
	int i=0,j=0,n=0,l=strlen(msg);
	unsigned char * font;
	while(line + i<IMAGE_HIGHT-8 && n <l){
		while(left +j< IMAGE_WIDTH -6 && n<l){
			font = Font_BMP( *(msg + n ) );
			set_char_6x8( data, i+line , j+left ,font ,COLOR_BLACK, COLOR_WHITE );
			//printf( "[%d,%d]\n", i+line , j+left  );
			n++;
			j+=6;
		}
		i+=8;
		j=0;
	}
	return ;
}

这个项目,没有用二维码,闭门造车德搞了一个彩色码(就是图省事)。

 识别起来算法也容易——在屏幕上画4个框,当每个框里颜色的平均值符合阈值时,就认为是该颜色,那么4个框就的组合就可以确定一个简短的代码了。

取景待扫描状态是这样的:

然后把刚才那张纸在镜头前一晃(别太快),还是用数组取数,分别求rgb三色的平均值:

int get_avg(uint16_t* data, int y,int x,int h,int w,int left ,int length ){
	int i,j,v,mask=(1<<length)-1;
	long long sum=0;
	for(i=0;i<h;i++){
		for(j=0;j<w;j++){
			v=(  uint16_exchange_HL(data[ (y+i)*IMAGE_WIDTH + (x+j) ])  >> left ) & mask ;
			sum+=v;
		}
	}
	//printf("%lld -> %lld . %d \n", sum ,sum/(w*h) ,mask );
	return sum/(w*h);
}

int ger_color_idx( uint8_t r , uint8_t g , uint8_t b ){
	if(r>COLOR_THRESHOLD_HIGH_RED && g <=COLOR_THRESHOLD_LOW_GREEN && b<=COLOR_THRESHOLD_LOW_BLUE){
		return COLOR_CAM_RED;
	}
	if(r<=COLOR_THRESHOLD_LOW_RED && g >COLOR_THRESHOLD_HIGH_GREEN && b<=COLOR_THRESHOLD_LOW_BLUE){
		return COLOR_CAM_GREEN;
	}
	if(r<=COLOR_THRESHOLD_LOW_RED && g <=COLOR_THRESHOLD_LOW_GREEN && b>COLOR_THRESHOLD_HIGH_BLUE){
		return COLOR_CAM_BLUE;
	}
	if(r>COLOR_THRESHOLD_HIGH_RED && g >COLOR_THRESHOLD_HIGH_GREEN && b>COLOR_THRESHOLD_HIGH_BLUE){
		return COLOR_CAM_WHITE;
	}
	return COLOR_CAM_UNKONW;
	
}

int check_color_idx( int r0, int g0, int b0, int r1, int g1, int b1, int r2, int g2, int b2, int r3, int g3, int b3 ){
	if(
		   COLOR_CAM_WHITE  == ger_color_idx( r0,g0,b0 )
		&& COLOR_CAM_GREEN  == ger_color_idx( r1,g1,b1 )
		&& COLOR_CAM_RED    == ger_color_idx( r2,g2,b2 )
		&& COLOR_CAM_BLUE   == ger_color_idx( r3,g3,b3 )
	){
		return 2;
	}
	return -1;
}

这样就可以识别了,结果是这样:

显示内容很简单:" You find it ! This is a leaf ."

遗憾的是,增加网络功能后,出现了摄像头申请DMA内存不够了,还未解决。

I (5874) cam_hal: buffer_size: 16384, half_buffer_size: 1024, node_buffer_size: 1024, node_cnt: 16, total_cnt: 15
I (5874) cam_hal: Allocating 15360 Byte frame buffer in PSRAM ...
E (5884) cam_hal: cam_dma_config(310): frame buffer malloc failed
E (5884) cam_hal: cam_config(394): cam_dma_config failed
E (5894) camera: Camera config failed with error 0xffffffff
E (5904) decode-TAG: Camera Init Failed

视频演示了操作过程,我给这个码配的展品有点小……

VID_20221030_115503 扫描彩色码

福利——源码:识别彩色码

 

 

 

点赞 关注
 
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表