当前位置: 首页 > 编程日记 > 正文

XMOVE3.0手持终端——软件介绍(五):在2KB内存的单片机上实现的T9中文输入法

编者注: X-MOVE是作者在业余时间于2010年6月份启动的以运动传感开发,算法和应用的平台,目前已经发展了三个版本,第四版的开发接近尾声。发布在博客园仅为交流技术,不存在商业目的,作者保留一切权利。

一. 综述

所谓T9,指的是在手机上广为流传的九宫格输入法。中文输入法大家每天都在使用,那么多大的空间才能承载一个输入法呢?搜狗安装包已经20M了,手机版本的也有2M。但我会告诉你,实现中文输入法仅需要14KB的存储空间和不到100byte的内存。虽然没有联想,并只支持拼音,但已经足够surprising了~

输入法的词组和数据结构定义是我大三时从某个不知名的网站上巴拉下来并移植到我的XMOVE平台下的嵌入式手持终端上的,现在实在想不起其真实来源了。我对它做了必要的改进,并优化了存储结构,想必算法的原作者也会乐于接受的吧。

以下是它的运行时实物截图:

它具有如下特点:

  • 低内存和低CPU占用
  • 支持摇动系统旋转输入字符(需陀螺仪支持)
  • 支持中英文混合输入
  • 由于物理按键不足,因此采用了屏幕虚拟键盘

与XMOVE手持终端相关的介绍文章列表如下:

系统综述: 自制的彩屏手持动作感应终端

软件介绍(一):精简型嵌入式系统的菜单实现和任务切换

软件介绍(二):在2KB内存单片机上实现的彩屏GUI控件库

软件介绍(三):在2KB内存单片机上实现的俄罗斯方块

软件介绍(四):在2KB内存单片机上实现的超精简五子棋算法

软件介绍(五):在2KB内存的单片机上实现的T9中文输入法

二. 数据结构和数据

从直觉来说,实现输入法的必要条件是建立索引,因为中文常用词就已经两三千。同时,应该在没有完成拼音输入之前就能获得可能的结果,例如,输入zhua,那么系统会提供来自zhua,zhuang,zhuan的汉字显示,而并非仅仅提供zhua。

通常的手机输入功能是这样的:

我们可以朴素的思考,我们建立一组拼音字符串(如"zhua")与相应汉字列表(如“抓爪...”),那么每次更新拼音字符串后,就只需要搜索匹配的汉字列表了。但实际上问题并非这么简单,这个表可能有200多条(可能的拼音字符串就有200种,没有仔细统计过),每次都在这里搜索,无疑会很慢。为了提升速度,应该将该表进行分割,通常可以根据按下的第一个键分割成10个拼音索引表。这样每组表只有20多个,大大提升了搜索速度。

数字按键组合,组合成16进制,比如按键246则为0x246。

通过这些基本思想,我们确定如下的数据结构。

1. 必要的结构体定义

相关信息都在注释上解释清楚了。

struct t9PY_index   //拼音索引结构
{const unsigned long  t9PY;   //对应的索引号const unsigned char *PY;  //显示的拼音字符串const unsigned char *PY_mb;  //对应的汉字排列表
};struct t9py_struct   
{unsigned char  pysrf;       //输入法选项unsigned char  firstno;     //输入的第一个数字按键unsigned char  mblen;       //查出码表的长度unsigned char  mbtimes;     //码表切换的次数unsigned long t9py;        //数字按键组合,组合成16进制,比如按键246则为0x246const struct t9PY_index  *t9PY_addr;
};

2. 汉字排列表

const unsigned char PY_mb_space []={""};
const unsigned char PY_mb_a     []={"啊阿呵吖嗄腌锕"};
const unsigned char PY_mb_ai    []={"爱矮挨哎碍癌艾唉哀蔼隘埃皑呆嗌嫒瑷暧捱砹嗳锿霭"};
const unsigned char PY_mb_an    []={"按安暗岸俺案鞍氨胺厂广庵揞犴铵桉谙鹌埯黯"};
const unsigned char PY_mb_ang   []={"昂肮盎仰"};
const unsigned char PY_mb_ao    []={"袄凹傲奥熬懊敖翱澳嚣拗媪廒骜嗷坳遨聱螯獒鏊鳌鏖"};
const unsigned char PY_mb_ba    []={"把八吧爸拔罢跋巴芭扒坝霸叭靶笆疤耙捌粑茇岜鲅钯魃"};
const unsigned char PY_mb_bai   []={"百白摆败柏拜佰伯稗捭呗掰"};
const unsigned char PY_mb_ban   []={"半办班般拌搬版斑板伴扳扮瓣颁绊癍坂钣舨阪"};
///省略....

//下面是英文对应的排列表
const unsigned char PY_mb_abc []={"abc"};

汉字排列表较容易理解,就是某拼音下对应的汉字数组,注意加上了const。在单片机环境中它会默认存储在flash中而不是内存,这样可以优化存储。

3. 拼音索引表

const struct t9PY_index  t9PY_index0[] ={0x00," ",PY_mb_bd};        //1
const struct t9PY_index  t9PY_index1[] ={0x20," ",PY_mb_space};    //1
const struct t9PY_index  t9PY_index2[] ={{0x2,"a",PY_mb_a},       //55
{0x22,"ba",PY_mb_ba},
{0x22,"ca",PY_mb_ca},
{0x224,"bai",PY_mb_bai},
{0x224,"cai",PY_mb_cai},
{0x226,"ban",PY_mb_ban},
{0x226,"bao",PY_mb_bao},
{0x226,"can",PY_mb_can},
{0x226,"cao",PY_mb_cao},
{0x226,"cen",PY_mb_cen},
{0x2264,"bang",PY_mb_bang},
{0x2264,"cang",PY_mb_cang},
{0x23,"ce",PY_mb_ce},
{0x234,"bei",PY_mb_bei},
{0x236,"ben",PY_mb_ben},
{0x2364,"beng",PY_mb_beng},
{0x2364,"ceng",PY_mb_ceng},
{0x24,"ai",PY_mb_ai},
{0x24,"bi",PY_mb_bi},
{0x24,"ci",PY_mb_ci},
{0x242,"cha",PY_mb_cha},
{0x2424,"chai",PY_mb_chai},
{0x2426,"bian",PY_mb_bian},
{0x2426,"biao",PY_mb_biao},
{0x2426,"chan",PY_mb_chan},
{0x2426,"chao",PY_mb_chao},
{0x24264,"chang",PY_mb_chang},
{0x243,"bie",PY_mb_bie},
{0x243,"che",PY_mb_che},
{0x2436,"chen",PY_mb_chen},
{0x24364,"cheng",PY_mb_cheng},
{0x244,"chi",PY_mb_chi},
{0x246,"bin",PY_mb_bin},
{0x2464,"bing",PY_mb_bing},
{0x24664,"chong",PY_mb_chong},
{0x2468,"chou",PY_mb_chou},
{0x248,"chu",PY_mb_chu},
{0x24824,"chuai",PY_mb_chuai},
{0x24826,"chuan",PY_mb_chuan},
{0x248264,"chuang",PY_mb_chuang},
{0x2484,"chui",PY_mb_chui},
{0x2484,"chun",PY_mb_chun},
{0x2486,"chuo",PY_mb_chuo},                                        
{0x26,"an",PY_mb_an},
{0x26,"ao",PY_mb_ao},                       
{0x26,"bo",PY_mb_bo},
{0x264,"ang",PY_mb_ang},
{0x2664,"cong",PY_mb_cong},
{0x268,"cou",PY_mb_cou},
{0x28,"bu",PY_mb_bu},
{0x28,"cu",PY_mb_cu},
{0x2826,"cuan",PY_mb_cuan},
{0x284,"cui",PY_mb_cui},
{0x286,"cun",PY_mb_cun},
{0x286,"cuo",PY_mb_cuo}    
};   
//还有大量省略

所谓拼音索引表一共有10个,本节的第一部分就介绍了拼音索引表的用途。以及如下的表:

const unsigned char t9PY_indexlen[10] = {1,1,55,33,38,57,44,79,19,74};   //以每个数字键开始的拼音代码组合数量  

三. 主流程实现

1. 输入法任务初始化

初始化主要设置为默认拼音,输入的拼音字符串和长度默认归零。

  struct t9py_struct t9pyfun; 
void py_init()
{t9pyfun.pysrf=T9PY;t9pyfun.t9PY_addr=t9PY_index1;t9pyfun.t9py=0;  t9pyfun.firstno=' ';t9pyfun.mblen =0;}

2. 查找索引

void py_index_sub(void)
{uchar i;uchar flag = 0x55;unsigned long temp;uchar mblentemp;mblentemp = t9pyfun.mblen;t9pyfun.mblen = 0x00;if ((t9pyfun.pysrf == T9PY) && (t9pyfun.firstno != ' '))           //拼音输入法
    {for (i=0;i<t9PY_indexlen[t9pyfun.firstno];i++)  {if (t9pyfun.t9py == (*(t9PY_index_headno[t9pyfun.firstno]+i)).t9PY){t9pyfun.mblen++;flag = 0xaa;t9pyfun.t9PY_addr = (t9PY_index_headno[t9pyfun.firstno]+i);for (i++;i<t9PY_indexlen[t9pyfun.firstno];i++){if (t9pyfun.t9py == (*(t9PY_index_headno[t9pyfun.firstno]+i)).t9PY)t9pyfun.mblen++;else break;}break;}}if (flag == 0x55)           //没有查找完全对应的拼音组合,
        {for (i=0;i<t9PY_indexlen[t9pyfun.firstno];i++){temp = (*(t9PY_index_headno[t9pyfun.firstno]+i)).t9PY;while (temp > t9pyfun.t9py){temp >>= 4;if (temp == t9pyfun.t9py){t9pyfun.t9PY_addr = t9PY_index_headno[t9pyfun.firstno]+i;t9pyfun.mblen++;i = t9PY_indexlen[t9pyfun.firstno];flag = 0xaa;break;}}             }if (flag == 0x55){t9pyfun.t9py >>= 4;t9pyfun.mblen = mblentemp;}}}else if(t9pyfun.pysrf == T9SZ)             //数字输入
    {t9pyfun.mblen++;t9pyfun.t9PY_addr = &t9PY_sz[t9pyfun.firstno];}else if(t9pyfun.pysrf == T9BD)            //标点输入
    {t9pyfun.mblen++;t9pyfun.t9PY_addr = t9PY_index0;} else if(t9pyfun.pysrf == T9DX)            //大写英文字母输入
    {if ((t9pyfun.firstno>1)&&(t9pyfun.firstno<10)){t9pyfun.mblen++;t9pyfun.t9PY_addr = &t9PY_ABC[t9pyfun.firstno];}} else if(t9pyfun.pysrf == T9XX)            //小写英文字母输入
    {if ((t9pyfun.firstno>1)&&(t9pyfun.firstno<10)){t9pyfun.mblen++;t9pyfun.t9PY_addr = &t9PY_abc[t9pyfun.firstno];}}
}

3. 通过用户输入标识(input_data)实现判断和相关操作:

由于不同的平台,用户输入是完全不同的,因此本部分仅供参考。

实现判断和相关操作
u8 T9InputChoose(u8 x,u8 y,u8 input_data,u8 *buff,u8 *buffin,uchar bufflen)
{if (input_data==0)           // 输入法切换
    {if ((++t9pyfun.pysrf) > T9SZ)t9pyfun.pysrf = T9DX; dispsrf(x,y);}else if (input_data==KEYLEFT_UP+20)       // 输入标点符号,
    {t9pyfun.mblen++;t9pyfun.t9PY_addr = t9PY_index0;}else if ((input_data>0&&input_data<9)||input_data==10||input_data==KEYDOWN_UP+20)      //输入内容
    {if (t9pyfun.pysrf == T9PY){if (input_data>0&&input_data<9)      //输入内容
            {t9pyfun.mbtimes = 0;PY_index = 0;if (t9pyfun.firstno == ' ')t9pyfun.firstno = input_data+1;t9pyfun.t9py = ((t9pyfun.t9py<<4) |  DecToHexFunc(input_data+1) );py_index_sub();}else if (input_data== 10||input_data==KEYDOWN_UP+20)                      //索引切换.
            {t9pyfun.t9PY_addr++;t9pyfun.mbtimes++;PY_index = 0;if (t9pyfun.firstno != ' '){if (t9pyfun.mbtimes >= t9pyfun.mblen){t9pyfun.mbtimes = 0;t9pyfun.t9PY_addr -= t9pyfun.mblen;}}}}else if (t9pyfun.pysrf == T9SZ)                //输入数字
        {buff[(*buffin)++] =0x30+input_data+1;clrindex(x,y,0);}else if ((t9pyfun.pysrf == T9DX) || (t9pyfun.pysrf == T9XX)) //输入字母
        {if (input_data>0&&input_data<9)      //输入内容
            {if (t9pyfun.firstno == ' '){t9pyfun.mbtimes = 0;PY_index = 0;                        t9pyfun.firstno = input_data;t9pyfun.t9py = ((t9pyfun.t9py<<4) | DecToHexFunc(input_data+1));py_index_sub();}                         }}                                            }else if (input_data==11||input_data==KEYRIGHT_UP+20)    // 删除键
    {if (t9pyfun.mblen > 0){                                         if (PY_index == 0)            //删除索引拼音    
            {if ((t9pyfun.t9py > 0) && (t9pyfun.pysrf == T9PY)){t9pyfun.t9py >>= 4;if (t9pyfun.t9py == 0)clrindex(x,y,1);else{ py_index_sub();clrindex(x,y,0);};}else {clrindex(x,y,1);}    }}else if (bufflen > 2)           //删除输入的汉字.
        {buff[--(*buffin)] = 0;buff[--(*buffin)] = 0;}                }else if (input_data==9||input_data==KEYUP_UP+20)   //确认键
    {if (t9pyfun.mblen>0){if (*buffin < bufflen){       select_data(x,y,buff, buffin, bufflen);}else {clrindex(x,y,1);}                    }}else if (input_data==10)  //跳出
    {return 0;}return 1;
}

4. 选择汉字函数

本部分是用户在输入拼音字符串后,在选取输入汉字时的函数。由于系统采用了虚拟键盘,因此必须读取外部的“旋转数据”,选择相应的输入字符。

系统有在汉字列表下有一红色光标,当左右旋转设备时,光标会随之移动,当您需要翻到上一页或下一页时,上下稍微用力摇晃设备即可。当然,这一切也可以通过物理的上下左右按键完成。

void select_data(u8 x,u8 y,uchar *buff,uchar *buffin,uchar bufflen)   //选择汉字函数
{InnerFuncState=1;u8 FlagSet=0;u8 GyroKey;        while(InnerFuncState==1){      key_data=KEYNULL;SetPaintMode(0,COLOR_Red);Circle(x+108+FlagSet*X_Witch_cn,y+7*Y_Witch_cn+5,4,1);        if(GyroControlEN==1){ITG3200ReadData();ITG3200ShowData();delay_ms(150);}elseInputControl();GyroKey=GyroKeyBoardInputMethod(0,1,200,1000);if(GyroKey!=KEYNULL)key_data=GyroKey;GyroKey=KEYNULL;SetPaintMode(0,COLOR_White);Circle(x+108+FlagSet*X_Witch_cn,y+7*Y_Witch_cn+5,4,1);switch(key_data){case KEYUP_UP:if(PY_index>8)PY_index-=9;dispsf(x,y,buff,*buffin);break;case KEYDOWN_UP:if((strlenExt(t9pyfun.t9PY_addr->PY_mb)-(2*(PY_index+8)))>0){PY_index+=9;dispsf(x,y,buff,*buffin);}break;case KEYCANCEL_UP:InnerFuncState=0;break;case KEYLEFT_UP:if(FlagSet>0)FlagSet--;break;case KEYRIGHT_UP:if(FlagSet<8)FlagSet++;break;case KEYENTER_UP:PY_index+=(FlagSet);if (*(*t9pyfun.t9PY_addr).PY_mb > 0x80)          //输入汉字
            {buff[(*buffin)++] = *((*t9pyfun.t9PY_addr).PY_mb+PY_index*2);buff[(*buffin)++] = *((*t9pyfun.t9PY_addr).PY_mb+PY_index*2+1);InnerFuncState=0;clrindex(x,y,1);}else               //输入字符
            {buff[(*buffin)++] = *((*t9pyfun.t9PY_addr).PY_mb+PY_index);//buff[(*buffin)++] = ' ';                InnerFuncState=0;clrindex(x,y,1);}break;}}}

5. 主函数流程

这是系统整个的输入流程,在主循环中,VirtualNumKeyBoardInput函数接收用户输入,用户输入的字符可通过形参的指针传递,返回值作为状态。但返回0时,表明用户选择放弃输入直接退出;返回1时,跳出循环保存,返回2时,继续输入,加20的偏移量,仅仅是为了前后的输入键值匹配。

u8 T9InputTask(u8 x,u8 y, u8 *Buff,u8 *BuffFlag,u8 Max)
{u8 VnKbX=1,VnKbY=1,VnKey;TaskBoxGUI_P(x,y,x+100+9*Y_Witch_cn,y+Y_Witch_cn+108,"中文输入程序",0);PutBitmap(x,y+Y_Witch_cn,VKNUM,0);FontMode(1,COLOR_White);py_init();dispsrf(x,y);OS_func_state=1;while (OS_func_state==1){dispsf(x,y,Buff,*BuffFlag);switch(VirtualNumKeyBoardInput(x,y-Y_Witch_cn,&VnKbX,&VnKbY,&VnKey,0,1)){case 0:return  0;case 1:break;case 2:VnKey+=20;  //加20偏移量break;}T9InputChoose(x,y,VnKey,Buff,BuffFlag,Max);}return 1;}

四. 总结

这些代码也是我在大三时移植和完成的,因此存在大量的C语言印记。

我的最大感受,即使是嵌入式C语言,也应该尽可能的将功能模块化,输入函数仅处理用户输入,显示函数和搜索算法都应该分离。当然,由于C语言没有事件,只能通过返回值确定系统状态,在传递参数较多时,要么传递结构体,要么通过长长的形参表传递,这都是不利于程序维护,也是我的代码需要改进的地方。

整个输入法模块移植起来依旧是需要时间,精力和耐心的。我承认在一篇文章中完整的表述中文输入法算法有些困难,附件将提供完整的源代码供大家参考。

以下是完整源代码。

相关文章:

推荐系统遇上深度学习,9篇阿里推荐论文汇总!

作者 | 石晓文转载自小小挖掘机&#xff08;ID: wAIsjwj&#xff09;业界常用的推荐系统主要分为两个阶段&#xff0c;召回阶段和精排阶段&#xff0c;当然有时候在最后还会接一些打散或者探索的规则&#xff0c;这点咱们就不考虑了。前面九篇文章中&#xff0c;有三篇是召回阶…

ReSharper修改命名风格

默认情况下&#xff0c;ReSharper会建议你全局变量命名使用下划线开头&#xff0c;且第一个字母小写。否则&#xff0c;会给你标记出来&#xff0c;如下&#xff1a; 但我个人不喜欢这种风格&#xff0c;一般使用首字母大写且不带下划线&#xff0c;可以通过配置来调整&#xf…

【Qt】Log4Qt(一)下载、编译

Log4Qt(一)下载、编译 1、下载2、编译2.1 单独编译成库2.2 将源码添加到项目中2.2.1 log4qt.pri分析2.2.2 pro示例如下1、下载 github上星最多的是这个:https://github.com/MEONMedical/Log4Qt 下载log4qt最新(截止2021-12-04)的稳定版本v1.5.1(Qt版本需要Qt5.7.0以上)…

android:退出程序

http://kofi1122.blog.51cto.com/2815761/703751 使用的是定义全局变量的方法

ubuntu中使用apt命令安装ipython失败解决方案

在最近使用ubuntu安装ipython时&#xff0c;出现如下报错&#xff1a; 出现这个问题&#xff0c;主要是因为apt还在运行&#xff0c;故解决方案为&#xff1a; 1、找到并且杀掉所有的apt-get 和apt进程 运行下面的命令来生成所有含有 apt 的进程列表&#xff0c;使用ps和grep命…

【Qt】Log4Qt(二)使用

Log4Qt(二)使用 1、使用TTCCLayout 格式化输出1.1 添加头文件1.2 配置根记录器的输出格式1.3 注册记录器,并输出日志2、最简代码3、将日志写入文件4、使用配置文件:log4qt.properties5、使用配置文件:QSettings6、周期性生成日志文件7、滚动生成日志文件(可以指定日志文件…

B站超全分享!2万人收藏的免费计算机科学速成课

整理 | 一一出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;作为一枚程序员&#xff0c;很多人可能都不太能清晰地说出计算机发展脉络&#xff0c;要想成为优秀的程序员&#xff0c;只会编程是不够的。“读史使人明智”&#xff0c;我们还要了解计算机理论知识&#…

图说:Windows 8使用搜索,快速开启应用

在Windows 8中&#xff0c;“开始菜单”变成的“开始屏幕”&#xff0c;想快速找到需要的应用不是件容易的事&#xff0c;毕竟桌面可以安装太多的应用。 怎么快速找到需要的应用的&#xff0c;其实方法也非常简单&#xff0c;只需在“开始屏幕”下使用键盘&#xff0c;键入需要…

一个可以卷起来的蓝牙键盘,简直是办公码字神器!

作为一个办公室码字党&#xff0c;熊大大一直觉得ipad最大的bug就是码字不方便。以前&#xff0c;我每次码字都会把平板先平放&#xff0c;打字才能顺手╮(╯﹏╰&#xff09;╭后来买了蓝牙键盘&#xff0c;码字方便了&#xff0c;但键盘又大又厚重&#xff0c;日常携带巨不方…

比较v-bind和v-model

简单来说&#xff0c;区别如下&#xff1a;1.v-bind用来绑定数据和属性以及表达式&#xff0c;缩写为&#xff1a;2.v-model使用在表单中&#xff0c;实现双向数据绑定的&#xff0c;在表单元素外使用不起作用 一、v-model v-model多在表单中使用&#xff0c;在表单元素上创建双…

【Qt】Log4Qt(四):周期性输出日志,并且限制日志文件数量

在Log4Qt中存在一个比较大的问题,当使用 DailyRollingFileAppender对日志进行输出时,会无限输出文件,也就是说,当系统运行很久时,日志文件有可能很大,大到无法想象。因此,很多开发者希望在DailyRollingFileAppender中加一个属性,用于配置日志文件的个数。 1、dailyrol…

g13 root

1.官方解锁&#xff1a; 官方已经给出了wildfire S的解锁bootloader教程。需要注意的是&#xff0c;这个解锁之后虽然仍是s-on状态&#xff08;但下边一行显示了unlock&#xff09;&#xff0c;不影响我们将来随意刷机&#xff0c;说白了就相当于s-off了。 准备工作&#xff0c…

【Qt】Log4Qt(三)源码分析

Log4Qt(三)源码分析 1、分层架构1.1 核心对象1.2 支持对象2、源码分析2.1 宏2.1.1 LOG4QT_DECLARE_QCLASS_LOGGER2.1.2 LOG4QT_DECLARE_STATIC_LOGGER2.2类2.2.1 Log4Qt::ClassLogger2.2.2 LogManager2.2.3 PropertyConfigurator2.3 深入理解 rootLogger、logLogger、qtLogge…

GitHub五万星登顶,程序员命令行最全技巧宝典!

作者 | 唐小引封图 | CSDN出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;一个项目 Get 所有命令行技巧&#xff01;最近两天&#xff0c;「The Art of Command Line&#xff08;命令行的艺术&#xff09;」这个开源项目雄踞了 GitHub TOP 榜&#xff0c;直接以 51…

开源硬件:极客们的伟大理想

自 Dennis Allison 在 1975 年发布它的 Tiny BASIC 以来&#xff0c;他倡导的开放、共享的思想得到了多数开发者的认同&#xff0c;这些年&#xff0c;软件开源取得了令人瞩目的成绩。同时&#xff0c;他那句 “让我们站在彼此的肩膀&#xff0c;而不是彼此的脚趾上。”也变成了…

五年12篇顶会论文综述!一文读懂深度学习文本分类方法

作者 | 何从庆来源 | AI算法之心&#xff08;ID&#xff1a;AIHeartForYou&#xff09;最近有很多小伙伴想了解深度学习在文本分类的发展&#xff0c;因此&#xff0c;笔者整理最近几年比较经典的深度文本分类方法&#xff0c;希望帮助小伙伴们了解深度学习在文本分类中的应用。…

Failed to fetch http://mirrors.cloud.aliyuncs.com/

服务器版本&#xff1a;阿里云 ubuntu 16.04 问题&#xff1a;阿里云安装软件时&#xff0c;提示 W: Failed to fetch http://mirrors.cloud.aliyuncs.com/ubuntu/dists/xenial/InRelea se Could not resolve mirrors.cloud.…

【FFmpeg】使用sws_scale将AVFrame转换后的图像数据放入cv::Mat中

1、方法一,伪代码如下 cv::Mat mat; AVFrame avFrame; const int stride[] = {static_cast<int>(mat.step[0])}; ret =

Android之Adapter用法总结

本文转自http://kb.cnblogs.com/a/2328334/&#xff0c;转载请注明原出处。 Android之Adapter用法总结 作者&#xff1a;Devin Zhang 来源&#xff1a;博客园 发布时间&#xff1a;2012-01-20 22:33 阅读&#xff1a;1193 次 原文链接 [收藏] 1.概念 Adapter是连接后端数…

【FFmpeg】ffmpeg命令详解(一)

ffmpeg命令详解(一) 1、命令格式2、简述3、详细说明3.1 过滤器3.1.1 简单的过滤器图3.1.2 复杂的过滤器图3.2 流拷贝1、命令格式 ffmpeg [global_options] {[input_file_options] -i input_url} ... {[output_file_options] output_url} ...global_options:全局选项 input_…

从流感预测到智能决策,深度学习能帮企业做哪些事?

未来将只有两种公司&#xff0c;一种是有人工智能的&#xff0c;一种是不赚钱的。这句话大概可以总结两层意思&#xff0c;一方面人工智能让更多的企业面对更广阔的商业前景&#xff0c;另一方面是如果要运用人工智能创造价值&#xff0c;就必须拥抱技术&#xff0c;实现真正的…

寻找隐形冠军 支付宝、微信用得那么溜,可谁知道背后有一名“上海功臣

下午三点半&#xff0c;离晚饭时间还有一段时间&#xff0c;可新沪路上的熟食店“尚老居”门口已经人头攒动。 “阿姨你来啦&#xff0c;今天要点什么&#xff1f;” “老样子&#xff0c;称点烧鹅和蹄髈&#xff0c;阿拉孙子老欢喜吃的&#xff0c;买好正好去接伊放学。” “阿…

Lnmp安装与配置笔记

——————————————安装与配置——————————————1.相关软件&#xff1a;yum -y install gcc gcc-c autoconf libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml2-devel zlib zlib-devel glibc glibc-devel glib2 glib2-…

【FFmpeg】ffmpeg命令详解(二)

ffmpeg命令详解(二) 4、流选择4.1 自动选择流4.2 手动选择流5、命令行选择详解5.1 命令行选项的值说明:5.2 流说明符5.3 通用选项5.4 主选项5.5 视频相关选项5.6 高级视频选项5.7 音频选项5.8 高级音频选项5.9 字幕选项5.10 高级字幕选项4、流选择 FFmpeg提供了“-map”选项…

谷歌开源张量网络库TensorNetwork,GPU处理提升100倍!

编译 | 琥珀出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;世界上许多最严峻的科学挑战&#xff0c;如开发高温超导体和理解时空的本质&#xff0c;都涉及处理量子系统的复杂性。然而&#xff0c;这些系统中量子态的数量程指数级增长&#xff0c;使得暴力计算并不可…

Python基础之逻辑运算符

1.在没有()的情况下&#xff0c;not的优先级高于and&#xff0c;and的优先级高于or&#xff0c;即优先级关系为()>not>and>or&#xff0c;同一优先级从左往右计算。 例题&#xff0c;判断下列逻辑语句的结果&#xff1a; 3 > 4 or 4 < 3 and 1 1 1 < 2 a…

《Android开发从零开始》——11.AbsoluteLayoutFrameLayout学习

本节课的主要内容有&#xff1a; 1.介绍AbsoluteLayout布局的使用 2.介绍FrameLayout布局的使用 课程下载地址&#xff1a;http://u.115.com/file/f15a9d5411 课件及地址&#xff1a;http://u.115.com/file/f1b56ce345 【转】转载于:https://blog.51cto.com/professor/1573001

【FFmpeg】ffmpeg命令详解(三)高级选项

ffmpeg命令详解(三)高级选项 1、-map2、-ignore_unknown3、-copy_unknown4、-map_channel5、-map_metadata6、-map_chapters7、-benchmark8、-benchmark_all9、-timelimit10、-dump11、-hex12、-readrate13、-re14、-vsync15、-frame_drop_threshold16、-async17、-adrift_th…

重磅!Google推出了Python最牛X的编辑器......

随着和大数据、人工智能绑定在一起&#xff0c;Python可畏是越来越厉害了!前几天&#xff0c; PYPL&#xff08;即编程语言流行指数&#xff0c;基于 Google 搜索频率而定&#xff09;出炉了 6 月编程语言排行榜&#xff0c;Python 拿下 NO.1&#xff0c;成为最流行的编程语言。…

ubuntu16.04 ROS安转及RVIZ启动

1、软件中心配置 首先打开软件和更新对话框&#xff0c;打开后按照下图进行配置&#xff08;确保你的"restricted"&#xff0c; "universe&#xff0c;" 和 "multiverse."前是打上勾的&#xff09;&#xff1a; 2、添加源 $ sudo sh -c echo &qu…