python版opencv笔记(无私奉献版)

最近,需要使用python写脚本来处理图像,幸亏最初学习的时候,做了详细的笔记。我现在只需复习笔记就可以很灵活的使用opencv。特此将我的笔记奉献出来,供需要的人参考。

https://www.bilibili.com/video/av69168847?p=1

*******************图片读取,展示********************

思路:

引入opencv模块

调用API实现图片读取和展示

调用API暂停程序

代码实现:

import cv2

img=cv2.imread('name',1)#图形读取API,参数1为图片文件全名,参数2为将图片按什么类型读进来(0为灰度,1位彩色),API返回一个表示图片的矩阵。完成文件的读取,文件封装格式解析(jpg,png),文件数据解码。

文件的封装(jpg,png等):

将文件按文件头和文件数据格式进行封装(不同格式,这两部分不同)

此处的文件数据,不是文件的原始数据,而是将图片压缩编码后的数据(按比例压缩图片,不同的压缩比对应得到不同大小的图片。缩小图片体积,方便存储和传输,我们一般常见的都是压缩后的文件,如.JPG等)

文件头描述的是文件数据部分的解码信息和附加信息

解码器根据文件头的信息将文件数据解码还原成文件原始数据

cv2.imshow('ima',img)#图片展示API,参数1为展示图片的窗口名称,参数2为要展示的图片的矩阵表示(这里的矩阵已经是对图片解码后的原图片数据)。完成数据加载

cv2.waitKey(0)#程序暂停API,只有暂停程序才能显示图片(此处参数为暂停的时间,0为0ms,1000为1000ms.时间用完后,程序会继续向下执行)

**************图片的写入**************************

思路:

引入opencv模块

调用API实现图片的读取功能

调用API实现图片的写入功能(其实就是另存为)

代码实现:

import cv2

img=cv2.imread('name',1)

cv2.imwrite('name2',img)#图片写入API,参数1为写入图片的名称(就是另存为的名称,这个名称是全名,要包含后缀名),参数2为图片的矩阵表示数据

********不同压缩比的图片写入*****************

思路:

引入opencv模块

调用API实现图片的读取功能

调用API实现按照指定压缩比写入图片(分为有损和无损)

代码实现:

import cv2

img=cv2.imread('name',1)

cv2.imwrite('name2',img,[cv2.IMWRITE_JPEG_QUALITY,0])#参数3为图片质量(也就是压缩比),参数3的图片质量范围为0~100,值越高,质量越高,0时大约缩小10倍,100时不缩小。一般压缩十几倍,图片质量和原图差别肉眼还是不容易看出来的。这个压缩是有损压缩(也就是以牺牲图片质量为代价来压缩图片)

jpg格式为有损压缩,并且无法设置图片的透明度

cv2.imwrite('name2',img,[cv2.IMWRITE_PNG_COMPRESSION,0])#png格式为无损压缩,可以设置图片的透明度(在修改RGB值进行压缩时,还可以修改蹄片的透明度,压缩比范围0~9,这里压缩比和jpg正好相反,值越小质量越高,0时代表无压缩

*************对图片的像素值进行读写***********************

知识补充:

图片时候一个个小放方块组成(每一个方块就是一个像素点)

像素点:在计算机中,每种颜色都可以用RGB三种颜色分量进行合成(比如黄色是由40%红色,40%绿色,20%的蓝色组成)

像素点如何在计算机中存储:对于每一个像素点来说,计算机存储的实际上是RGB三种颜色的值,对一个8位(8bit)颜色深度(这个颜色深度就是RGB每一个颜色分量都有二的八次方这么多个)的图片来说,RGB每一个颜色的分量范围为0~255。(对于一个8位颜色深度的RGB图像来说,一共有256的三次方种表示方式)

图片的宽高:比如宽*高为640*480的图像,表示的是水平方向上有640个像素点,竖直方向上有480个像素点

图像的大小:比如1.14M=像素点数*颜色分量数*颜色深度(bit)

每个像素点除了RGB三个颜色通道为,还可能有一个alpha通道(描绘的就是图片的透明度),如PNG图片

常见的颜色分量除了RGB外,还有一种是BGR(知识将RGB颜色通道顺序改变了)

每一个颜色分量成为一种颜色通道

图片在内存中存储的坐标系:横向为x轴代表列数(宽度),纵向为y轴代表行数(高度)。(x,y)

思路:

引入opencv模块

调用API实现图片的读取功能

利用矩阵原理读取给定坐标的像素值(以元组形式返回读取结果,元组内三个元素分别代表B蓝绿R红)

利用数据结构实现像素的写入(也是以元组形式写入像素值,元组内元素顺序为BGR)

调用API展示图片

调用API暂停程序

代码实现:

import cv2

img=cv2.imread('name',1)

(B,G,R)=img[100,100]#利用矩阵原理读取坐标为(100,100)的像素值(以元组形式返回读取结果,元组内三个元素分别代表B蓝绿R红)

for i in range(100):

img [10+i,100]=(255,0,0)#利用数据结构实现像素的写入(也是以元组形式写入像素值,元组内元素顺序为BGR),此处写入的是标准的蓝色B

cv2.imshow('ima',img)

cv2.waitKey(1000)#暂停1000ms,后程序继续向下执行


*********tensorflow基本数据类型******************

知识补充:

tensorflow相当于一门开发语言

因此学习tensorflow就要像学习一门开发语言一样,掌握它的基础语法,API调用

还要掌握图像,深度学习,机器学习等算法原理(这样才能自己用tensorflow实现这些原理)

开发语言有共性:

都有基础数据类型、运算符、流程控制语句

如果是面向对象的语言还会有 字典、数组、元组等等

tensorflow也具有上述开发语言的共性

tensorflow中的所有操作都必须要使用seession(会话)来执行

程序如果运行中出错,会打印出报错的日志(我们需要根据这个打印出的日志来排查问题,修改程序)

思路:

引入tensorflow模块

调用API定义常量

调用API定义变量

打印常量的表示

打印变量的表示

调用API定义一个seession(会话)

调用API在session中运行打印常量的操作

调用API在会话中一次性初始化所有变量(在TensorFlow中,所有变量必须在会话中进行初始化,否则会报错)

调用API关闭会话或使用with关键字自动关闭会话(从使用with开始代表创建了session会话,with sess:后的代码运行结束,走出with,代表自动关闭了会话)

代码实现:

import tensorflow as tf#引入tensorflow,并用tf来代表tensorflow

data1=tf.constant(2.5)#调用API定义常量(此处为浮点型类型),并以张量形式返回(张量可以理解为一种数据形式)

data2=tf.Variable(10,name='var')#调用API定义变量(参数1为初始化的变量值10,参数2 为变量的名字var),并以张量形式返回

print(data1)#并未打印出常量2.5,而是但引出一个描述它的张量tensor(参数1,参数2,参数3),参数1表示该数据为常数("Const:0"),参数2表示数据的维度(shape()),参数3代表该数据的数据类型(这里dtype=float32)

print(data2)#打印出出对数据的描述(参数1,参数2,参数3),参数1表示该数据为一个变量(tf.Variable 'var:0' ),参数2表示数据的维度(shape()),参数3代表该数据的数据类型(这里dtype=int32_ref)

sess=tf.Session()#调用API实例化一个Session()类

print(sess.run(data1))#调用API,在会话中打印常量(相当于对张量解析后返回解析结果)

data3=tf.constant(2,dtype=tf.int32)#调用API定义常量(此处为定点型类型),并以张量形式返回(张量可以理解为一种数据形式)

init=tf.global_variables_initializer()#调用API,实例化一个用来初始化变量的类(功能室对tensorflow代码中所有的变量初始化)

sess.run(init)#将初始化变量的类在会话中执行

print(sess.run(data2))#调用API在会话中打印变量(之后在初始化变量之后才能打印成功,否则会报错)

sess.close()#调用API关闭会话

init=tf.global_variables_initializer()

sess=tf.Session()

with sess:

sess.run(init)

print(sess.run(data2))


**********tensorflow代码运行原理*************************

知识补充

tensorlfow本质上由张量(tensor)和计算图(graphs)这两部分组成

变量和常量都是由张量这种数据结构来表示(tensor本质代表TensorFlow中的数据,数据可以是1维,也可以是n维)

op(操作):对tensor的操作(比如对tensor的赋值,tensor之间的四则运算),对tensord的操作必须在Seesion会话中进行

op和tensor共同构成了计算图

tensorflow的本质也可以理解为,在会话(session)中对张量(tensor)进行的一些列操作(op)。(换句话说,就是在会话中运行计算图)

session相当于一个tensorflow运行的环境

sess.tf.Session()

sess.run(data1)#这里把data1放进括号里,相当于把“data1=tf.constant(2.5)”这一系列都放进会话中执行。run后的括号的内容会被执行。没有放进括号中的不会被执行。

分析tensorflow代码,先分析定义了哪些tensor(数据),然后在分析session中的计算图(也就是对tensor的操作)有哪些。这样就可以很清晰的理解当前的tensorflow代码(本质就是对tensor的各种操作)

************tensorflow的数据运算-常量与常量**********************

思路:

引入tensorflow模块

调用API定义常量

调用API定义常量

调用API对常量进行+-*/四则运算(运算结果以tensor形式返回)

使用with 语句创建会话运行程序

结束代码

代码实现:

import tensorflow as tf

data1=tf.constant(6)

data2=tf.constant(2)

dataAdd=tf.add(data1,data2)#调用API实现两个常量相加,这里是data1+data2(运算结果以tensor形式返回)

dataMul=tf.multiply(data1,data2)#调用API实现对两个常量相乘,这里是data1*data2(运算结果以tensor形式返回)

dataSub=tf.subtract(data1,data2)#调用API实现对两个常量的减法,这里是data1-data2(运算结果以tensor形式返回)

dataDiv=tf.divide(data1,data2)#调用API实现对两个常量的除法,这里是data1/data2(运算结果以tensor形式返回)

with tf.Session() as sess:#使用with 语句简化会话创建

print(sess.run(dataAdd))

print(sess.run(dataMul))

print(sess.run(dataSub))

print(sess.run(dataDiv))

print('end!')#代表代码的结束

************tensorflow的数据运算-常量与变量**********************

思路:

引入tensorflow模块

调用API定义常量

调用API定义变量

调用API对常量进行+-*/四则运算(运算结果以tensor形式返回)

一次性初始化所有变量

使用with 语句创建会话运行程序

结束代码

代码实现:

import tensorflow as tf

data1=tf.constant(6)

data2=tf.Variable(2)

dataAdd=tf.add(data1,data2)#调用API实现两个常量相加,这里是data1+data2(运算结果以tensor形式返回)

dataMul=tf.multiply(data1,data2)#调用API实现对两个常量相乘,这里是data1*data2(运算结果以tensor形式返回)

dataSub=tf.subtract(data1,data2)#调用API实现对两个常量的减法,这里是data1-data2(运算结果以tensor形式返回)

dataDiv=tf.divide(data1,data2)#调用API实现对两个常量的除法,这里是data1/data2(运算结果以tensor形式返回)

init=tf.global_variables_initializer()

with tf.Session() as sess:#使用with 语句简化会话创建

sess.run(init)

print(sess.run(dataAdd))

print(sess.run(dataMul))

print(sess.run(dataSub))

print(sess.run(dataDiv))

print('end!')#代表代码的结束

************tensorflow的数据运算-数据拷贝*********************

知识补充:

tensorflow中程序在会话中运行的方式有两种:

一种是调用run方法:sess.run(程序)

一种是调用eval方法:程序.eval()

两种方法本质是一样的,eval方法其实是获取了一个默认会话的,并调用默认会话的run方法

程序.eval()=tf.get_default_session().run()程序

思路:

引入tensorflow模块

调用API定义常量

调用API定义变量

调用API对常量进行+-*/四则运算(运算结果以tensor形式返回)

调用API拷贝数据

一次性初始化所有变量

使用with 语句创建会话运行程序

结束代码

代码实现:

import tensorflow as tf

data1=tf.constant(6)

data2=tf.Variable(2)

dataAdd=tf.add(data1,data2)#调用API实现两个常量相加,这里是data1+data2(运算结果以tensor形式返回)

dataCopy=tf.assign(data2,dataAdd)#调用API完成数据拷贝(将参数2的数据拷贝到参数1,同时将参数1的值以tensor形式返回),这里是将dataAdd数据拷贝到data2(其实就是赋值)

dataMul=tf.multiply(data1,data2)#调用API实现对两个常量相乘,这里是data1*data2(运算结果以tensor形式返回)

dataSub=tf.subtract(data1,data2)#调用API实现对两个常量的减法,这里是data1-data2(运算结果以tensor形式返回)

dataDiv=tf.divide(data1,data2)#调用API实现对两个常量的除法,这里是data1/data2(运算结果以tensor形式返回)

init=tf.global_variables_initializer()

with tf.Session() as sess:#使用with 语句简化会话创建

sess.run(init)

print(sess.run(dataAdd))

print(sess.run(dataMul))

print(sess.run(dataSub))

print(sess.run(dataDiv))

print(sess.run(dataCopy))

print('dataCopy.eval()',dataCopy.eval())

print('tf.get_default_session.run(dataCopy)',tf.get_default_session().run(dataCopy))

print('end!')#代表代码的结束


*************tensorflow-placehold功能*******************

知识补充:

数据可以在初始化的时候定义好,后续运算的时候直接用

数据也可以在运算的过程中实时插入进去(使用placehold函数来实现这种操作)

思路:

引入tensorflow

调用API初始化数据

调用API实现对数据的加法

创建会话

在会话中运行计算图的同时,输入数据

输出结束

代码实现:

import tensorflow as tf

data1=tf.placeholder(tf.float32)#调用API初始化数据,这里并未对数据进行具体定义,只是定义了数据的类型为float32(就是括号里的参数)

data2=tf.placeholder(tf.float32)

dataAdd=tf.add(data1,data2)

with tf.Session() as sess:

print(sess.run(dataAdd,feed_dcit={data1:6,data2:2}))#调用API,在会话中运行计算图时,对数据进行赋值,这里用的是feed_dict={参数1:data,参数2:data}语法(这里也叫喂数据,因为feed中文意思是喂,dict是数据的缩写)

print('end')

*************tensorflow矩阵原理*****************

知识补充:

矩阵其实就是一个多维数组(m行n列的数组)

矩阵下标是从0开始的,3行2列的矩阵其实行从0~2(m的范围),和列0~1(n的范围)

矩阵最外面有[](这是矩阵的基础语法,这个[]是一定要有的)

矩阵的内部全部是由一个个的[列数据,列数据]组成(每一个[列数据]整体表示一行,里面的数据表示的是列数据)

按照矩阵语法定义一个1行2列的矩阵:

先把最外层中括号写上:[]

行数是一行,那么内部的中括号就只有一个:[[]]

列数是2,则内部的每一个[]里有两个数据:[[0,0]]

思路:

引入tensorflow

调用API定义矩阵

打印矩阵维度

创建会话

打印矩阵


代码实现:

import tensorflow as tf

data1=tf.constant([[6,6]])#调用API定义一个矩阵(这里是一行两列的矩阵)

data2=tf.constant([[2],[2]])#调用API定义一个矩阵(这里是两行一列的矩阵)

data3=tf.constant([[3,3]])

data4=tf.constant([[1,2],[3,4],[5,6]])#调用API定义一个矩阵(这里是三行两列的矩阵)

print(data4.shape)#使用矩阵的shape属性,打印矩阵的维度

with tf.Session() as sess:

print(sess.run(data4))#打印整个矩阵

print(sess.run(data4[0]))#以列表的心事打印行,这里是打印第0行(矩阵[n],这个语法是用来打印第n行,[]中只有一个元素,这个元素代表的就是第几行)

print(sess.run(data4[:,0]))#以列表的形式打印列,这里是打印第0列(矩阵[:,n],这个语法是用来打印第n列,[]中有两个元素,第一个元素代表行,这里没给出就是代表打印所有行,第二个元素代表列)

print(sess.run(data4[0,0]))#打印第0行,第0列的元素


*************tensorflow矩阵运算*****************

知识补充:

矩阵加法(1种),矩阵进行加法运算时,矩阵规模必须相同(就是行数和列数必须相同),矩阵加法其实就是对应元素相加。

矩阵乘法(2种),

第一种,矩阵乘法运算时,第一个矩阵的列必须和第二个矩阵的行数相同才可以进行乘法运算(第一个矩阵的行与第二个矩阵的列对应元素相乘,并将相乘的结果相加得到一个值作为乘法运算得到的矩阵的元素,第一个矩阵的行位置和第二个矩阵的列位置就是得到的这个元素的行标和列标)

第二种,就是矩阵对应元素相乘,最终结果的位数是两个矩阵最大维数的合成

一次性打印多个结果:

使用print(sess.run([参数1,参数2,参数3]))这种语法,一次性打印多个结果

思路:

引入tensorflow

调用API定义矩阵

调用API完成第一种矩阵乘法运算,结果以tensor形式返回

调用API完成第二种矩阵乘法运算,结果以tensor形式返回

调用API完成矩阵加法运算,结果以tensor形式返回

创建会话

运行计算图


代码实现:

import tensorflow as tf

data1=tf.constant([[6,6]])

data2=tf.constant([[2],[2]])

data3=tf.constant([[3,3]])

data4=tf.constant([[1,2],[3,4],[5,6]])

matMul=tf.matmul(data1,data2)#调用API完成第一种矩阵乘法运算,结果以tensor形式返回。此处乘法的结果为1行1列

matMul2=tf.multiply(data1,data2)#调用API完成第二种矩阵乘法运算,结果以tensor形式返回。此处乘法的结果为2行2列

matAdd=tf.add(data1,data3)#调用API完成矩阵加法运算,结果以tensor形式返回。此处加法的结果为1行2列

with tf.Session() as sess:

print(sess.run(matMul))

print(sess.run(matMul2))

print(sess.run(matAdd))

print(sess.run([matMul,matMul2,matAdd]))#使用print(sess.run([参数1,参数2,参数3]))这种语法,一次性打印多个结果


*************tensorflow特殊矩阵的初始化*****************

知识补充:

定一个空矩阵

可以按照普通定义矩阵方式进行定义

也可以调用tf.zeros([行数,列数])这个API进行定义

定义一个全1矩阵

可以按照普通定义矩阵方式进行定义

也可以调用tf.ones([行数,列数])这个API进行定义

定义一个全n矩阵(也叫填充矩阵)

可以按照普通定义矩阵方式进行定义

也可以调用tf.fill([行数,列数],n)API进行定义

拷贝现有矩阵规模,定义空矩阵:

可以按照普通定义矩阵方式进行定义

也可以调用tf.zeros_like(目标局阵)进行定义

将一个范围内的数据等分后作为矩阵元素:

可以按照普通定义来进行定义

也可以调用tf.linspace(起始值,终止值,等分数)API来进行定义

随机矩阵序列:

定一个给定规模的矩阵,并且这个矩阵的元素是在一个范围内的随机值

调用tf.random_uniform([行数,列数],其实值,终止值)API来定义



思路:

引入tensorflow

调用API定义矩阵

创建会话

打印矩阵


代码实现:

import tensorflow as tf

mat0=tf.constant([[0,0,0],[0,0,0]])

mat1=tf.zeros([2,3])#调用tf.zeros([行数,列数])API,生成全0矩阵

mat2=tf.ones([3,2])#调用tf.ones([行数,列数])API,生成全1矩阵

mat3=tf.fill([2,3],15)#调用tf.fill([行数,列数],n)API,生成全n矩阵,这里n=15

mat4=tf.zeros_like(mat3)#调用tf.zeros_like(目标局阵),定义一个和目标局阵规模相同的全0矩阵,这里目标局阵是mat3

mat5=tf.linspace(0.0,2.0,11)#调用tf.linspace(起始值,终止值,元素个数)API来进行定义,这里是将0~2范围内的数等分为10份(也就是最后矩阵有11个元素)

mat6=tf.random_uniform([2,3],-1,2)#调用tf.random_uniform([行数,列数],其实值,终止值)API来定义矩阵,这里是定义一个2行3列的矩阵,矩阵元素为-1~2之间的随机值

with tf.Session() as sess:

print(sess.run(mat0))

print(sess.run(mat1))

print(sess.run(mat2))

print(sess.run(mat3))

print(sess.run(mat4))

print(sess.run(mat5))

print(sess.run(mat6))

******************numpy****************

知识补充:

矩阵的基本操作和数据库类似(都是CRUD增删改查)

思路:

引入numpy模块

调用API定义一个矩阵

打印矩阵

打印矩阵维度

调用API,直接打印特殊矩阵

矩阵的修改和查询

实现矩阵和常数之间的基本运算

实现矩阵和矩阵之间的基本运算

代码实现:

import numpy as np

data1=np.array([1,2,3,4,5])#调用API,array()生成一个矩阵,并将矩阵以nDarry类型返回

data2=np.array([[1,2],[3,4]])#调用API,array()生成一个矩阵,并将矩阵以nDarry类型返回

print(data1)

print(data2)

print(data1.shape)#利用nDarry类型矩阵的shape属性,打印矩阵维度(以元组形式返回矩阵维度)

print(data2.shape)#利用nDarry类型矩阵的shape属性,打印矩阵维度(以元组形式返回矩阵维度)

print(np.zeros([2,3]),np.ones([2,2]))#调用API,直接打印特殊矩阵(这里打印了空矩阵和全1矩阵)

data2[1,0]=5#利用矩阵性质对矩阵元素进行修改,其实就是赋值(这里是将1行0列的位置元素赋值为5)

print(data2)

print(data2[1,1])#利用矩阵性质查询矩阵元素(这里是查询位于第1行第1列的矩阵元素)

data3=np.ones([2,3])

print(data3*2)#实现矩阵乘法(矩阵乘以一个常数)

print(data3/3)#实现矩阵除法(矩阵除以一个常数)

print(data3+2)#实现矩阵加法(矩阵加上一个常数)

data4=np.array([[1,2,3],[4,5,6]])

print(data3+data4)#实现两个矩阵相加(两个矩阵对应元素相加)

print(data3*data4)#相乘实现两个矩阵相加(两个矩阵对应元素相乘)


***********matplotlib模块******************

知识补充:

常用到的三大图表(折线,饼状,柱状)

思路:

引入numpy模块

引入matplotlib模块的绘图方法pyplot

利用矩阵定义x轴坐标和y轴坐标

调用API绘制折线图

调用API绘制柱状图

显示图

代码实现:

import numpy as np

import matplotlib.pyplot as plt

x=np.array([1,2,3,4,5,6,7,8])#定义即将绘制的图的x轴坐标矩阵

y=np.array([1,5,7,6,2,7,10,15])#定义即将绘制的图的y轴坐标矩阵

plt.plot(x,y,'r')#调用API绘制折线图,这里是调用plot(x轴坐标矩阵,y轴坐标矩阵,颜色)API来进行绘制折线图

plt.plot(x,y,'g',lw=10)#调用API绘制折线图,这里是调用plot(x轴坐标矩阵,y轴坐标矩阵,颜色,线条宽度)API来进行绘制折线图

x=np.array([1,2,3,4,5,6,7,8])#定义即将绘制的图的x轴坐标矩阵

y=np.array([13,25,17,36,21,16,10,15])#定义即将绘制的图的y轴坐标矩阵

plt.bar(x,y,0.5,alpha=1,color='b')#调用API绘制柱状图,这里是调用bar(x轴坐标矩阵,y轴坐标矩阵,柱宽度比例,透明度(这个属性只有PNG图片有),颜色)API来进行绘制柱状图

plt.show()


**********股票实例***********

知识补充:

思路:

导入tensorflow、numpy、matplotlib模块

定义x轴和y轴

调用API定义一个绘图

利用循环进行数据装载,并绘制柱状图

显示当前图

代码实现:

import tensorflow as tf

import numpy as np

import matplotlib.pyplot as plt

date=np.linspace(1,15,15)#定义x轴坐标矩阵(这里是日期)

endPrice=np.array([2511.90,2538.26,2510.68,2591.66,2732.98,2701.69,2701.29,2678.67,2726.50,2681.50,2739.17,2715.07,2823.58,2864.90,2919.08])#定义y轴坐标矩阵(这里是收盘价格)

beginPrice=np.array([2438.71,2500.88,2534.95,2512.52,2594.04,2743.26,2697.47,2695.24,2678.23,2722.13,2674.93,2744.13,2717.46,2832.73,2877.40])#定义y轴坐标矩阵(这里是开盘价格)

print(date)

plt.figure()#调用API定义一个绘图

for i in range(15):

    dateOne=np.zeros([2])

    dateOne[0]=i

    dateOne[1]=i

    priceOne=np.zeros([2])

    priceOne[0]=beginPrice[i]

    priceOne[1]=endPrice[i]

    if endPrice[i]>beginPrice[i]:

        plt.plot(dateOne,priceOne,'r',lw=8)

    else:

        plt.plot(dateOne,priceOne,'g',lw=8)

plt.show()


*********实现神经网络******************

知识补充:

神经网络分为三层

输入层(A,就是一个输入矩阵),输入层功能就是把数据传递个隐藏层

隐藏层(B,也是由一个个的矩阵组成),数据经隐藏层计算之后,计算结果传递给输出层

输出层(C,就是一个输出矩阵),输出层就是保存显示最后结果

通过输入天数,输出每天对应的股价(收盘价格)

用数学公式将神经网络不同层之间进行连接:

A*w1+b1=B

B*w2+b2=C

A:输入矩阵(15*1)

B:隐藏层矩阵(15*10)

C:输出矩阵(15*1)

w1:权重矩阵(1*10)

b1:偏移矩阵(1*10)

w2:_______(10*1)

b2:________(15*1)

就是输入天数矩阵A,通过利用w1,b1,w2,b2,最终得到输出天数矩阵C

第1次循环,输入日期A,初始化w1,w2,,b1,b2为0.1,0.1,0.2,0.3,计算出第一天的股价C1。然后将已知的股价C10-C1的得到预测股价与真实股价的差值D1

第二次循环,利用梯度下降法(一个API,这个API的功能是为了使当前的预测值和真实值得差距D1减小。这个API是通过修改w1,w2,b1,b2,的值来逐渐是当前预测值和真实值差距D1减小。因此这个API会给出更新后的w1,w2,b1,b2为0.11,0.99.0,22,0.34,然后利用更新后的w1,w2,b1,b2,重复第一次的循环,计算出新的C1,然后继续与C10做差更新D1)

然后不断循环直到终止

终止条件可以定义循环多少次进行终止(可自己定义)

终止条件也可以通过控制D1来进行终止(比如说定义C1,和C10差异在2%以内则终止循环)


循环终止之后会得到一个最终的w1,w2,b1,b2(这就是神经网络最重要的参数,得到这些参数的模型,就叫做训练好的模型),然后利用这些最终的参数就可以输入未来的日期进行预测未来的股价。

其实w,b在神经网络图上表现出来就是节点之间的连线(节点其实就相当于矩阵),这样得到最终的w,b就相当于确定了节点的连线,这样任意给定一个输入就可以根据这些线来计算出隐藏层节点(结果)和输出层节点(结果)

所以神经网络最根本的实质就是来求w,b(就是来求这些节点之间的线)


讲述输入神经网络之前,为了计算方便,需要对数据预处理(归一化)


激励函数其实就是对当前计算结果进行映射变成另外一个值

思路:

导入tensorflow、numpy、matplotlib模块

定义x轴和y轴

调用API定义一个绘图

利用循环进行数据装载,并绘制柱状图


对输入数据进行归一化

初始化权值

初始化偏移量

计算出隐藏层矩阵

利用激励函数处理隐藏层矩阵

初始化权值

初始化偏移量

计算出输出层矩阵

利用激励函数处理输出层矩阵


调用API计算预测结果和实际结果的差异(损失值)

利用梯度下降法不断迭代,调整权值和偏移量,使损失值不断减小


创建会话

一次性初始化所有变量

运行计算图(这个过程也叫作训练模型)

定义迭代终止条件(满足条件时停止迭代,完成训练)

运行迭代程序(同时输入参数)

对模型进行测试

并将测试结果进行还原(就是去归一化),然后与真实值进行比较

绘制预测结果柱状图

显示图



代码实现:

import tensorflow as tf

import numpy as np

import matplotlib.pyplot as plt

date=np.linspace(1,15,15)#定义x轴坐标矩阵(这里是日期)

endPrice=np.array([2511.90,2538.26,2510.68,2591.66,2732.98,2701.69,2701.29,2678.67,2726.50,2681.50,2739.17,2715.07,2823.58,2864.90,2919.08])#定义y轴坐标矩阵(这里是收盘价格)

beginPrice=np.array([2438.71,2500.88,2534.95,2512.52,2594.04,2743.26,2697.47,2695.24,2678.23,2722.13,2674.93,2744.13,2717.46,2832.73,2877.40])#定义y轴坐标矩阵(这里是开盘价格)

print(date)

plt.figure()#调用API定义一个绘图

for i in range(15):

    dateOne=np.zeros([2])

    dateOne[0]=i

    dateOne[1]=i

    priceOne=np.zeros([2])

    priceOne[0]=beginPrice[i]

    priceOne[1]=endPrice[i]

    if endPrice[i]>beginPrice[i]:

        plt.plot(dateOne,priceOne,'r',lw=8)

    else:

        plt.plot(dateOne,priceOne,'g',lw=8)


dateNormal=np.zeros([15,1])

priceNormal=np.zeros([15,1])

for i in range(15):

    dateNormal[i,0]=i/14#归一化输入层矩阵

    priceNormal[i,0]=endPrice[i]/3000.0#归一化输入层矩阵

x=tf.placeholder(tf.float32,[None,1])

y=tf.placeholder(tf.float32,[None,1])


w1=tf.Variable(tf.random_uniform([1,10],0,1))#随机初始化权重

b1=tf.Variable(tf.zeros([1,10]))#初始化偏移量

wb1=tf.matmul(x,w1)+b1#根据输入层矩阵、权值,偏移量,计算出隐藏层矩阵

layer1=tf.nn.relu(wb1)#利用激励函数对隐藏层局阵进行映射,生成新的隐藏层矩阵


w2=tf.Variable(tf.random_uniform([10,1],0,1))#随机初始化权重

b2=tf.Variable(tf.zeros([15,1]))#初始化偏移量

wb2=tf.matmul(layer1,w2)+b2#根据隐藏层矩阵、权值,偏移量,计算出输出层矩阵

layer2=tf.nn.relu(wb2)#利用激励函数对输出层局阵进行映射,生成新的输出层矩阵


loss=tf.reduce_mean(tf.square(y-layer2))#调用API计算预测结果和实际结果的差异

#。这里使用square(实际值矩阵-预测值矩阵)API,对实际值和预测值的差进行开方。

#然后再使用reduce_mean(矩阵)API,对得到的差值矩阵取平均值。


train_step=tf.train.GradientDescentOptimizer(0.1).minimize(loss)#利用梯度下降法不断迭代,调整权值和偏移量,使损失值不断减小

with tf.Session() as sess:

    sess.run(tf.global_variables_initializer())

    for i in range(10000):#定义迭代终止条件(满足条件时停止迭代,完成训练)

        sess.run(train_step,feed_dict={x:dateNormal,y:priceNormal})#运行迭代程序(同时输入参数)

    pred=sess.run(layer2,feed_dict={x:dateNormal})#对模型进行测试

    predPrice=np.zeros([15,1])

    for i in range(15):

        predPrice[i,0]=(pred*3000)[i,0]#并将测试结果进行还原(就是去归一化),然后与真实值进行比较

    plt.plot(date,predPrice,'b',lw=1)#绘制预测结果柱状图

plt.show()


**********图像几何变换*************

知识补充:

图像的几何变换是图像处理中非常基础的一步。

图像的几何变换很少直接应用在工程中,常用于实现工程前图像预处理。

只要涉及到图像处理和计算机视觉都会用到图像的几何变换(图像的几何变换是计算机视觉的基础)。


常用的图像几何变换,图形等比例缩放

后续会用Hog+SVM实现一个目标检测算法,但是目标检测第一步就是图像样本的准备,所有的样本搜集好之后,都要运用图像几何变换变为相同尺寸的大小。(其实就是对图像等比例缩放或者裁剪,得到相同规格大小的图片作为训练学习的样本)


图像的放射变换(也叫投射变换),其实就是将图片从一中形状投射成另一种形状(比如车幅系统中的车道检测算法,一般摄取的车道是梯形,我们需要运用放射变换,将梯形的车道投射程正方形的车道)


图像几何变换是高级计算机视觉的基础和前提


其他常用的图像几何变换,图像位移,图像镜像,图像剪切,(还有上面提到的,图像缩放,图像放射变化)


图像缩放,其实就是改变图像的宽和高

包括图像放大和图像缩小

具体又可分为图片等比例缩放和图片非等比例缩放

四种常用的图像缩放算法:最近邻域插值算法、双线性插值算法(默认情况下使用这一种)、像素关系重采样、立方插值

图片剪切,其实就是已知图片矩阵中的一块数据,根据这个已知图像块的数据把它从整个图像矩阵中单独剪切出来(本质其实就是对矩阵的操作)


图片的位移,就是通过矩阵运算,将图片的位置在视图中整体移动


图片的镜像,其实就是将原图像矩阵倒序绘制一次,然后倒序绘制的新矩阵和原图像矩阵拼接成一个两倍大的矩阵


其实不论位移,还是旋转、缩放,都可以通过图像放射变换来实现

图像的几何变换的本质就是对图像矩阵的操作


思路:

引入opencv模块

加载图片

获取图片信息(宽、高)

定义缩放后的图片尺寸

调用API完成图片的缩放

显示缩放结果

暂停

代码实现:

import cv2

img=cv2.imread('1.jpg',1)#读入图片(这里的img其实就是一个矩阵)

imgInfo=img.shape#获取矩阵的行数(就是图片的高度),矩阵的列数(就是图片的宽度),通道数(图片的颜色组成方式)

print(imgInfo)

height=imgInfo[0]#图像的高

widht=imgInfo[1]#图像的宽

mode=imgInfo[2]#图像颜色组成方式(此处为3,表示一个图像的像素点实际上是由三个基本颜色组成)


dstHeight=int(height*0.5)#定义缩放后的图片高度

dstWidth=int(width*0.5)#定义缩放后的图片宽度


dst=cv2.resize(img,(dstHeight,dstWidth))#调用API对图片进行缩放操作,这里使用cv2.resize(原图矩阵,(缩放后的高度,缩放后的宽度))这个API,返回一个缩放后的图片矩阵

cv2.imshow('image',dst)

cv2.waitKey(0)



**********最近邻域插值法、双线性插值法*************************

知识补充:

在将原图缩放成目标图片时。目标图片上的每一个点都可以来自原图像(如何通过计算的方式找到这些点)

如果已知目标图片的点坐标(x,y),计算出它来自与原图片的那个点(x0,y0)

x0=x*(原图行数/目标图片行数)

y0=y*(原图列数/目标图片列数)

当计算出来的x0,y0是浮点数时,进行取整即可(四舍五入,去距离当前浮点数最近的整数,这就叫做最近邻域插值法)

当计算出来的x0,y0是浮点数时,使用周边四个像素点与权重进行线性运算来表示点(x0,y0)(这就是双线性插值法)。具体如下图

这里计算出来的x0=15.3,y0=22.3

A1=20%(15,22)+80%(16,22)

A2=20%(15,23)+80%(16,23)

(x0,y0)=A1*30%+A2*70%

B1=30%(15,22)+70%(15,23)

B2=30%(15622)+70%(16,23)

(x0,y0)=B1*20%+B2*80%

上面两种计算方式(一种是用A1,A2;一种使用B1,B2表示)都可以,任选一种表示方式即可


图形缩放实现方式

可以直接调用API,cv2.resize()

也可以根据几种插值法的算法原理,编写源码实现

对每一个编程和算法的知识点,分这三步(现成的API,经典算法原理,算法原理的代码实现),就可以掌握的十分透彻

大多课程,都是只讲了API的调用和算法原理,而对算法原理的代码实现,需要我们自己课下实现和反复的练习,才能彻底吃透这一个知识点或算法

思路:

引入opencv

引入numpy模块

获取图片信息

定义缩放后的目标图片的高和宽

创建空白模板(大小与缩放后的目标图像相同)

计算空白模板的每一个像素在原图的坐标,并从原图中复制对应像素点空白模板(这就完成了对图片的缩放,得到了目标图片)

显示缩放后的图像

暂停


代码实现:

import cv2

import numpy as np

img=cv2.imread('1.jpg',1)#读入图片(这里的img其实就是一个矩阵)

imgInfo=img.shape#获取矩阵的行数(就是图片的高度),矩阵的列数(就是图片的宽度),通道数(图片的颜色组成方式)

print(imgInfo)

height=imgInfo[0]#图像的高

width=imgInfo[1]#图像的宽

mode=imgInfo[2]#图像颜色组成方式(此处为3,表示一个图像的像素点实际上是由三个基本颜色组成)


dstHeight=int(height*0.5)#定义缩放后的图片高度

dstWidth=int(width*0.5)#定义缩放后的图片宽度


dstImage=np.zeros((dstHeight,dstWidth,3),np.uint8)#调用API按照目标图片尺寸和信息创建空白模板,这里使用了np.zeros((目标图片高,目标图片宽,目标图片通道数),目标图片每个像素的数据类型),这里np.uint8这个数据类型的范围是0-255


for i in range(0,dstHeight):

for j in range(0,dstWidth):

iNew=int(i*(height*1.0/dstHeight))#利用公式计算出,与目标图片该点对应的原图片中点的坐标x。这里乘以1.0是为了类型转换(转换为浮点型)

jNew=int(j*(width*1.0/dstWidth))#利用公式计算出,与目标图片该点对应的原图片中点的坐标y。这里乘以1.0是为了类型转换(转换为浮点型)

dstImage[i,j]=img[iNew,jNew]#根据计算得出的坐标,将原图片中的像素点复制到目标图片中。(以此完成图像的缩放)

cv2.imshow('dst',dstImage)

cv2.waitKey(0)


*************************图片的剪切******************************

知识点补充:

图片坐标系如图

x轴表示宽度或者叫列信息(向右为+),y轴表示高度或者叫行信息(向下为+)

左上角为(0,0)点

实现图像剪切时,首先要确定剪切出来的目标图片在原始图片中的位置(也就是目标图片的左上角的原点在原图中的坐标)。然后根据坐标和目标图片的尺寸来进行剪切(从原图剪切得到目标图片)


思路:

引入opencv

读取图片信息

实现图片的剪切

显示剪切出来的图片

暂停

代码实现:

import cv2

img=cv2.imread('1.jpg',1)

imgInfo=img.shape

dst= img[100:200,100:300]#使用 原图矩阵[剪切图片在原图中的x轴范围,剪切图片在原图中的y轴范围] 来得到目标矩阵(剪切出来的图像矩阵)

cv2.imshow('src',dst)

cv2.waitKey(0)

***************************图片位移*************************

知识补充:

可以用现成API实现图片位移

原图矩阵为C(2*1)=[[x],[y]]

位移矩阵为D(2*3)=[[1,0,100],[0,1,200]]

将D拆分成两个矩阵A(2*2)=[[1,0],[0,1]],B(2*1)=[[100],[200]]

通过公式A*C+B运算得到位移后的图片矩阵E

[[1,0],[0,1]]*[[x],[y]]+[[100],[200]]=

[[1*x,0*y],[0*x,1*y]]+[[100],[200]]=

[[x+100],[y+200]]

至此就实现了对图像的位移


也可以根据图片位移的算法原理,编写源码进行实现

对每个像素点进行相同的位移就可得到对整个图像位移后的目标图像

其实就是将原图的每个像素点按照定义的位移投影到空白图像上的新的坐标点上

本质就是计算与在空白图像上的像素点坐标(该像素点与原图像素点相对应)

思路:

引入 opencv

引入 numpy

读取图片

显示图片


获取图片信息(宽,高)

定义位移矩阵(通过将原图与该矩阵进行四则运算实现图像的位移)

调用API,通过将原矩阵按照定义矩阵进行映射得到位移矩阵

显示位移图片

暂停


引入 opencv

引入 numpy

读取图片

显示图片


获取图片信息(宽,高)

定义空白图像矩阵

根据图像位移的算法原理利用矩阵计算来实现图像的位移

显示位移后的图像

暂停


代码实现:

import cv2

import numpy as np



img=cv2.imread('1.jpg',1)

cv2.imshow('src',img)

cv2.waitKey(0)


imgInfo=img.shape

height=imgInfo[0]

width=imgInfo[1]


matShift=np.float([[1,0,100],[0,1,200]])#定义位移矩阵,这里是沿x轴(沿水平方向,向右移动100个像素位置)方向移动100个像素,沿y轴(沿竖直方向,向下移动200个像素位置)方向移动200个像素(通过将原图与该矩阵进行四则运算实现图像的位移)

dst=cv2.warpAffine(img,matShift,(height,width))#调用API,通过将原矩阵按照定义矩阵进行映射得到位移矩阵。这里使用cv2.warpAffine(原图矩阵,位移矩阵,(原图高度,原图宽度)),最终返回位移图像矩阵

cv2.imshow('dst',dst)

cv2.waitKey(0)



import cv2

import numpy as np

img=cv2.imread('1.jpg',1)

cv2.imshow('src',img)

cv2.waitKey(0)


imgInfo=img.shape

height=imgInfo[0]

width=imgInfo[1]


dst=np.zeros(img.shape,np.uint8)#定义空白图cv2像矩阵


for i in range(height):

for j in range(width-100):

dst[i,j+100]=img[i,j]

cv2.imshow('dst',dst)

cv2.waitKey(0)


**********图片的镜像**********

知识补充:

图片的镜像其实就是对图像进行了翻转(上下镜像就是,每个像素点的x坐标不变,y轴坐标上下对调)

y=2h-y-1






思路:

引入 opencv

引入 numpy

读取图片

显示图片


获取图片信息(宽,高,通道数)


定义空白画板的信息(就是定义空白图像矩阵的信息,宽,高,通道数)

创建一个高度为原图片两倍,宽度与原图片相同的的画板(就是空白矩阵)

在画板上从上到小绘制原图,然后再从下到上绘制原图

在画板中间绘制分割线

显示镜像图像

暂停


代码实现:

import cv2

import numpy as np

img=cv2.imread('1.jpg',1)

cv2.imshow('src',img)

cv2.waitKey(0)


imgInfo=img.shape

height=imgInfo[0]

width=imgInfo[1]

deep=imgInfo[2]


newImgInfo(height*2,width,deep)#定义空白画板的信息(就是定义空白图像矩阵的信息,宽,高,通道数)

dst=np.zeros(newImgInfo,np.uint8)#创建一个高度为原图片两倍,宽度与原图片相同的的画板(就是空白矩阵)

for i in range(height):

for j in range(0,width):

dst[i,j]=img[i,j]#在画板上从上到小绘制原图

dst[height*2-i-1,j]=img[i,j]#从下到上绘制原图

for i in range(0,width):

dst[height,i]=(0,0,255)#在画板中间绘制分割线

cv2.imshow('dst',dst)

cv2.waitKey(0)


***********利用图像位移来实现图像的缩放*******************

知识补充:

思路:

引入 opencv

引入 numpy

读取图片

显示图片


获取图片信息(宽,高,通道数)


定义缩放矩阵

对图像进行缩放

显示缩放后的图像

暂停


代码实现:

import cv2

import numpy as np

img=cv2.imread('1.jpg',1)

cv2.imshow('src',img)

cv2.waitKey(0)


imgInfo=img.shape

height=imgInfo[0]

width=imgInfo[1]


matScale=np.float32([[0.5,0,0],[0,0.5,0]])

dst=cv2.warpAffine(img,matScale,(int(width/2),int(height/2)))

cv2.imshow('dst',dst)

cv2.waitKey(0)


************图像的放射变换*************

知识补充:

图像的放射变换,其实就是将图像的像素点按照一定的规律映射到新的位置上

实际上也是求图像中像素点的新的坐标的问题

放射变换并没有确定的公式

一般是通过对图像的三个点(左上角,左下角,右上角)的拉伸来实现放射变换

放射变换的实质就是将原图像的三个点映射到目标图像的三个新的位置上


思路:

引入 opencv

引入 numpy

读取图片

显示图片


获取图片信息(宽,高,通道数)

取原图三个点

定义原图上三个点在目标图像上的新的坐标位置


调用API定义放射变换矩阵(通过原图和放射变换矩阵进行四则运算最终得到放射后的目标图像矩阵)

调用API进行放射变换得到目标图像矩阵

显示目标图像

暂停

代码实现:

import cv2

import numpy as np

img=cv2.imread('1.jpg',1)

cv2.imshow('src',img)

cv2.waitKey(0)


imgInfo=img.shape

height=imgInfo[0]

width=imgInfo[1]


matSrc=np.float32([[0,0],[0,height-1],[width-1,0]])#取原图三个点

matDst=np.float32([[50,50],[300,height-200],[width-300,100]])#定义原图上三个点在目标图像上的新的坐标位置


matAffine=cv2.getAffineTransform(matSrc,matDst)#调用API定义放射变换矩阵。这里使用getAffineTransform(原图三个点,目标图三点的新坐标)这个API,返回一个放射变换矩阵

dst=cv2.warpAffine(img,matAffine,(width,height))#调用API进行放射变换得到目标图像矩阵

cv2.imshow('dst',dst)

cv2.waitKey(0)


*************图片的旋转**********

知识补充:


思路:

引入 opencv

引入 numpy

读取图片

显示图片


获取图片信息(宽,高,通道数)

调用API得到旋转矩阵(通过将原图与旋转矩阵进行四则运算最终得到一个旋转后的目标图像)

调用API对得到目标图像

显示旋转后的目标图像

暂停

代码实现:

import cv2

import numpy as np

img=cv2.imread('1.jpg',1)

cv2.imshow('src',img)

cv2.waitKey(0)


imgInfo=img.shape

height=imgInfo[0]


width=imgInfo[1]

matRotate=cv2.getRotationMatrix2D((height*0.5,width*0.5),45,0.5)#调用API得到旋转矩阵,这里使用cv2.getRotationMatrix2D(旋转的中心点坐标,旋转的角度,缩放的系数)这个API来获得一个旋转矩阵

dst=cv2.warpAffine(img,matRotate,(height,width))

cv2.imshow('dst',dst)

cv2.waitKey(0)

********图像几何变换小结*******

放射变换用在了图像位移,旋转,缩放上

图像几何变幻的实质其实就是矩阵的运算(原图与不同的系数矩阵进行四则运算就对原图像完成了不同的几何变换)


***********图像的特效**********

知识补充:

灰度处理(普通灰度,底板效果),马赛克效果,毛玻璃效果,图像融合,颜色变换,边缘检测,浮雕效果,油画效果

这些都属于图像滤镜的相关算法

使用opencv进行线段绘制、文字绘制(加字)、图片绘制(加图)等

直方图的绘制(统计当前灰度等级出现的概率)

图像检测都是基于图像的灰度特征(人脸检测、车牌检测等等)

还是按照,先API实现,在根据算法原理编码实现


灰度效果,其实就是完成彩色图像灰度化的过程(是很多高级图像处理的基础,是最重要的图像效果算法,没有之一,比如图形的边缘检测,人脸检测等都是以灰度图像为基础。很多计算机视觉都要求实时处理,通过图像的灰度化可以提高运算效果,更好的实现实时图像处理)

彩色图像的三个颜色通道R,G,B的值是互不相等的

灰度图像的三个颜色通道R,G,B等值是相等

如果要得到单通道的灰度图像,那么他的通道值需要经过对彩色图像的R,G,B值进行计算得到

两种计算公式,一种是直接对R,G,B,取均值,另一种是根据心理学定义的按比例对R,G,B进行加权后相加的运算


opencv中用很多API都可以实现整个功能

比如imread(图像名,0),这里第二个参数设置为0,就是将图像按照灰度方式方式进行读取

cvtColor,这个API也可以实现图形的灰度化

也可以根据图像灰度化的算法原理来编程实现图像的灰度化


优化灰度处理算法

定点元素速度比浮点运算快

+-操作比*/操作速度要快

>>,<<操作比*/速度要快

基于以上三点可以实现图像灰度算法的优化







底板效果

彩色底板效果,其实就是对当前彩色图像的R,G,B,值取反得到

灰度底板,是对灰度通道值取反得到


马赛科效果

将要打马赛克的区域划分成一个个的小方框(方框的尺寸就是马赛克的尺寸)

然后将方框中的所有像素点,全部用这个方框中的某一个像素点覆盖,使这个小方框中所有的像素值都是一样的

马赛克就是将方框中的所有像素点,用同一个像素点替代


毛玻璃效果

毛玻璃是将马赛克的方框中的每个像素点,从组成这个方框的所有像素点取一个来覆盖(这样方框中的每个点都是随机的,都是不同的,而且都是属于原来组成这个方框的像素点集)


融合效果

实现的是两种图片像素的融合


颜色映射

给定RGB颜色导向值,然后图像根据这个导向值修改RGB

边缘检测(也称二值化)

保留的是整个图像的细节信息(比较光滑平缓的地方就删除掉了,只留下了轮廓和纹理)


浮雕效果:

在边缘检测的基础上,再进行底板效果,就形成了浮雕效果


思路:

引入opencv

调动API分别以灰度和彩色两种形式读取图片

分别打印灰度图像矩阵信息和彩色图像矩阵信息

显示灰度图像

暂停


引入opencv

将图像一彩色图片形式读取进来

调用API将彩色图像转换为灰度图像

显示灰度图像

暂停


引入 opencv

引入 numpy

读取图片

显示图片


获取图片信息(宽,高,通道数)

定义空白画板

读取原图像素值并进行数据类型转换(因为Uint8类型数在四则运算时有可能溢出,所以要进行数据类型的转换,转换为int类型),b对RGB取平均得到平均值并进行数据类型转换(在再由int转换为uint8),使空白画板相同坐标位置的像素点的RGB值都等于这个平均值(这就完成了图像的灰度化)


引入 opencv

引入 numpy

读取图片

显示图片


获取图片信息(宽,高,通道数)

定义空白画板

读取原图像素值并进行数据类型转换(因为Uint8类型数在四则运算时有可能溢出,所以要进行数据类型的转换,转换为int类型),b对RGB运用心理学计算公式进行加权并求和,然后进行数据类型转换(在再由int转换为uint8),使空白画板相同坐标位置的像素点的RGB值都等于这个平均值(这就完成了图像的灰度化)



优化灰度算法

将小数放大为整数,运算结束后再进行缩小

进一步优化将*1省略掉,将*2用<<替换,将/4用>>替换

这样提升了速度


代码实现:

import cv2

img0=cv2.imread('1.jpg',0)

img1=cv2.imread('1.jpg',1)

print(img0.shape)#灰度图像,颜色通道数为1(灰度图像颜色是一维的,也就是单通道)

print(img1.shape)#彩色图像,颜色通道数为3(彩色图像颜色是三维的,也就是三通道)

cv2.imshow('src',img0)

cv2.waitKey(0)


import cv2

img0=cv2.imread('1.jpg',1)

dst=cv2.cvtColor(img,cv2.COLOR_BGRA2GRAY)#调用API将彩色图像转换为灰度图像,这里使用cv2.cvtColor(原图矩阵数据,颜色转换的方式(就是定义转换成那种))这个API完成颜色空间的转换(这里是由RGB颜色空间,转换为灰度空间)


import cv2

import numpy as np

img=cv2.imread('1.jpg',1)

cv2.imshow('src',img)

cv2.waitKey(0)

imgInfo=img.shape

height=imgInfo[0]

width=imgInfo[1]


dst=np.zeros((height,width,3),np.uint8)

for i in range(height):

for j in range(width):

(b,g,r)=img[i,j]#读取原图像素值

gray=(int(b)+int(g)+int(r))/3#对原图像素值并进行数据类型转换(因为Uint8类型数在四则运算时有可能溢出,所以要进行数据类型的转换,转换为int类型),b对RGB取平均得到平均值。

dst[i,j]=np.uint8(gray)#进行数据类型转换(在再由int转换为uint8),使空白画板相同坐标位置的像素点的RGB值都等于这个平均值(这就完成了图像的灰度化)

dst

cv2.imshow('dst',dst)

cv2.waitKey(0)



import cv2

import numpy as np

img=cv2.imread('1.jpg',1)

cv2.imshow('src',img)

cv2.waitKey(0)

imgInfo=img.shape

height=imgInfo[0]

width=imgInfo[1]


dst=np.zeros((height,width,3),np.uint8)

for i in range(height):

for j in range(width):

(b,g,r)=img[i,j]#读取原图像素值

gray=int(b)*0.114+int(g)*0.587+int(r)*0.299#对原图像素值并进行数据类型转换(因为Uint8类型数在四则运算时有可能溢出,所以要进行数据类型的转换,转换为int类型),对RGB运用心理学计算公式进行加权并求和

dst[i,j]=np.uint8(gray)#进行数据类型转换(在再由int转换为uint8),使空白画板相同坐标位置的像素点的RGB值都等于这个平均值(这就完成了图像的灰度化)


dst

cv2.imshow('dst',dst)

cv2.waitKey(0)



import cv2

import numpy as np

img=cv2.imread('1.jpg',1)

cv2.imshow('src',img)

cv2.waitKey(0)

imgInfo=img.shape

height=imgInfo[0]

width=imgInfo[1]


dst=np.zeros((height,width,3),np.uint8)

for i in range(height):

for j in range(width):

(b,g,r)=img[i,j]#读取原图像素值

gray=(int(b)*1+int(g)*2+int(r)*1)/4#对原图像素值并进行数据类型转换(因为Uint8类型数在四则运算时有可能溢出,所以要进行数据类型的转换,转换为int类型),对RGB运用心理学计算公式进行加权并求和。这里进行了优化,先将浮点数左移两位,运算结束后在右移两位(提高了速度,但是增大了误差)

dst[i,j]=np.uint8(gray)#进行数据类型转换(在再由int转换为uint8),使空白画板相同坐标位置的像素点的RGB值都等于这个平均值(这就完成了图像的灰度化)


dst

cv2.imshow('dst',dst)

cv2.waitKey(0)


import cv2

import numpy as np

img=cv2.imread('1.jpg',1)

cv2.imshow('src',img)

cv2.waitKey(0)

imgInfo=img.shape

height=imgInfo[0]

width=imgInfo[1]


dst=np.zeros((height,width,3),np.uint8)

for i in range(height):

for j in range(width):

(b,g,r)=img[i,j]#读取原图像素值

gray=(int(b)+(int(g)<<1)+int(r))>>4#对原图像素值并进行数据类型转换(因为Uint8类型数在四则运算时有可能溢出,所以要进行数据类型的转换,转换为int类型),对RGB运用心理学计算公式进行加权并求和。这里进行了优化,先将浮点数左移两位,运算结束后在右移两位,并将*1省略掉,并用左移替换了*2,用右移替换/4(提高了速度,但是增大了误差)

dst[i,j]=np.uint8(gray)#进行数据类型转换(在再由int转换为uint8),使空白画板相同坐标位置的像素点的RGB值都等于这个平均值(这就完成了图像的灰度化)


dst

cv2.imshow('dst',dst)

cv2.waitKey(0)


***************图像颜色翻转*********************

知识补充:

灰度图像颜色翻转:

对于灰度图像,它的像素点的像素值(灰度值)取值范围为0-255

对灰度图像进行颜色翻转,其实就是对每一个像素,使他们的像素值=255-他们原来的像素值


彩色图像颜色翻转:

对于彩色图像,它的像素点的像素值(灰度值)取值范围也是0-255

对彩色图像进行颜色翻转,其实就是对每一个像素点的RGB三个通道,使每个通道的像素值=255-他们原来的像素值


思路:

引入 opencv

引入 numpy

读取图片

显示图片


获取图片信息(宽,高,通道数)

对图像进行灰度化

建立空白画板

对灰度图像进行颜色翻转


显示颜色翻转后的目标图像

暂停



引入 opencv

引入 numpy

读取图片

显示图片


获取图片信息(宽,高,通道数)

建立空白画板

对灰度图像进行颜色翻转


显示颜色翻转后的目标图像

暂停

代码实现:

import cv2

import numpy as np

img=cv2.imread('1.jpg',1)

cv2.imshow('src',img)

cv2.waitKey(0)

imgInfo=img.shape

height=imgInfo[0]

width=imgInfo[1]


gray==cv2.cvtColor(img,cv2.COLOR_BGRA2GRAY)

dst=np.zeros((height,width,1),np.uint8)

for i in range(height):

for j in range(width):

grayPixel=gray[i,j]

dst[i,j]=255-grayPixel


cv2.imshow('dst',dst)

cv2.waitKey(0)


import cv2

import numpy as np

img=cv2.imread('1.jpg',1)

cv2.imshow('src',img)

cv2.waitKey(0)

imgInfo=img.shape

height=imgInfo[0]

width=imgInfo[1]


dst=np.zeros((height,width,1),np.uint8)

for i in range(height):

for j in range(width):

(b,g,r)=img[i,j]

b=255-b

g=255-g

r=255-r

dst[i,j]=(b,g,r)


cv2.imshow('dst',dst)

cv2.waitKey(0)

************图片的马赛克效果**********************

知识补充:

马赛克效果的范围(窗体范围,窗体形状有矩形也有圆形)


思路:

引入 opencv

引入 numpy

读取图片

显示图片


获取图片信息(宽,高,通道数)

实现马赛克效果

暂停

代码实现:

import cv2

import numpy as np

img=cv2.imread('1.jpg',1)

cv2.imshow('src',img)

cv2.waitKey(0)

imgInfo=img.shape

height=imgInfo[0]

width=imgInfo[1]


for m in range(100,300):

for n in range(100,200):

if m%10==0 and n%10==0:

for i in range(10):

for j in range(10):

(b,g,r)=img[m,n]

img[i+m,j+n]=(b,g,r)

cv2.imshow('dst',img)

cv2.waitKey(0)

*********图片的毛玻璃效果***************

知识补充:


思路:

引入 opencv

引入 numpy

引入 random模块

读取图片

显示图片


获取图片信息(宽,高,通道数)

定义空白画板

实现毛玻璃效果

显示毛玻璃效果

暂停

代码实现:

import cv2

import numpy as np

import random

img=cv2.imread('1.jpg',1)

cv2.imshow('src',img)

cv2.waitKey(0)

imgInfo=img.shape

height=imgInfo[0]

width=imgInfo[1]


dst=np.zeros((height,width,3),np.uint8)

#mm=8

for m in range(height-8):

for n in range(width-8):

index=int(random.random()*8)

(b,g,r)=img[m+index,n+index]

dst[m,n]=(b,g,r)

cv2.imshow('dst',dst)

cv2.waitKey(0)


*********************图片的融合*********************

知识补充:

图像融合时图像大小必须保持一致

图像融合实现公式

dst=src1*a+src2*(1-a)#目标图像矩阵=原图矩阵1*系数+原图矩阵2*(1-系数)

思路:

引入 opencv

引入 numpy

读取两张图片


获取图片信息(宽,高,通道数)

定义融合区域

定义空白画板

调用API实现图像的融合

显示图像融合效果

暂停


代码实现:

import cv2

import numpy as np

img0=cv2.imread('11.jpg',1)

img1=cv2.imread('22.jpg',1)

imgInfo=img0.shape

height=imgInfo[0]

width=imgInfo[1]


roiH=int(height/2)

roiW=int(width/2)

img0ROI=img0[0:roiH,0:roiW]

img1ROI=img1[0:roiH,0:roiW]


dst=np.zeros((roiH,roiW,3),np.uint8)

dst=cv2.addWeighted(img0ROI,0.5,img1ROI,0.5,0)#调用API实现图像的融合,此处调用addWeighted(图src1,权重a,src2,权重(1-a),0),这个API 来实现两个图的加权和

cv2.imshow('dst',dst)

cv2.waitKey(0)

****************图像的边缘检测******************

知识补充:

边缘检测的效果类似素描

用两种算子分别实现边缘检测

边缘检测的实质就是对图像进行卷积运算

边缘检测是基于灰度图像的算法(所有的边缘检测算子都是基于灰度图像来处理的)


sobel算子的算法原理

算子的模板,有水平方向和竖直方向两种

水平方向                        竖直方向

图片卷积

卷积不同于矩阵四则运算

卷积是算子模板中每个元素与矩阵元素相乘再求和

卷积实例

阈值判决

经过卷积之后,得到的结果,就是我们所说的梯度

梯度有水平方向和竖直方向两种

f=sqrt(a*a+b*b)#a竖直方向上的算子与图片卷积的结果数值(a其实就是竖直梯度),b是水平方向上的算子与图片卷积的结果(b其实就是水平梯度),sqrt是对括号内内容取平方根。

将f与给定的门限值作比较,若f大于门限值则认为该像素点为边缘点


思路:

引入 opencv

引入 numpy

引入 random模块

读取图片

显示图片

获取图片信息

对图片进行灰度化

对图片进行高斯滤波去燥

调用API实现边缘检测(这里氏使用opencv中的canny方法)

显示边缘检测的图像

暂停


引入 opencv

引入 numpy

引入 random模块

读取图片

显示图片

获取图片信息

对图片进行灰度化

创建空白画板

计算竖直方向和水平反向上的梯度

计算整体梯度

根据sobel算子的算法原理实现图像的边缘检测

显示边缘检测的图像

暂停

代码实现:


import cv2

import numpy as np

import random

img=cv2.imread('1.jpg',1)

cv2.imshow('src',img)

cv2.waitKey(0)

imgInfo=img.shape

height=imgInfo[0]

width=imgInfo[1]


gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

imgG=cv2.GaussianBlur(gray,(3,3),0)#这里调用API对灰度图像进行高斯滤波(参数1位灰度图,参数2位模板大小,参数3未知)

dst=cv2.Canny(imgG,50,50)#使用Canny(图片,门限1,门限2),如果图像经过卷积之后,图像像素点的值若大于门限值,我们就认为这个点是边缘点

cv2.imshow('dst',dst)

cv2.waitKey(0)


import cv2

import numpy as np

import random

import math

img=cv2.imread('a.jpg',1)

cv2.imshow('src',img)

cv2.waitKey(0)

imgInfo=img.shape

height=imgInfo[0]

width=imgInfo[1]


gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

dst=np.zeros((height,width,1),np.uint8)

for i in range(height-2):

    for j in range(width-2):

        gy=gray[i,j]*1+gray[i,j+1]*2+gray[i,j+2]*1-gray[i+2,j]*1-gray[i+2,j+1]*2-gray[i+2,j+2]*1#竖直方向上的梯度计算

        gx=gray[i,j]*1+gray[i+1,j]*2+gray[i+2,j]*1-gray[i,j+2]*1+gray[i+1,j+2]*2+gray[i+2,j+2]*1#水平方向上的梯度计算

        grad=math.sqrt(gx*gx+gy*gy)

         #print(grad)

        if grad>900:

            dst[i,j]=255 

        else:

            dst[i,j]=0

cv2.imshow('dst',dst)

cv2.waitKey(0)


****************图像的浮雕效果************

知识补充:

浮雕效果与边缘检测原理相似,也是通过计算梯度来实现

浮雕效果的计算公式

newP=gray0-gray1+150#新的像素值=相邻像素值之差+指定值

相邻像素之差:为了突出边缘特征

指定值:增强图片灰度等级

思路:

引入 opencv

引入 numpy

引入 random模块

读取图片

显示图片

获取图片信息

对图片进行灰度化

定义空白画板

根据浮雕效果算法原理实现浮雕效果

显示浮雕效果图片

暂停

代码实现:

import cv2

import numpy as np

import random

import math

img=cv2.imread('a.jpg',1)

cv2.imshow('src',img)

cv2.waitKey(0)

imgInfo=img.shape

height=imgInfo[0]

width=imgInfo[1]


gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

dst=np.zeros((height,width,1),np.uint8)

for i in range(height):

for j in range(width-1):

grapyP0=int(gray[i,j])

grapyP1=int(gray[i,j+1])

newP=grapyP0-grapyP1+150

if newP>255:

newP=255

if newP<0:

newP=0

dst[i,j]=newP

cv2.imshow('dst',dst)

cv2.waitKey(0)

***********颜色风格变换**********

知识补充:

通过颜色映射来实现不同的颜色风格

最简单的实现就是做一个RGB查找表,根据原始图像RGB值在查找表上查找到一组新的RGB值,然后用这个新的RGB值来代替原来的像素值(RGB值)


通过公式来进行颜色映射,但这只适用于简单地颜色效果

因为颜色效果越复杂,用公式进行拟合的难度会越大,计算量甚至会超过制作一个查找表的工作量


蓝色效果公式

b=b*1.5#把RGB中的蓝色b乘以1.5进行增强

g=g*1.3#把RGB中的绿色g乘以1.3进行增强


思路:

引入 opencv

引入 numpy


读取图片


获取图片信息

建立空白画板

根据蓝色风格算法进行颜色映射

显示蓝色风格图片

暂停

代码实现:

import cv2

import numpy as np

img=cv2.imread('a.jpg',1)

imgInfo=img.shape

height=imgInfo[0]

width=imgInfo[1]


dst=np.zeros((height,width,3),np.uint8)

for i in range(height):

for j in range(width):

(b,g,r)=img[i,j]

b*=1.5

g*=1.3

if b> 255:

b=255

  if g >255:

g=255

dst[i,j]=(b,g,r)

cv2.imshow('dst',dst)

cv2.waitKey(0)


*************图片的油画效果***************************

知识补充:

将图像灰度化

将灰度图像分割为若干个小方框,统计每个小方框中每个像素点的灰度值

将0-255的灰度值划分为n等级,并将之前统计的灰度值按照这个等级进行划分

找到每个方框中占比例最多的灰度等级的所有像素点,并且对这些像素点的像素值求均值

用计算得到的平均值来代替原像素值


思路:

引入 opencv

引入 numpy

获取图片信息

对图片进行灰度化

定义空白画板


算法原理:


import cv2

import numpy as np

img=cv2.imread('a.jpg',1)

imgInfo=img.shape

height=imgInfo[0]

width=imgInfo[1]



gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

dst=np.zeros((height,width,3),np.uint8)

for i in range(4,height-4):

for j in range(4,width-4):

array1=np.zeros(8,np.uint8)

for m in range(-4,4):

for n in range(-4,4):

p1=int(gray[i+m,j+n]/32)

array1[p1]=array1[p1]+1

currentMax=array1[0]

l=0

for k in range(8):

if currentMax

currentMax=array1[k]

l=k


for m in range(-4,4):

for n in range(-4,4):

if gray[i+m,j+n]>(l*32) and gray[i+m,j+n]<=(l+1)*32:

(b,g,r)=img[i+m,j+n]

dst[i,j]=(b,g,r)


cv2.imshow('dst',dst)

cv2.waitKey(0)


********图片上的线段绘制***********

知识补充:

思路:

引入opencv

引入numpy

自定义图像的信息

创建自定义图像

调用API绘制线段

绘制三角形

显示绘制结果

暂停

代码实现:

import cv2

import numpy as np

newImageInfo=(500,500,3)

dst=np.zeros(newImageInfo,np.uint8)


cv2.line(dst,(100,100),(400,400),(0,0,255))#调用API绘制线段,line(原图,线段起点,线段终点,线段颜色)

cv2.line(dst,(100,200),(400,200),(0,255,255),20)#调用API绘制线段,line(原图,线段起点,线段终点,线段颜色,线条宽度)

cv2.line(dst,(100,300),(400,300),(0,255,0),20,cv2.LINE_AA)#调用API绘制线段,line(原图,线段起点,线段终点,线段颜色,线条宽度,线条类型)

cv2.line(dst,(200,150),(50,250),(25,100,255))

cv2.line(dst,(50,250),(400,380),(25,100,255))

cv2.line(dst,(400,380),(200,150),(25,100,255))

cv2.imshow('dst',dst)

cv2.waitKey(0)

********图像的多边形h绘制***********

知识补充:

思路:

引入opencv

引入numpy

自定义图像的信息

创建自定义图像

调用API绘制矩形

调用API绘制圆形

调用API绘制椭圆形

绘制任意多边形

显示绘制的图形

暂停

代码实现:

import cv2

import numpy as np

newImageInfo=(500,500,3)

dst=np.zeros(newImageInfo,np.uint8)

cv2.rectangle(dst,(50,100),(200,300),(255,0,0),-1)#调用API绘制矩形,rectangle(原图矩阵,矩形左上角坐标,矩形右下角坐标,矩形颜色,是否填充),最后一个参数若为-1表示填充矩阵,若为>=0的数表示矩形线条的宽度

cv2.circle(dst,(250,250),(50),(0,255,0),2)#调用API绘制圆形,circle(原图矩阵,圆心坐标,半径长度,圆形颜色,是否填充),最后一个参数若为-1表示填充矩阵,若为>=0的数表示圆形线条的宽度

cv2.ellipse(dst,(256,256),(150,100),0,0,180,(255,255,0),-1)#调用API绘制椭圆形,ellipse(原图矩阵,椭圆圆心坐标,椭圆的长轴和短轴的长度,偏转角度,椭圆圆弧起始角度,椭圆圆弧终止角度,椭圆颜色,内容是否填充)

points=np.array([[150,50],[140,140],[200,170],[250,250],[150,50]],np.int32)#定义多变形的各个顶点坐标并且以数组形式保存

points=points.reshape((-1,1,2))#对数组进行维度转换(这里是将二维数组(5,2)转换成三维数组(5,1,2),这样后续就可以根据这个三维数组绘制多边形)

cv2.polylines(dst,[points],True,(0,255,255))#调用API绘制多边形

cv2.imshow('dst',dst)

cv2.waitKey(0)


*********************在图像上绘制图片、文字***************************

知识补充

思路:

引入opencv

引入numpy

读入图片

定义字体

调用API绘制矩形

调用API绘制文字

显示绘制的文字

暂停


引入opencv

引入numpy

读入图片

缩放原图产生新的图片

将新图片放在原图上

显示图片绘制的效果

暂停

代码实现:

import cv2

import numpy as np

img=cv2.imread('a.jpg',1)

font=cv2.FONT_HERSHEY_SIMPLEX

cv2.rectangle(img,(200,100),(500,400),(0,255,0),3)

cv2.putText(img,'this is flower',(100,300),font,1,(200,100,255),2,cv2.LINE_AA)#调用API绘制文字,putText(原图矩阵,文字内容,文字的坐标,字体,字体的大小,文字颜色,字体的粗细,字体线条的类型)

cv2.imshow('img',img)

cv2.waitKey()


import cv2

img=cv2.imread('a.jpg',1)

height=int(img.shape[0]*0.2)

width=int(img.shape[1]*0.2)

imgResize=cv2.resize(img,(width,height))

for i in range(height):

for j in range(width):

img=[i+200,j+350]=imgResize[i,j]

cv2.imshow('src',img)

cv2.waitKey(0)


************图片美化********

知识补充:

颜色等级的直方图统计特征

RGB三种颜色的直方图

横坐标为颜色等级:0-255(8位的颜色深度,2的8次方=256,就是0-255)

纵坐标为每个颜色等级在整整图片上出现的概率:0-1

直方图均衡化

如果一付图片上的直方图没有均匀分布,而是集中在某一处,

这时可以利用直方图均衡化算法,让原本聚合在一起的直方图尽可能的离散化

这个过程就被称为直方图的均衡化

直方图的均衡化也分为对灰度图像的均衡化和对彩色图像的均衡化

经过直方图均衡化后的图像的亮度、清晰度等会视觉上感觉很漂亮

彩色图像的直方图均衡化

灰度图像的直方图均衡化

图片美白

图像的亮度增强

将当前的每个像素点的灰度值加上一个固定的值

或者将当前的每个像素点的灰度值乘以一个固定的放大系数(如1.1,1.2等)

这个算法是对整个图像进行亮度增强

磨皮美白:

采用双边滤波器来实现

图像滤波:

高斯滤波

使用API实现

中值滤波

根据算法原理,编写源码

均值滤波

图像的修复

如果图像因为某些原因造成了污损,可以采用图像修复算法对图像进行修复


****************图像直方图**********************

知识补充:

思路:

引入opencv

引入numpy

定义函数(用于直方图的统计)

调用API完成直方图的统计每种像素等级出现的次数h

调用API获取直方图中的最大值和最小值的坐标

创建空白画布

画布上绘制直方图

h将归一化数据在0-255之间

调用API绘制直方图

显示绘制好的直方图

读取图片

调用API将图像矩阵,分解为按照RGB三个通道分为三个矩阵

循环调用函数绘制直方图

暂停

代码实现:

import cv2

import numpy as np

def ImageHist(image,type):

    color=(255,255,255)#定义颜色,此处为白色

    windowName='Gray'#定义窗体名称

    if type==31:#表示蓝色

        color=(255,0,0)

        windowName='B Hist'

    elif type==32:#表示绿色

        color=(0,255,0)

        windowName='G Hist'

    elif type==33:#表示红色

        color=(0,0,255)

        windowName='R Hist'


    hist=cv2.calcHist([image],[0],None,[256],[0.0,255.0])#调用API完成直方图的统计,calcHist([图像矩阵],[直方图的通道],mask蒙版,[直方图横坐标范围],[直方图中像素值范围]])

    print(hist)

    minV,maxV,minL,maxL=cv2.minMaxLoc(hist)#调用API获取直方图中的最大值和最小值的坐标

    histImg=np.zeros([256,256,3],np.uint8)#创建空白画布

    for h in range(256):

        intenNormal = int(hist[h]*256/maxV)

        cv2.line(histImg,(h,256),(h,256-intenNormal),color)

    cv2.imshow(windowName,histImg)

    return histImg

img=cv2.imread('a.jpg',1)

channels=cv2.split(img)#将RGB图像分解为,R,G,B三个颜色通道

for i in range(3):

    print(channels[i])

    ImageHist(channels[i],31+i)


cv2.waitKey(0)

****************直方图均衡化*******************

知识补充:

思路:

引入opencv

引入numpy

读取图片

实现图像的灰度化

调用API完成灰度图像的直方图均衡化

显示处理后的图像

暂停

代码实现:

import cv2

import numpy as np

img=cv2.imread('a.jpg',1)

gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

cv2.imshow('img',gray)

dst=cv2.equalizeHist(gray)




******************补充*********************

监督学习:有特征和标签

分类问题:输出是离散的数据

回归问题:输出是连续的数据

尽量把问题转换为分类问题,这样比较好处理


非监督学习:没有标签

聚类:最常用K-means

密度估计:

入门sklearn(实现了很多机器学习的算法)

()


KNN,用于minist

获取原始图像的时候,每个环节都可能引入噪声(比如放大图像,图像会模糊不清,锯齿状,这就产生了噪声)

引入噪声的可能环节:传感器质量差导致噪声,光线差引入噪声,对图像量化时引入噪声

去除噪声的操作叫图像复原,也叫图像去噪,也叫图像滤波(往往是我们拿到图像之后的第一步操作)。(图像收到噪声污染,叫做图像退化,去燥的过程就叫做复原)

常见的噪声:加性噪声(不论有误信号,噪声始终存在,噪声与信号的关系是相加的关系,一般把加性噪声看成是系统的背景噪声),乘性噪声(信号存在,则噪声存在,信号不存在,则噪声不存在,它与信号的关系是相乘的,把乘性噪声看成是系统的变化噪声)

常听说的噪声:白噪声(功率谱在频域内分布的噪声),高斯噪声(高斯型的噪声,其实就是正态分布型噪声)



滤波(也叫相关)算法:常说的图像滤波是指空间滤波和频率滤波

去燥:做平均(用滑动平均窗口,其实就是用卷积核来进行滤波,但计算方式与卷积不同)

高斯滤波:典型的高通滤波器,完全把高频阻断,得到的图像非常平滑(牢记高斯公式)

相关和卷积都是线性的运算(满足线性运算的各中性质,比如交换律结合律等,在加速元算时很有用)

一种非线性滤波器:均值滤波器

边缘检测算法

全局特征

局部特征

SIFT

你可能感兴趣的:(python版opencv笔记(无私奉献版))