精华内容
下载资源
问答
  • 代码中有紧接着两个独立if语句,两个if分别判断两个按键是否按下,是不是下面if不会被执行?
  • 因为独立按键、矩阵按键其实本质上控制原理都一样,都是通过检测高低电平来判断按键是否按下。 先看原理图: 独立按键是最左侧S4-S7四个按键,矩阵按键则为这个4x416个按键。 左侧J5,若用跳帽将2、3短接,则为...

    绝对不能放弃的事!要从“今天”开始!!

    【刚刚调字体颜色的时候才发现,原来调颜色和字体大小也有语句在前面,突然发现了什么不得了的事情……】

    矩阵按键

    为啥我在这只说矩阵按键?
    因为独立按键、矩阵按键其实本质上控制原理都一样,都是通过检测高低电平来判断按键是否按下。
    先看原理图:
    在这里插入图片描述
    独立按键是最左侧的S4-S7四个按键,矩阵按键则为这个4x4的16个按键。
    左侧J5,若用跳帽将2、3短接,则为独立按键模式,若用跳帽将1、2短接,则为矩阵按键模式。

    矩阵按键的使用,就是检测某个按键对应的行列是否同时置0,若是,则按下,若不是,则没按。

    首先,将第一列置0,P3=0x7f。
    【注意】:
    P36 - >P42, P37 - >P44;
    并且若使用的头文件为 <reg52.h>,则应自己定义P4口,sfr P4 = 0xc0;

    第一列置低电平后,可检测第一列的按键哪个按下,若为S7按下,则P30为低电平,则 P3 = 0x7e;
    另外,判断完了之后,还要确定按键是否释放,要有一个while语句。

    其他按键同理。

    对常见写法的分析

    在我学习矩阵按键的过程中最初见到的写法:

    一、延时消抖法

    由于按键需要不停的扫描,达到成功检测的目的,则需要进行消抖测试。
    抖动的原理
    若不对抖动进行检测和处理,就会造成误判。

    #include <reg52.h>
    
    sfr P4 = 0xc0;
    
    sbit P42 = P3^6;
    sbit P44 = P3^7;
    
    void Delay10ms()		//@11.0592MHz
    {
    	unsigned char i, j;
    
    	i = 108;
    	j = 145;
    	do
    	{
    		while (--j);
    	} while (--i);
    }
    
    uchar keyscan()
    {
    	uchar key,temp;
    
    	P3 = 0x7f; 		//令第一列为低电平
    	P42 = 1;P44 = 0;
    	temp &= 0x0f; 	//P3与0x0f相与,若结果不为0x0f,说明代表行的P30-P33中有置低电平的部分,说明有键按下
    	if(temp != 0x0f)
    	{
    		delay10ms();		//延时消抖
    		temp = P3;
    		temp &= 0X0f;			//再次确认是否按下
    		if(temp != 0x0f)		//确实有键按下
    		{
    			temp = P3;
    			swith(temp)
    			{
    				case 0x7e:key = 7;break;
    				case 0x7d:key = 6;break;
    				case 0x7b:key = 5;break;
    				case 0x77:key = 4;break;
    				default:break;
    			}
    			while(temp != 0x0f)		//判断是否释放按键
    			{
    				temp = P3;
    				temp &= 0x0f;
    			}
    		}
    	}
    ……	
    }
    

    就仅举S4-S7来写,其他列同理,只不过若是第二列,则先将P3 = 0xbf,再去判断其他行是否置低电平。

    上面的写法是我之前比较喜欢用的,但是使用延时函数会对整个使用造成比较大的影响。 我之前用的时候就经常会误判,延时函数占用了一部分时间。 在此,给大家推荐另一种方法,也是我逐渐适应的一种写法

    二、中断扫描按键

    此时按键的扫描不再放在主函数中,而是在中断中扫描,通过判断按键状态的持续时间来确定按键是否按下或者弹起。
    隔一段时间扫描一次按键的状态,如果与上一次按键的状态不同,再隔一段时间扫描一次按键状态,如果又改变了,则说明按键完成了一次按下又弹起的动作。

    sbit Key_Out_1 = P3^0;		//行扫描
    sbit Key_Out_2 = P3^1;
    sbit Key_Out_3 = P3^2;
    sbit Key_Out_4 = P3^3;
    
    sbit Key_In_4 = P3^4;		//列扫描
    sbit Key_In_3 = P3^5;
    sbit Key_In_2 = P4^2;
    sbit Key_In_1 = P4^4;
    
    uchar KeySta[4][4] = {{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}};			//储存按键当前值
    uchar code KeyMap[4][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}}; 		//规定16个键分别代表的值
    
    void KeyDriver()
    {
    	uchar i,j;
    	static uchar KeyBack[4][4] = {{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}};	//矩阵按键初始化
    
    	for(i=0;i<4;i++)
    	{
    		for(j=0;j<4;j++)
    		{
    			if(KeySta[i][j] != KeyBack[i][j])	//按键状态改变
    			{
    				if(KeySta[i][j] != 0)		//按键松开
    				{
    				 	KeyAction();//按下之后,写入相应语句执行按键操作
    				}
    				KeyBack[i][j] = KeySta[i][j];		//将变化后的按键值储存
    			}
    		}
    	}	
    }
    
    uchar KeyScan()
    {
    	uchar i=0;
    	static uchar KeyOut = 0;
    	static uchar KeyBuff[4][4] = {{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff}};
    
    	switch(KeyOut)
    	{
    		case 0:Key_Out_1=0; Key_Out_4=1; break;
    		case 1:Key_Out_2=0; Key_Out_1=1; break;
    		case 2:Key_Out_3=0; Key_Out_2=1; break;
    		case 3:Key_Out_4=0; Key_Out_3=1; break;
    	}
    	
    	KeyBuff[KeyOut][0] = KeyBuff[KeyOut][0]<<1 | Key_In_1;
    	KeyBuff[KeyOut][1] = KeyBuff[KeyOut][1]<<1 | Key_In_2;
    	KeyBuff[KeyOut][2] = KeyBuff[KeyOut][2]<<1 | Key_In_3;
    	KeyBuff[KeyOut][3] = KeyBuff[KeyOut][3]<<1 | Key_In_4;
    
    	for(i=0;i<4;i++)		//消抖
    	{
    		if((KeyBuff[KeyOut][i]&0x0f) == 0x00)
    		{
    			KeySta[KeyOut][i] = 0;
    		}	
    		else if((KeyBuff[KeyOut][i]&0x0f) == 0x0f)
    		{
    			KeySta[KeyOut][i] = 1;
    		}
    	}
    	KeyOut ++;  		//检测下一行
    	KeyOut &= 0X03;		//若超过3,则与0x03相与又变回0x00了
    }
    
    

    函数的使用应该在中断函数中进行每1ms一次,4ms消抖

    void Timer0() interrupt 1
    {
    	KeyScan();
    }
    
    void main()
    {
    	while(1)
    	{
    		KeyDrive();
    	}
    }
    

    通过阅读别人的博客,学习到:
    ①KeyScan() 放在中断中作扫描作用,运用移位操作、静态变量、循环,判断按下的键值;
    ②KeyDriver() 放在主函数里,判断按键的按下、松开、按住。

    其实一开始从别处看到上面第二种写法,理解了很久才懂。
    以前用过的另一种方法似乎比这个好理解,但是我忘记写法了【没办法,每次学到一半都放弃了】

    有问题欢迎大家提出,共同交流学习!

    展开全文
  • 思路是在main函数中通过死循环来扫描端口电平状态检测,以此判断按键是否按下。实现较为简单。 1.初始化(注意C语言中变量声明需放在函数开头) 以下是初始化PB5端口(LED灯)代码,每一条语句的含义在我另一篇...

    (涉及专有名词较多,难免解释不到位,若有错误还请指出,谢谢!)

    硬件连接图如下:

    一、扫描

    思路是在main函数中通过死循环来扫描端口电平状态检测,以此判断按键是否按下。实现较为简单。

    1.初始化(注意C语言中变量声明需放在函数开头)

    以下是初始化PB5端口(LED灯)的代码,每一条语句的含义在我另一篇博客里

    GPIO_InitTypeDef GPIO_Init1;
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    
    GPIO_Init1.GPIO_Pin = GPIO_Pin_5;
    GPIO_Init1.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init1.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_SetBits(GPIOB, GPIO_Pin_5);                       //先熄灯
    
    GPIO_Init(GPIOB, &GPIO_Init1);
    

    以下是初始化PE3端口(按键)的代码

    GPIO_InitTypeDef GPIO_Init2;
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
    
    GPIO_Init2.GPIO_Pin = GPIO_Pin_3;           // 设置GPIO端口号为5
    GPIO_Init2.GPIO_Mode = GPIO_Mode_IPU;       // 设置端口模式为输入上拉
    // 设置为输入端口时不需要指定GPIO_Speed参数
    
    GPIO_Init(GPIOE, &GPIO_Init2);
    

    输入上拉与输入下拉的区别:
    输入上拉(GPIO_Mode_IPU):端口与VCC通过一个电阻串连,因此没有输入或输入高电平时端口为高电平,输入低电平时端口为低电平
    输入下拉(GPIO_Mode_IPD):端口与GND通过一个电阻串连,因此没有输入或输入低电平时端口为低电平,输入高电平时端口为高电平

    从硬件图上得知按键与GND相连,如果端口设置为输入上拉,那么松开按键时端口为高电平,按下按键时端口为低电平,可以区分两种状态
    如果端口设置为输入下拉,那么无论是按下还是松开按键时端口总为低电平,无法区分两种状态
    类似地,如果按键与VCC相连,则端口需要设置为输入下拉才能区分按下/松开两种状态

    2.扫描

    读取PE3端口的状态:

    GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)
    

    返回值为SET则端口为高电位,返回值为RESET则端口为低电位

    在main函数中放入以下死循环代码以实现扫描PE3端口并点灯的功能

    while (1)
    {
        if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)==SET) // 如果按键对应端口为高电平
    	{
    		GPIO_SetBits(GPIOB, GPIO_Pin_5);             // 熄灯(LED负极连接PB5,LED正极连接VCC,PB5高电平熄灯)
    	}
    	else                                             // 否则
    	{
    		GPIO_ResetBits(GPIOB, GPIO_Pin_5);           // 亮灯
    	}
    	delay_ms(10);                                    // 一些开发板例程当中提供了delay函数,需要通过delay_init()初始化后才可使用
                                                         // 若无现成delay函数,可通过一定次数的for循环来代替
    }
    

    3.例程

    代码如下:

    int main(void)
    {
        GPIO_InitTypeDef GPIO_Init1, GPIO_Init2;
    	delay_init();
    
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
        GPIO_Init1.GPIO_Pin = GPIO_Pin_5;
        GPIO_Init1.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_Init1.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_Init1);
        GPIO_SetBits(GPIOB, GPIO_Pin_5);                       //先熄灯
    
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
        GPIO_Init2.GPIO_Pin = GPIO_Pin_3;
        GPIO_Init2.GPIO_Mode = GPIO_Mode_IPU;
        GPIO_Init(GPIOE, &GPIO_Init2);
    	
    	delay_ms(200);
    
        while (1)
        {
            if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)==SET)
    		{
    			GPIO_SetBits(GPIOB, GPIO_Pin_5);
    		}
    		else
    		{
    			GPIO_ResetBits(GPIOB, GPIO_Pin_5);
    		}
    		delay_ms(10);
        }
    }
    

    二、中断

    0.相关概念

    中断:程序运行过程中,系统外部、系统内部或者现行程序本身若出现紧急事件,处理机立即中止现行程序的运行,自动转入相应的处理程序(中断服务程序),待处理完后,再返回原来的程序运行
    简而言之就是触发某一事件可以使得MCU跳转执行该事件的处理程序,而按键按下或放开(GPIO口电平改变)则可作为一个外部中断,通过编写这一事件的处理程序从而达到改变灯亮灭状态的目的
    (这里提到的“事件”并不是STM32当中的专有名词“事件”,而是泛指发生了某一件事)

    使用扫描方式获得按键输入的思路如下:

    主函数()
    {
        初始化()
        死循环
        {
            如果(按键按下)
            {……}
            否则
            {……}
        }
    }
    

    而使用中断获得按键输入的思路如下:

    主函数()
    {
        初始化()
        其它操作()
    }
    
    中断处理函数()
    {
        如果(按键按下)
        {……}
        否则
        {……}
    }
    

    对比可知使用扫描方式将使得芯片无法(难以)处理其它事务

    NVIC:全名为“内嵌向量中断控制器”,主要用来控制芯片中各个中断的优先级,在很多地方都会使用(串口通信、SPI通信、定时器、I?C通信等涉及到实时处理的功能都会与中断有关)

    EXTI(不是EXIT):全名为“外部中断/事件控制器”,可以实现输入信号的上升沿检测和下降沿的检测

    1.初始化(注意C语言中变量声明需放在函数开头)

    1.1 NVIC

    需要用到的初始化语句如下:

    NVIC_InitTypeDef NVIC_I;                           //定义初始化结构体
    
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);    //设置整个系统的中断优先级分组
    
    NVIC_I.NVIC_IRQChannel=EXTI3_IRQn;                 //设置初始化哪个中断
    NVIC_I.NVIC_IRQChannelPreemptionPriority=0x02;     //设置中断抢占优先级
    NVIC_I.NVIC_IRQChannelSubPriority=0x02;            //设置中断响应优先级(子优先级)
    NVIC_I.NVIC_IRQChannelCmd=ENABLE;                  //中断使能(启动)
    
    NVIC_Init(&NVIC_I);                                //初始化
    

    中断优先级分组、抢占优先级和子优先级的关系:
    STM32系列的芯片当中一般会有很多的中断,而当多个中断同时发生时就需要一个调度机制来控制它们的执行顺序,因此有了中断的优先级的概念。优先级遵循以下几点:
    1.优先级的数字越小优先级越高
    2.抢占优先级高的中断会先执行,它也可以打断抢占优先级低的中断
    3.当抢占优先级相同时,响应优先级高的中断会先执行,但它不可以打断响应优先级低的中断
    4.当两个中断的抢占优先级和响应优先级都相同时,先产生的中断先执行(按照时间顺序)

    举个例子,现在有三个中断:
    中断1:抢占优先级为2,响应优先级为1
    中断2:抢占优先级为3,响应优先级为0
    中断3:抢占优先级为2,响应优先级为0
    则3个中断的优先级顺序是中断3>中断1>中断2,同时中断1、3可以打断中断2,中断3不能打断中断1

    而两类优先级可以设置成哪些值呢?这取决于整个系统的中断优先级分组。通过

    NVIC_PriorityGroupConfig();
    

    可以设置整个系统的中断优先级分组,其参数可以是NVIC_PriorityGroup_0、NVIC_PriorityGroup_1、NVIC_PriorityGroup_2、NVIC_PriorityGroup_3、NVIC_PriorityGroup_4之一。具体关系如下:
    NVIC_PriorityGroup_0:0位抢占优先级(无效)+4位响应优先级(0~15)
    NVIC_PriorityGroup_1:1位抢占优先级(01)+3位响应优先级(07)
    NVIC_PriorityGroup_2:2位抢占优先级(03)+2位响应优先级(03)
    NVIC_PriorityGroup_3:3位抢占优先级(07)+1位响应优先级(01)
    NVIC_PriorityGroup_4:4位抢占优先级(0~15)+0位响应优先级(无效)

    例如中断分组设置为3,则所有中断的抢占优先级可以被设置为0~7,响应优先级可以被设置为0、1
    需要注意的是如果程序中用到了二次封装的一些库(比如开发板例程中厂商为初学者写的串口库等),则NVIC_PriorityGroupConfig()可能已经被调用过了,此时再次修改可能会带来其它问题

    1.2 EXTI

    需要用到的初始化语句如下:

    EXTI_InitTypeDef EXTI_I;                           //定义初始化结构体
    
    EXTI_I.EXTI_Line=EXTI_Line3;                       //设置初始化哪条中断/事件线
    EXTI_I.EXTI_Mode = EXTI_Mode_Interrupt;            //设置为产生中断(EXTI_Mode_Event为产生事件)
    EXTI_I.EXTI_Trigger = EXTI_Trigger_Falling;        //设置为下降沿触发
    EXTI_I.EXTI_LineCmd = ENABLE;                      //使能
    
    EXTI_Init(&EXTI_I);                                //初始化
    

    中断/事件的区别:
    中断产生后经由NVIC交给MCU进行处理(软件层面)
    事件最终作为一个脉冲信号直接触发其它硬件(硬件层面)
    附一张EXTI的框图便于理解,蓝色是中断,红色是事件

    EXTI、NVIC与GPIO的对应关系:
    如图所示

    上升/下降沿:
    低电平跳到高电平为上升沿,高电平跳到低电平为下降沿

    1.3 GPIO

    与扫描方式的初始化代码相同

    GPIO_InitTypeDef GPIO_Init1, GPIO_Init2;
    
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    GPIO_Init1.GPIO_Pin = GPIO_Pin_5;
    GPIO_Init1.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init1.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_Init1);
    GPIO_SetBits(GPIOB, GPIO_Pin_5);                       //先熄灯
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
    GPIO_Init2.GPIO_Pin = GPIO_Pin_3;
    GPIO_Init2.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOE, &GPIO_Init2);
    
    1.4 其它

    目前不明确这两条语句的作用

    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);          //开启端口复用,涉及到GPIO口做外部中断时都需要这一条语句
    

    2.中断处理函数

    函数名与中断/事件线有着对应关系,可参照上一张表

    void EXTI3_IRQHandler(void)
    {
    	if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)==SET)
        {
            GPIO_SetBits(GPIOB, GPIO_Pin_5);
        }
        else
        {
            GPIO_ResetBits(GPIOB, GPIO_Pin_5);
        }
    	EXTI_ClearITPendingBit(EXTI_Line3);
    }
    

    最后的EXTI_ClearITPendingBit()用于清除中断标志位,避免对之后的中断造成影响

    3.例程

    代码如下:

    int main(void)
    {
        GPIO_InitTypeDef GPIO_Init1, GPIO_Init2;
        NVIC_InitTypeDef NVIC_I;
        EXTI_InitTypeDef EXTI_I;
    
    	GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
    	
        NVIC_I.NVIC_IRQChannel=EXTI3_IRQn;
        NVIC_I.NVIC_IRQChannelPreemptionPriority=0x02;
        NVIC_I.NVIC_IRQChannelSubPriority=0x02;
        NVIC_I.NVIC_IRQChannelCmd=ENABLE;
        NVIC_Init(&NVIC_I);
    
        EXTI_I.EXTI_Line=EXTI_Line3;
        EXTI_I.EXTI_Mode = EXTI_Mode_Interrupt;
        EXTI_I.EXTI_Trigger = EXTI_Trigger_Falling;
        EXTI_I.EXTI_LineCmd = ENABLE;
        EXTI_Init(&EXTI_I);
    
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
        GPIO_Init1.GPIO_Pin = GPIO_Pin_5;
        GPIO_Init1.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_Init1.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_Init1);
        GPIO_SetBits(GPIOB, GPIO_Pin_5);                       //先熄灯
    
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
        GPIO_Init2.GPIO_Pin = GPIO_Pin_3;
        GPIO_Init2.GPIO_Mode = GPIO_Mode_IPU;
        GPIO_Init(GPIOE, &GPIO_Init2);
    
    }
    
    void EXTI3_IRQHandler(void)
    {
    	if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)==SET)
        {
            GPIO_SetBits(GPIOB, GPIO_Pin_5);
        }
        else
        {
            GPIO_ResetBits(GPIOB, GPIO_Pin_5);
        }
    	EXTI_ClearITPendingBit(EXTI_Line3);
    }
    

    2019.12.22

    展开全文
  • 下面通过一个示例演示如何通过函数cv2.witkey实现交互功能。【例1.3】在一个窗口内显示图像,并针对按下的不同按键做出不同的反应。...例如,通过语句“返回值-97”就可以判断是否按下了字母a键。 Py...

    下面通过一个示例演示如何通过函数cv2.witkey实现交互功能。

    例1.3】在一个窗口内显示图像,并针对按下的不同按键做出不同的反应。

     函数cv2.waitkey()能够获取按键的ASCⅡ码。例如,如果该函数的返回值为97,表示按下了键盘上的字母a键。通过将返回值与ASCⅡ码值进行比较,就可以确定是否按下了某个特定的键。例如,通过语句“返回值-97”就可以判断是否按下了字母a键。 Python提供了函数ord(),用来获取字符的ASCII码值。因此,在判断是否按下了某个特定的按键时,可以先使用ord()函数获取该特定字符的ASCI码值,再将该值与cv2.waitkey() 函数的返回值进行比较,从而确定是否按下了某个特定的键。这样,在程序设计中就不需要ASCⅡ值的直接参与了,从而避免了使用ASCII进行比较可能带来的不便。例如,要判断是否 按下了字母A键,可以直接使用“返回值ord('A')”语句来完成。

    根据题目要求及以上分析,编写代码如下:

    import cv2
    lena=cv2.imread("lena.bmp")
    cv2.imshow("demo", lena)
    key=cv2.waitkey ()
    if key==ord('A'):
    cv2.imshow("PressA",lena)
    elif key==ord('B'):
    cv2.imshow("PressB",lena)

    运行上述程序,按下键盘上的A键或者B键,会在一个新的窗口内显示图像lena.bmp, 它们的不同之处在于:

    • 如果按下的是键盘上的A键,则新出现的窗口名称为 Pressa,如图1-4的左图所示。
    • 如果按下的是键盘上的B键,则新出现的窗口名称为 Press,如图1-4的右图所示。
    83f171e05def2a26794307ef963a1816.png
    图1-4【例1.3】程序的运行结果

     从另外一个角度理解,该函数还能够让程序实现暂停功能。当程序运行到该语句时,会按 照参数 delay的设定等待特定时长。根据该值的不同,可能有不同的情况:

    • 如果参数 delay的值为0,则程序会一直等待。直到有按下键盘按键的事件发生时,オ会执行后续程序。

    • 如果参数 delay的值为一个正数,则在这段时间内,程序等待按下键盘按键。当有按下键盘按键的事件发生时,就继续执行后续程序语句;如果在 delay参数所指定的时间内 直没有这样的事件发生,则超过等待时间后,继续执行后续的程序语句。

    例1.4】在一个窗口内显示图像,用函数cv2. witkey实现程序暂停,在按下键盘的按键后让程序继续运行。

    根据题目要求,编写代码如下:

    import cv2
    lena=cv2.imread("lena.bmp")
    cv2.imshow("demo", lena)
    key=cv2.waitkey ()
    if key!=-1:
    print("触发了按键”)

     运行上述程序,首先会在一个名为demo的窗口内显示lena.bmp图像。在未按下键盘上的 按键时,程序没有新的状态出现;当按下键盘上的任意一个按键后,会在控制台打印“触发了按键”。

     在本例中,由于cv2. waitkeyoi函数的参数值是默认值0,所以在未按下键盘上的按键时,程序会一直处于暂停状态。当按下键盘上的任意一个按键时,程序中key=cv2.waitkey()下方的 语句便得以执行,程序输出“触发了按键”。

    1. destroy Window函数  函数cv2.destroyWindow()用来释放(销毁)指定窗口,其语法格式为:
    None= cv2 destroywindow( winname)

    其中, winname是窗口的名称.

     在实际使用中,该函数通常与函数cv2.waitkey()组合实现窗口的释放。【例1.5】编写一个程序,演示如何使用函数cv2. destroy Window释放窗口。

    根据题目要求,编写代码如下

    import cv2
    lena=cv2.imread("lena.bmp")
    cv2.imshow("demo", lena)
    cv2.waitkey()
    cv2 destroyWindow("demo")

     运行上述程序,首先会在一个名为demo的窗口内显示lena.bmp图像。在程序运行的过程 中,当未按下键盘上的按键时,程序没有新的状态出现;当按下键盘上的任意一个按键后,窗 口demo会被释放。

    1. destroyallwindows函数 函数cv2.destroyAllwindows()用来释放(销毁)所有窗口,其语法格式为:
    None =cv2.destroyallwindows()

    例1.6】编写一个程序,演示如何使用函数cv2.destroyAllwindows()释放所有窗口。

    根据题目要求,编写代码如下

    import cv2
    lena=cv2.imread("lena. bmp")
    cv2.imshow("demol", lena)
    cv2.imshow("demo2", lena)
    cv2.waitkey()
    cv2.destroyAllWindows()

     运行上述程序,会分别出现名称为 demol和demo2的窗口,在两个窗口中显示的都是lena.bmp图像。在未按下键盘上的按键时,程序没有新的状态出现:当按下键盘上的任意一个 按键后,两个窗口都会被释放。

    1.2.3 保存图像  OpenCV提供了函数cv2.imwrite(),用来保存图像,该函数的语法格式为:

    retval = cv2.imwrite( filename, img[ ,params])

    式中:

    • retval是返回值。如果保存成功,则返回逻辑值真(True);如果保存不成功,则返回逻辑值假( False).
    • filename是要保存的目标文件的完整路径名,包含文件扩展名。
    • img是被保存图像的名称。
    • params是保存类型参数,是可选的。【例1.7】编写一个程序,将读取的图像保存到当前目录下。根据题目要求,编写代码如下:
    import cv2
    lena=cv2.imread("lena.bmp")
    r=cv2.imwrite("result.bmp", lena)

    上述程序会先读取当前目录下的图像lena.bmp,生成它的一个副本图像,然后将该图像以名称 result.bmp存储到当前目录下。

    1.3 Opencv贡献库

    目前, Opencv库包含如下两部分。

    • Opencv主库:即通常安装的 Opencv库,该库是成熟稳定的,由核心的 Opencv团队 维护。
    • Opencv贡献库:该扩展库的名称为 opencv contrib,主要由社区开发和维护,其包含 的视觉应用比 Opencv主库更全面。需要注意的是, Opencv贡献库中包含非 Opencv 许可的部分,并且包含受专利保护的算法。因此,在使用该模块前需要特别注意。

    Opencv贡献库中包含了非常多的扩展模块,举例如下。

    • bioinspired:生物视觉模块。
    • datasets:数据集读取模块。
    • dnn:深度神经网络模块。
    • face:人脸识别模块。
    • matlab: MATLAB接口模块。
    • stereo:双目立体匹配模块。
    • text:视觉文本匹配模块。
    • tracking:基于视觉的目标跟踪模块。
    • Ximgpro:图像处理扩展模块。
    • xobjdetect:增强2D目标检测模块。
    • photo:计算摄影扩展模块。

    可以通过以下两种方式使用贡献库:

    • 下载 Opencv贡献库,使用 cmake手动编译。
    • 通过语句 pip install opencv-contrib- python直接安装编译好的 Opencv贡献库。网页htts/pypi.org/ project/opencv- contrib- python/上提供了该方案的常见问题列表FAQ( Frequently Asked Questions),而且该FAQ是不断更新的。
    704030565b41a2919906b0b4376641bc.giffab142a809dfbb34441374fa8d5845db.png

    joker-wt

    扫码|关注我们

    微信号|joker-wt123

    新浪微博|梧tw桐

    承蒙关照!!!

    我的心愿是——世界和平

    展开全文
  • 下面通过一个示例演示如何通过函数cv2.witkey实现交互功能。【例1.3】在一个窗口内显示图像,并针对按下的不同按键做出不同的反应。...例如,通过语句“返回值-97”就可以判断是否按下了字母a键。 Py...

    下面通过一个示例演示如何通过函数cv2.witkey实现交互功能。

    例1.3】在一个窗口内显示图像,并针对按下的不同按键做出不同的反应。

     函数cv2.waitkey()能够获取按键的ASCⅡ码。例如,如果该函数的返回值为97,表示按下了键盘上的字母a键。通过将返回值与ASCⅡ码值进行比较,就可以确定是否按下了某个特定的键。例如,通过语句“返回值-97”就可以判断是否按下了字母a键。 Python提供了函数ord(),用来获取字符的ASCII码值。因此,在判断是否按下了某个特定的按键时,可以先使用ord()函数获取该特定字符的ASCI码值,再将该值与cv2.waitkey() 函数的返回值进行比较,从而确定是否按下了某个特定的键。这样,在程序设计中就不需要ASCⅡ值的直接参与了,从而避免了使用ASCII进行比较可能带来的不便。例如,要判断是否 按下了字母A键,可以直接使用“返回值ord('A')”语句来完成。

    根据题目要求及以上分析,编写代码如下:

    import cv2
    lena=cv2.imread("lena.bmp")
    cv2.imshow("demo", lena)
    key=cv2.waitkey ()
    if key==ord('A'):
    cv2.imshow("PressA",lena)
    elif key==ord('B'):
    cv2.imshow("PressB",lena)

    运行上述程序,按下键盘上的A键或者B键,会在一个新的窗口内显示图像lena.bmp, 它们的不同之处在于:

    • 如果按下的是键盘上的A键,则新出现的窗口名称为 Pressa,如图1-4的左图所示。
    • 如果按下的是键盘上的B键,则新出现的窗口名称为 Press,如图1-4的右图所示。
    9fb6db9ddfbcef679c21931d93aa6302.png
    图1-4【例1.3】程序的运行结果

     从另外一个角度理解,该函数还能够让程序实现暂停功能。当程序运行到该语句时,会按 照参数 delay的设定等待特定时长。根据该值的不同,可能有不同的情况:

    • 如果参数 delay的值为0,则程序会一直等待。直到有按下键盘按键的事件发生时,オ会执行后续程序。

    • 如果参数 delay的值为一个正数,则在这段时间内,程序等待按下键盘按键。当有按下键盘按键的事件发生时,就继续执行后续程序语句;如果在 delay参数所指定的时间内 直没有这样的事件发生,则超过等待时间后,继续执行后续的程序语句。

    例1.4】在一个窗口内显示图像,用函数cv2. witkey实现程序暂停,在按下键盘的按键后让程序继续运行。

    根据题目要求,编写代码如下:

    import cv2
    lena=cv2.imread("lena.bmp")
    cv2.imshow("demo", lena)
    key=cv2.waitkey ()
    if key!=-1:
    print("触发了按键”)

     运行上述程序,首先会在一个名为demo的窗口内显示lena.bmp图像。在未按下键盘上的 按键时,程序没有新的状态出现;当按下键盘上的任意一个按键后,会在控制台打印“触发了按键”。

     在本例中,由于cv2. waitkeyoi函数的参数值是默认值0,所以在未按下键盘上的按键时,程序会一直处于暂停状态。当按下键盘上的任意一个按键时,程序中key=cv2.waitkey()下方的 语句便得以执行,程序输出“触发了按键”。

    1. destroy Window函数  函数cv2.destroyWindow()用来释放(销毁)指定窗口,其语法格式为:
    None= cv2 destroywindow( winname)

    其中, winname是窗口的名称.

     在实际使用中,该函数通常与函数cv2.waitkey()组合实现窗口的释放。【例1.5】编写一个程序,演示如何使用函数cv2. destroy Window释放窗口。

    根据题目要求,编写代码如下

    import cv2
    lena=cv2.imread("lena.bmp")
    cv2.imshow("demo", lena)
    cv2.waitkey()
    cv2 destroyWindow("demo")

     运行上述程序,首先会在一个名为demo的窗口内显示lena.bmp图像。在程序运行的过程 中,当未按下键盘上的按键时,程序没有新的状态出现;当按下键盘上的任意一个按键后,窗 口demo会被释放。

    1. destroyallwindows函数 函数cv2.destroyAllwindows()用来释放(销毁)所有窗口,其语法格式为:
    None =cv2.destroyallwindows()

    例1.6】编写一个程序,演示如何使用函数cv2.destroyAllwindows()释放所有窗口。

    根据题目要求,编写代码如下

    import cv2
    lena=cv2.imread("lena. bmp")
    cv2.imshow("demol", lena)
    cv2.imshow("demo2", lena)
    cv2.waitkey()
    cv2.destroyAllWindows()

     运行上述程序,会分别出现名称为 demol和demo2的窗口,在两个窗口中显示的都是lena.bmp图像。在未按下键盘上的按键时,程序没有新的状态出现:当按下键盘上的任意一个 按键后,两个窗口都会被释放。

    1.2.3 保存图像  OpenCV提供了函数cv2.imwrite(),用来保存图像,该函数的语法格式为:

    retval = cv2.imwrite( filename, img[ ,params])

    式中:

    • retval是返回值。如果保存成功,则返回逻辑值真(True);如果保存不成功,则返回逻辑值假( False).
    • filename是要保存的目标文件的完整路径名,包含文件扩展名。
    • img是被保存图像的名称。
    • params是保存类型参数,是可选的。【例1.7】编写一个程序,将读取的图像保存到当前目录下。根据题目要求,编写代码如下:
    import cv2
    lena=cv2.imread("lena.bmp")
    r=cv2.imwrite("result.bmp", lena)

    上述程序会先读取当前目录下的图像lena.bmp,生成它的一个副本图像,然后将该图像以名称 result.bmp存储到当前目录下。

    1.3 Opencv贡献库

    目前, Opencv库包含如下两部分。

    • Opencv主库:即通常安装的 Opencv库,该库是成熟稳定的,由核心的 Opencv团队 维护。
    • Opencv贡献库:该扩展库的名称为 opencv contrib,主要由社区开发和维护,其包含 的视觉应用比 Opencv主库更全面。需要注意的是, Opencv贡献库中包含非 Opencv 许可的部分,并且包含受专利保护的算法。因此,在使用该模块前需要特别注意。

    Opencv贡献库中包含了非常多的扩展模块,举例如下。

    • bioinspired:生物视觉模块。
    • datasets:数据集读取模块。
    • dnn:深度神经网络模块。
    • face:人脸识别模块。
    • matlab: MATLAB接口模块。
    • stereo:双目立体匹配模块。
    • text:视觉文本匹配模块。
    • tracking:基于视觉的目标跟踪模块。
    • Ximgpro:图像处理扩展模块。
    • xobjdetect:增强2D目标检测模块。
    • photo:计算摄影扩展模块。

    可以通过以下两种方式使用贡献库:

    • 下载 Opencv贡献库,使用 cmake手动编译。
    • 通过语句 pip install opencv-contrib- python直接安装编译好的 Opencv贡献库。网页htts/pypi.org/ project/opencv- contrib- python/上提供了该方案的常见问题列表FAQ( Frequently Asked Questions),而且该FAQ是不断更新的。
    3bd11e5325575f99e2fd15fa6628582e.gifd2ad9bc7224eb1946ca7c8118d311dc3.png

    joker-wt

    扫码|关注我们

    微信号|joker-wt123

    新浪微博|梧tw桐

    承蒙关照!!!

    我的心愿是——世界和平

    展开全文
  • 另一个我们学习是键盘对象kbd,它告诉我们指定键盘按钮是否按下。上节课我们实现了键盘向←键的判断,不知道你们是否实现了其他按键的操作。这是我们实现后代码。让我们先来看一看。这就是他如何工作
  • (EscASCII码为27,即判断是否按下esc键) if cv2.waitkey(30)==27 if cv2.waitkey(30)&0xff==27 疑惑 首先&运算即“and”运算。 其次0xFF是16进制数,对应二进制数为1111 1111。 然后cv2.waitkey...
  • (EscASCII码为27,即判断是否按下esc键) if cv2.waitkey(30)==27 if cv2.waitkey(30)&0xff==27 疑惑 首先&运算即“and”运算。 其次0xFF是16进制数,对应二进制数为1111 1111。 然后cv2.waitkey...
  • 断enterBtn 是否按下 { w.show(); //如果被按下,显示主窗口 return a.exec(); //程序一直执行,直到主窗口 关闭 } else return 0; //如果没被按下,则不会进入主窗口,整个程 序结束运行 } 主函数必须这么写,...
  • 2020-10-20

    2020-10-20 23:07:26
    坦克大战项目开发过程中,为了实现按住方向键坦克持续移动,原先采用打开重复按键设置pygame.key.set_repeat(50),在主程序添加这条语句虽然能够实现按住方向键持续移动,但坦克射击时按下射击键,则坦克移动...
  • 解答:因为这是用来跳出循环判断是否进入while语句,而且按下按键后 前面f 将会改变 而 e不会改变 消除抖动 ,延时函数 , while 和 if 都可以 , 最好用 if 不容易出错 矩阵键盘 高四位 指 键盘 列 , ...
  • //判断是否接收到应答信号 SCL=0; _Nop(); _Nop(); } /******************************************* * 设置DAC输出值 * DA转换 * ********************************************/ bit ...
  • //键盘扫描 判断是否按下,如果此时按下为2,判断是否又有按键按下,若没有,循环输//出三角波,若有,跳出while循环,跳出switch break; case 3: while(!(XBYTE[0xCFE9]&0x07)) fangbo(); break; ...
  • 咕咕咕~~~十分不好意思...打开程序后,编译,将程序烧到核心板内,打开串口调试程序,调好各参数后打开串口,将核心板的按键拨到NC端,按下复位键,则出现视频中现象。(本篇博客里没有放视频,放个视频太麻烦了=_...
  • (其中逆波兰表达式可以有各种表示形式,如数组、链表等,这里我们选用字符数组即字符流形式表示可以使得一般情况所占用存储空间最小。) 而转换逆波兰表达式又可以分为预转换及生成逆波兰表达式两个过程。预...
  • delphi 开发经验技巧宝典源码

    热门讨论 2010-08-12 16:47:23
    0162 判断字符串中某一字符是否大写 106 0163 判断字符串中是否有小写字母 107 0164 判断字符串中是否有指定字符 107 0165 判断字符是否可以转换成整数 108 0166 判断字符中是否有汉字 108 0167 判断...
  • 根据大嘴鱼嘴方向,判断是否到了鱼池边界(此处为难点)。 private boolean isTouched() 检测大嘴鱼是否吃到了小鱼。 内部类 private class RightListenerImpl extends AbstractAction 内部类 - 向右按键事件。...
  • c#编写计算器

    2013-04-10 10:58:32
    按键【负数】name值修改为btn_sign,按键【.】name修改为btn_dot,按键【+ - * /】name值分别修改为btn_add、btn_sub、btn_mul、btn_div,按键【=】name值修改为btn_equ,按键【倒数】name值修改为btn_rev...
  • 在接入网产品A测试中,在内存数据库正常的情况下的各种数据库方面的操作都是正常的。为了进行数据库异常测试,于是将数据库内容人为地破坏了。发现在对数据库进行比较操作时,出现程序跑死了现象。 经过跟踪调试...
  • asp.net知识库

    2015-06-18 08:45:45
    .Net框架下的XSLT转换技术简介 一个XSLT的简单例子 XSLXSLT板主题整理 xsl入门的好文章 新手学习XSL的好东西 XSL语法介绍 XSL学习心得 - 调用属性值 XSLT与XML转换的详细介绍 功能应用 读写搜索 基础教程 RSS Web2.0...
  • 实例026 实现按下esc键关闭窗体 实例027 屏蔽系统ctrl+c/x/v组合键 实例028 避免按回车键产生“嘀”声 实例029 设置/屏蔽系统热键 2.3 键盘操作在实际中应用 实例030 打开和关闭输入法编辑器 实例031 使用键盘...
  • 在对话框中为什么不响应按下向下箭头键(VK_DOWN)和向右箭头键(VK_RIGHT)消息 Visualc C++ 6.0可以编写哪几种dll Visualc C++ 6.0如何编写Non-MFC Dlls Visualc C++ 6.0如何编写Regular Dlls Visualc C++ 6.0...
  • 想把13-1和13-2代码进行结合,实现按键切换,但是这样写代码又过于冗长,能否通过一个键盘的按下事件来直接调整star_random值呢?(之前在check_event中试了if语句来进行条件判断,但是似乎无法有效在同时改变...
  • Visual C++编程技巧精选500例.pdf

    热门讨论 2012-09-01 15:01:50
    116 如何判断程序窗口是否为切分窗口? 117 如何创建非矩形窗口? 118 如何实现无标题窗口拖动? 119 如何将应用程序窗口居中显示? 049 如何禁止标题栏最小化按钮?… 050 如何禁止标题栏最大化按钮? 051 如何禁止...
  • Java范例开发大全 (源程序)

    热门讨论 2011-04-27 07:47:22
     实例14 判断输入年份是否为闰年 26  实例15 抽奖活动 27  3.2 for语句 28  实例16 小九九乘法表 28  实例17 如何列出素数 29  实例18 Java中递归 31  实例19 男生女生各多少人 32  实例20 求...
  • Delphi开发B.S数据库应用系统教程

    热门讨论 2014-05-31 12:55:11
    八、DBGrid 中回车移动到一字段 (137) 九、Edit 框中只允许输入数字或小数点 (137) 十、去除 FastReport 打印报表注册标记 (137) 十一、调用外部文件 (137) 十二、判断光驱盘符(方法一# (138) ...
  • java范例开发大全源代码

    热门讨论 2011-10-30 23:31:51
     实例14 判断输入年份是否为闰年 26  实例15 抽奖活动 27  3.2 for语句 28  实例16 小九九乘法表 28  实例17 如何列出素数 29  实例18 Java中递归 31  实例19 男生女生各多少人 32  实例...
  • java范例开发大全

    2013-03-08 20:06:54
    实例14 判断输入年份是否为闰年 26 实例15 抽奖活动 27 3.2 for语句 28 实例16 小九九乘法表 28 实例17 如何列出素数 29 实例18 Java中递归 31 实例19 男生女生各多少人 32 实例20 求水仙花数 34 实例21 求任意...
  • 手机 pdf 阅读器

    2009-02-12 23:00:29
    阅读时,具有“返回键”手机按下“返回键”,可以直接打开跳到下一本书窗口上。 [2007.9.29] Ver:3.1.19 完善了对UMD支持,阅读文本格式UMD功能正常 增加了俄语支持 [2007.9.24] Ver:3.1.18 多数人还是...
  • 实现了长按超过500毫秒重复执行按下的键的功能。例如长按退格键,不断删除。 shift键切换输入法,esc键隐藏输入法,空格选中第一个汉字,回车选中输入的拼音。和搜狗输入法处理一致。 英文、中文、数字字母、大小写...

空空如也

空空如也

1 2 3
收藏数 46
精华内容 18
关键字:

判断按键是否按下的语句