记录学习日志4

第四周的学习日志
现阶段所作笔记不一定都正确,仅供参考作用。
我使用的是开源库opencv-python
跟着教师学习了关于图像的一些操作,尝试通过控制键盘实现图片的移动。

  • License

license是一种协议许可,是类似于决定我能用它进行开发的许可,还是我卖产品的许可。也就是说是我在一台电脑上用它进行开发是一个license还是我发布我程序的一个copy算一个license。
一个license就是一个许可,多了就会产生侵权问题。

譬如某甲公司卖给你一个产品,按lincense收费。
你本人买了100个license,也就是说这款软件做多安装在100个人电脑里,多了便会造成侵权问题

也有常见的开源license。
Apache License
是著名的非盈利开源组织Apache采用的协议。该协议和BSD类似,同样鼓励代码共享和尊重原作者的著作权,同样允许代码修改,再发布(作为开源或商业软件)。需要满足的条件也和BSD类似:

(1)、需要给代码的用户一份Apache License。

(2)、如果你修改了代码,需要在被修改的文件中说明。

(3)、在延伸的代码中(修改和有源代码衍生的代码中)需要带有原来代码中的协议,商标,专利声明和其他原来作者规定需要包含的说明。

(4)、如果再发布的产品中包含一个Notice文件,则在Notice文件中需要带有Apache License。你可以在Notice中增加自己的许可,但不可以表现为对Apache License构成更改。

(5)、Apache License也是对商业应用友好的许可。使用者也可以在需要的时候修改代码来满足需要并作为开源或商业产品发布/销售。
MPL (Mozilla Public License)
1998年初,Netscape的Mozilla小组为其开源软件项目设计的软件许可证。MPL许可证出现的最重要原因就是,Netscape公司认为GPL许可证没有很好地平衡开发者对源代码的需求和他们利用源代码获得的利益。同著名的GPL许可证和BSD许可证相比,MPL在许多权利与义务的约定方面与它们相同(因为都是符合OSIA 认定的开源软件许可证)。但是,相比而言MPL还有以下几个显著的不同之处:

(1)、MPL虽然要求对于经MPL许可证发布的源代码的修改也要以MPL许可证的方式再许可出来,以保证其他人可以在MPL的条款下共享源代码。但是,在MPL 许可证中对”发布”的定义是”以源代码方式发布的文件”,这就意味着MPL允许一个企业在自己已有的源代码库上加一个接口,除了接口程序的源代码以MPL许可证的形式对外许可外,源代码库中的源代码就可以不用MPL许可证的方式强制对外许可。这些,就为借鉴别人的源代码用做自己商业软件开发的行为留了一个豁口。

(2)、MPL许可证第三条第7款中允许被许可人将经过MPL许可证获得的源代码同自己其他类型的代码混合得到自己的软件程序。

扫描二维码关注公众号,回复: 11589701 查看本文章

(3)、对软件专利的态度,MPL许可证不像GPL许可证那样明确表示反对软件专利,但是却明确要求源代码的提供者不能提供已经受专利保护的源代码(除非他本人是专利权人,并书面向公众免费许可这些源代码),也不能在将这些源代码以开放源代码许可证形式许可后再去申请与这些源代码有关的专利。

(4)、对源代码的定义而在MPL(1.1版本)许可证中,对源代码的定义是:”源代码指的是对作品进行修改最优先择取的形式,它包括:所有模块的所有源程序,加上有关的接口的定义,加上控制可执行作品的安装和编译的’原本’(原文为’Script’),或者不是与初始源代码显著不同的源代码就是被源代码贡献者选择的从公共领域可以得到的程序代码。”

(5)、MPL许可证第3条有专门的一款是关于对源代码修改进行描述的规定,就是要求所有再发布者都得有一个专门的文件就对源代码程序修改的时间和修改的方式有描述。
该处引用了**CSDN博主「fengbingchun」**的原创文章这里所做的开源项目的license较为完善。
https://blog.csdn.net/fengbingchun/article/details/55106926
在这里插入图片描述

  • opencv-python库的安装

可以使用这个命令进行下载 这是清华的开源库

pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple

opencv库非常强大,算目前世界上最强大的计算机视觉库可以做人脸识别以及目标检测以及各类图像特征处理 。
安装好后就调用看看

import cv2

img1 = cv2.imread('d:\\lib2.png') 
img1 = cv2.resize(img1,(200,200))
cv2.imshow('nut.edu.cn RPG',img1)

cv2.waitKey(0)
cv2.destroyAllWindows()

注意这里文件路径使用的是双斜杠,如果这里文件路径输入错误会报错误。

cv2.error: OpenCV(4.2.0) C:\projects\opencv-python\opencv…

我这里第一次使用时也报错了,不过将文件路径改正就好了。
输出结果
在这里插入图片描述
这里的cv2.resize方法是用来修改图片大小的。

  • resize()方法

opencv的函数原型

 cv2.resize(InputArray src, OutputArray dst, Size, fx, fy, interpolation)
参数 意义
InputArray src 输入图片
OutputArray dst 输出图片
Size 输出图片尺寸
fx, fy 沿x轴,y轴的缩放系数
interpolation 插入方式
interpolation值 意义
INTER_NEAREST 最近邻插值
INTER_LINEAR 双线性插值(默认设置)
INTER_AREA 使用像素区域关系进行重采样。
INTER_CUBIC 4x4像素邻域的双三次插值
INTER_LANCZOS4 8x8像素邻域的Lanczos插值

这里借鉴了CSDN博主「li_il」的原创文章,他这个方面写的较为全面。附上原文链接:https://blog.csdn.net/li_l_il/article/details/83218838
大家想要深入了解的话可以进入链接查看。

- waitKey(dalay)

cv2.waitKey(delay)

cv.waitKey(delay)函数的功能是不断刷新图像,频率时间为delay,单位为ms
1、waitKey()–是在一个给定的时间内(单位ms)等待用户按键触发; 如果用户没有按下键,则接续等待(循环),在opencv应用中常见:设置waitKey(0),则表示程序会无限制的等待用户的按键事件一般在imgshow的时候,如果设置waitKey(0),则表示无限期的等待键盘输入,代表按任意键继续。

2、显示视频时,延迟时间需要设置为 大于0的参数delay>0时,延迟”delay”ms,在显示视频时这个函数是有用的,用于设置在显示完一帧图像后程序等待”delay”ms再显示下一帧视频; 如果使用waitKey(0)则只会显示第一帧视频。
3、如下程序:
if cv2.waitKey(100) == 27:
break
等待用户触发事件,等待时间为100ms,如果在这个时间段内, 用户按下ESC(ASCII码为27),执行if体如果没有按,if函数不做处理。
————————————————
这里也引用了CSDN博主「古月金真」的原创文章,解释都比较到位。
原文链接:https://blog.csdn.net/weixin_44572622/article/details/97494468

  • destroyAllWindows()
cv2.destroyAllWindows() 

cv2.destroyAllWindows() 用来删除窗口的,()里不指定任何参数,则删除所有窗口,删除特定的窗口,往()输入特定的窗口值。
cv2.destroyAllWindow()销毁所有窗口
cv2.destroyWindow(wname)销毁指定窗口

  • imread(filepath,flags)
cv2.imread(filepath,flags)

filepath:要读入图片的完整路径
flags:读入图片的标志
    cv2.IMREAD_COLOR:默认参数,读入一副彩色图片,忽略alpha通道
    cv2.IMREAD_GRAYSCALE:读入灰度图片
    cv2.IMREAD_UNCHANGED:顾名思义,读入完整图片,包括alpha通道

  • imshow(wname,img)
cv2.imshow(wname,img)

imshow(wname,img)显示图像,第一个参数是显示图像的窗口的名字,第二个参数是要显示的图像(imread读入的图像),窗口大小自动调整为图片大小

接着创建一个函数用来输入两张图片以及传入x,y坐标。

def image_on_image(img1, img2, x=100, y=100):
    rows, cols, channels = img2.shape

    img1[0 + y:rows + y, 0 + x:cols + x] = img2

    cv2.imshow('res', img1)
    return img1
rows, cols, channels = img2.shape

这一句是用来获取图像2的shape信息,存入rows,cols,channels中。
代表图像像素有多少列,多少行,多少通道数。
在RGB图像中一般一个像素点含有三个通道数,三个值相加便是所得颜色,故又称加色模式。
RGB色彩模式
 RGB色彩模式使用RGB模型为图像中每一个像素的RGB分量分配一个0~255范围内的强度值。例如:纯红色R值为255,G值为0,B值为0;灰色的R、G、B三个值相等(除了0和255);白色的R、G、B都为255;黑色的R、G、B都为0。RGB图像只使用三种颜色,就可以使它们按照不同的比例混合,在屏幕上重现16581375种颜色。
CMYK色彩模式
C. 青色(Cyan) M. 洋红色(Magenta) Y. 黄色(Yellow) K. 黑色(blacK)
CMYK模型针对印刷媒介,即基于油墨的光吸收/反射特性,眼睛看到颜色实际上是物体吸收白光中特定频率的光而反射其余的光的颜色。
每种 CMYK 四色油墨可使用从 0 至 100% 的值。
色彩相减便可以得到所得颜色,故又称减色模式。与RGB色彩互补。

LAB 颜色空间
LAB 颜色空间由一个亮度通道和两个颜色通道组成的. 在LAB 颜色空间中,每个颜色用L、A、B三个数字表示,其中,各个分量的含义是:
– L – 亮度

– A – 从绿色到红色的分量

– B – 从蓝色到黄色的分量
L 越大,亮度越高。L 为 0 时代表黑色,为100时代表白色。
A 和 B 为0时都代表灰色。
A 从负数变到正数,对应颜色从绿色变到红色。
B 从负数变到正数,对应颜色从蓝色变到黄色。
在实际应用中常常将颜色通道的范围[-100, +100]或[-128, 127]之间。
HSI 颜色空间
色调(Hue)、饱和度(Saturation, Chroma)和亮度(Intensity, Brightness)
色相 H(Hue) - 表示颜色的相位角. 红、绿、蓝分别相隔 120 度;互补色分别相差 180 度,即颜色的类别.

饱和度 S(Saturation) - 色彩的强度或纯度. 表示成所选颜色的纯度和该颜色最大的纯度之间的比率,范围:[0, 1],即颜色的深浅程度.

亮度 I(Intensity) - 表示颜色的明亮程度,通常以 0% (黑色) 到 100% (白色) 的百分比来衡量(人眼对亮度很敏感)

import cv2  # 导入 opencv -python 库 


img1 = cv2.imread('d:\\lib.jpg') 
img2 = cv2.imread('d:\\lib2.png')
img2 = cv2.resize(img2,(100,100))


def image_on_image(img1,img2,x=100,y=100):
    
    rows,cols,channels = img2.shape
    roi = img1[0:rows, 0:cols ]

roi = img1[0:rows, 0:cols ] 把背景图片img1 的左上角 按图像2的形状赋值给 roi。

cv2.cvtColor(img2, cv2.Color_Style)
  • cvtColor(img,Color_Style)

cv2.cvtColor(img,p2) 是颜色空间转换函数,img是需要转换的图片,Color_Style是转换成何种格式。
cv2.COLOR_BGR2RGB 将BGR格式转换成RGB格式
cv2.COLOR_BGR2GRAY 将BGR格式转换成灰度图片…

import cv2  # 导入 opencv -python 库

img1 = cv2.imread('E:\\Ink_painting.png')

img1 = cv2.resize(img1, (400, 400))
img1gray = cv2.cvtColor(img1, cv2.COLOR_BGR2HSV)
cv2.imshow('res', img1gray)
cv2.waitKey(0)
cv2.destroyAllWindows()

原图和转换为HSV色彩模式的图片对比
在这里插入图片描述在这里插入图片描述

  • threshold()函数
cv2.threshold(src, thresh, maxval, type[, dst]) 

src:表示的是图片源
thresh:表示的是阈值(起始值)
maxval:表示的是最大值
type:表示的是这里划分的时候使用的是什么类型的算法,常用值为0(cv2.THRESH_BINARY)一般的(BINARY)效果是:
将一个灰色的图片,变成要么是白色要么就是黑色。
在这里插入图片描述
这里(x,y)表示的是图像中的坐标,INV 表示的是取反。

import cv2  # 导入 opencv -python 库

img1 = cv2.imread('E:\\Ink_painting.png')

img1 = cv2.resize(img1, (400, 400))
ret, thresh = cv2.threshold(img1, 200, 255, 0)
cv2.imshow('res', thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述
图像基本运算
图像的基本运算有很多种,比如两幅图像可以相加、相减、相乘、相除、位运算、平方根、对数、绝对值等;图像也可以放大、缩小、旋转,还可以截取其中的一部分作为ROI(感兴趣区域)进行操作,各个颜色通道还可以分别提取及对各个颜色通道进行各种运算操作。

cv2.bitwise_not(mask)
cv2.bitwise_and(roi, roi, mask=mask)
...

bitwise_and是对二进制数据进行“与”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“与”操作,1&1=1,1&0=0,0&1=0,0&0=0
bitwise_or是对二进制数据进行“或”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“或”操作,1|1=1,1|0=0,0|1=0,0|0=0
bitwise_xor是对二进制数据进行“异或”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“异或”操作,11=0,10=1,01=1,00=0
bitwise_not是对二进制数据进行“非”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“非”操作,1=0,0=1

掩膜(mask)
有些图像处理的函数中有的参数里面会有mask参数,即此函数支持掩膜操作。
在所有图像基本运算的操作函数中,凡是带有掩膜(mask)的处理函数,其掩膜都参与运算(输入图像运算完之后再与掩膜图像或矩阵运算)。
此处详情可移步到CSDN博主「小伟锅」的文章,介绍都较为全面。
原文链接:https://blog.csdn.net/u011028345/article/details/77278467

回到这个代码中

def image_on_image(img1,img2,x=100,y=100):
    
    rows,cols,channels = img2.shape

    img1[0+y:rows+y, 0+x:cols+x ] = img2
    #A:B   , C:D    就是从行和列去索引范围

    cv2.imshow('res',img1)
    return img1
rows,cols,channels = img2.shape

img1[0+y:rows+y, 0+x:cols+x ] = img2

这里相当于直接让主角的图像覆盖掉背景图片,省去了很多步骤。

   img1[0+y:rows+y, 0+x:cols+x ] = img2

这里A:B , C:D 就是 从行和列去索引范围

cur_flag = -1
pre_flag = -1

设置两个状态,一个作为当前状态,一个座位作为以前状态。

x,y=100,100
delta=15

再增加个坐标参数,以及等下要用到的人物一次走路的步伐。
接下来就是重点了

#无限循环
while True:
    #每一帧


    background=img1.copy() #背景图像值拷贝
    actor=img2.copy()#主角图像值拷贝

设置一个无限循环来更新每次图像位置的变化。
在将之前的img1图片,img2图片命名拷贝下来。

 #获取键盘事件
    flag = cv2.waitKey(0)
    #Esc,退出
    if flag == 27:
        break
    #判断是否按下其他键
    if flag > -1 and flag != pre_flag:
        cur_flag = flag
    pre_flag = flag

通过waitKey函数获取键盘事件
在ASCLL表中ESC为27, 所以这里按下ESC键便可以退出图片刷新程序了。
判断函数是否按下其他键,并将按键状态进行转换。

#响应 actor移动事件
    if cur_flag == ord('w'):
        y=y-delta

    elif cur_flag == ord('s'):
        y=y+delta
    elif cur_flag == ord('a'):
        x=x-delta
    elif cur_flag == ord('d'):
        x=x+delta
    else:
        1+1

ord()函数
ord() 函数是 对于ASCII字符串的配对函数,它以一个字符作为参数,返回对应的 ASCII 数值,
这个函数便是用来检测是否按下了wasd键,来实现图片位置的移动。

putText()函数

cv2.putText(src, text, place, Font, Font_Size, Font_Color, Font_Overstriking)

python-OpenCV之在图片上添加文字(cv.putText())
src:输入图像
text:需要添加的文字
place:左上角坐标
Font 字体类型
Font_Size:字体大小
Font_Color:文字颜色
Font_Overstriking:字体粗细

    elif cur_flag == ord('t'):
        text = "Your are so beautiful!"

        cv2.putText(img1, text, (200, 100), cv2.FONT_HERSHEY_COMPLEX, 1, (100, 200, 200), 2)

这里就可以实现简单的按t显示出一句话来。

也可以再调用一个pywin32包来实现语音说话
这是网上一个简单的语音案例。

import winsound
import win32com.client
import time

speak_out = win32com.client.Dispatch('SAPI.SPVOICE')

def speak(str):
    print(str)
    speak_out.Speak(str)
    winsound.PlaySound(str,winsound.SND_ASYNC)


speak("靓女通过调用一个pywin32包来实现语音说话")
speak("帅哥~")
speak("靓仔~")
time.sleep(1)

类似的可以加到刚创建的函数里面去

    elif cur_flag == ord('v'):
        speak("靓女通过调用一个pywin32包来实现语音说话")
        speak("帅哥~")
        speak("靓仔~")
        time.sleep(1)

实现按V听语音功能,当然肯定还有其他更多更好用的功能,还有待大家一起学习。(大佬当我不存在。)

消除png透明边框的办法目前还没有找到合适的方法,如果有大佬知道,请指导知道我,拜托了!!
整个程序现在简单的代码

"""
南昌理工学院人工智能学院 深度学习实验室workshop兴趣小组

Project:超级玛丽woroshop
第一季:南理文字RPG
时间:2020/5/9 19:22
Authors:超级玛丽workshop教研指导组
第一季目标:
1、完成Python主要的语法特性
2、能够掌握用Python进行实现自己想要的逻辑和设计
3、掌握一些基本的智能体的决策
4、掌握图形及人机基本交互

"""
import cv2  # 导入 opencv -python 库 
import winsound
import win32com.client
import time

speak_out = win32com.client.Dispatch('SAPI.SPVOICE')

def speak(str):
    print(str)
    speak_out.Speak(str)
    winsound.PlaySound(str,winsound.SND_ASYNC)




img1 = cv2.imread('E:\\Battle\\Ink_painting.png')
img2 = cv2.imread('E:\\Battle\\lib2.png')


img2 = cv2.resize(img2,(100,100))



def image_on_image(img1,img2,x=100,y=100):
    
    rows,cols,channels = img2.shape

    img1[0+y:rows+y, 0+x:cols+x ] = img2
    

    cv2.imshow('res',img1)
    return img1


#当前状态、之前状态
cur_flag = -1
pre_flag = -1

#无限循环

x,y=100,100
delta=15

while True:
    #每一帧


    background=img1.copy()
    actor=img2.copy()
    #获取键盘事件
    flag = cv2.waitKey(0)
    #Esc,退出
    if flag == 27:
        break
    #判断是否按下其他键
    if flag > -1 and flag != pre_flag:
        cur_flag = flag
    pre_flag = flag
    
    #响应 actor移动事件
    if cur_flag == ord('w'):
        y=y-delta

    elif cur_flag == ord('s'):
        y=y+delta
    elif cur_flag == ord('a'):
        x=x-delta
    elif cur_flag == ord('d'):
        x=x+delta
    elif cur_flag == ord('t'):
        text = "Your are so beautiful!"

        cv2.putText(img1, text, (200, 100), cv2.FONT_HERSHEY_COMPLEX, 1, (100, 200, 200), 2)
    elif cur_flag == ord('v'):
        speak("靓女通过调用一个pywin32包来实现语音说话")
        speak("帅哥~")
        speak("靓仔~")
        time.sleep(1)
    else:
        1+1
        
        
    #显示
    print('Actor(x,y)=('+str(x)+','+str(y)+')')
    background=image_on_image(background,actor,x,y)
    

cv2.destroyAllWindows()

哈哈哈哈哈哈哈哈哈哈哈哈,python好酷!

猜你喜欢

转载自blog.csdn.net/ye_sheng_/article/details/106041612