jQuery火箭图标返回顶部代码

jQuery火箭图标返回顶部代码

滚动滑动条后,查看右下角查看效果。很炫哦!!

适用浏览器:IE8、360、FireFox、Chrome、Safari、Opera、傲游、搜狗、世界之窗.

2 opencv-python核心库模块core(上)

core模块定义了opencv中的基础数据结构和基础运算,是整个库的核心模块。而mat数据结构是opencv中最重要的数据结构,是opencv中图像最常用的存储格式。本章节主要记录opencv的基本数据结构,图像的裁剪和缩放,矩阵的简单运算,图像通道分解合并以及几个有趣的实验。

1 基本数据结构

opencv的基本数据结构有mat数据结构,point数据结构,rect数据结构,size数据结构。

1)在python中,mat类型的对象构造操作可以通过numpy来实现(创建图像矩阵)

如下代码构建全0矩阵m1,然后将所有值初始化为128,还可以用copy进行矩阵拷贝,也可以对图像数据的部分原始值进行修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
import cv2
import numpy as np        #python中,mat类型的对象通过numpy来实现
 
m1 = np.zeros([512,512],np.uint8)  #创建全0二维矩阵
m1[:] = 128  #初始化赋值
 
m2 = m1.copy()   #把m1图像拷贝到m2
m2[128:384,128:384] = 0  #将行,列为128到384的区域像素值赋值为0
 
cv2.imshow('m2',m2)
cv2.imshow('m1',m1)
cv2.waitKey(0)
cv2.destroyAllWindows()

2 图像的裁剪和缩放

可以对图像矩阵进行裁剪和缩放,裁剪直接用python的切片来完成,缩放可以用opencv的 resize() 函数来操作。resize函数介绍如下:

cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]]) -> dst

参数说明:

src:原图像;dst:改变大小的目标图像;dsize:输出图像的大小。

fx:width方向的缩放比例;fy:height方向的缩放比例;

interpolation:指定插值的方式,图像resize之后,像素要重新计算,靠这个参数来指定重新计算像素的方式,有以下几种:
INTER_NEAREST - 最邻近插值
INTER_LINEAR - 双线性插值,如果最后一个参数你不指定,默认使用这种方法
INTER_AREA -区域插值,使用像素区域关系进行重采样(效果最好)
INTER_CUBIC - 4x4像素邻域内的双立方插值
INTER_LANCZOS4 - 8x8像素邻域内的Lanczos插值

有两点需要注意:1 dsize和fx/fy不能同时为0。指定dsize的值,让fx和fy直接省略或置0 或者 dsize=None或置 (0,0),指定fx和fy的值,(dsize不可省略,会报错)。2 图像的size是(h,w),而
resize的操作是先w,再h。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import cv2         #图像裁剪和缩放
import numpy as np
 
img = cv2.imread('cat.jpg')
cv2.imshow('cat',img)
 
rows = img.shape[0]   #图像的行(高) [h,w,c]
cols = img.shape[1] #图像的列(宽)
 
img2 = img.copy()    #把img1图像拷贝到img2
img2 = cv2.resize(img2,(int(cols/2),int(rows/2)))  #图像尺寸减小为原来的一半,不是裁剪 [w,h]
cv2.imshow('img2',img2)
 
img3 = img[0:int(rows/2),0:int(cols/2)]   #图像裁剪为原来的1/4,用切片来裁剪,cropped_image = img[80:280, 150:330]  切片img[高,宽]
 
cv2.imshow('img3',img3)
 
cv2.waitKey(0)
cv2.destroyAllWindows()

2)在opencv中,点的定义由point类实现。python语言中,point类型可以由tuple元组表示,然后利用numpy进行点乘和叉乘计算。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import numpy as np     #tuple元组点乘叉乘(向量内积/外积)
 
point1 = (10,20)
point2 = (2,4)
print(type(point1))  #tuple(元组,有序且不可更改的集合)类型,
# 元组与列表相似,不同之处在于元组的元素不能修改,而列表的元素可以修改。元组使用小括号(),列表使用中括号[]。
 
res1 = np.dot(point1,point2) #点乘
print('res1',res1)
 
point3 = (1,2,3)
point4 = (4,5,6)
 
res2 = np.cross(point3,point4)  #叉乘,输出一个向量,方向垂直于输入两向量形成的平面
print('res2',res2)

3)opencv中定义了矩形的表示类rect,模板类rect定义了顶点坐标,宽高,面积等信息的获取操作,以及矩形是否包含点的判断操作。在python中的rect也是通过tuple类型的数据表示,即左上角坐标点(x,y)和矩形宽高4个值表示的rect为(x,y,w,h)的形式,在需要传入rect数据类型的地方,可以按照tuple类型的数据传入。

4)opencv的很多函数中都需要传入size类型的参数,比如mat类的后置函数为mat(Size size,int type),需要通过size类型对象传入构造矩阵的尺寸。size类型对象包含两个成员变量width和height。python中的size对象也是通过tuple类型的数据表示,即 (w,h) 的形式传入宽高数据的,在需要传入size数据类型的地方,可以按照tuple类型的数据传入。

3 矩阵运算

core模块中提供了图像矩阵的基本运算,opencv对这些基本运算都做了封装,比如四则运算,位运算,比较运算等。

 1)四则运算

加法:dst = add(src1, src2, mask=None)  减法:dst = subtract(src1, src2, mask=None)  乘法:dst = multiply(src1, src2)  除法:dst = divide(src1, src2)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import cv2    #矩阵加减乘除,相当于对矩阵中的每个元素进行对应操作
import numpy as np
 
m1 = np.array([[1,2,3],[4,5,6],[7,8,9]],dtype=float#创建ndarray二维数组(矩阵),数据类型为浮点数
m2 = np.array([[11,12,13],[14,15,16],[17,18,19]],dtype=float)
 
m_add = cv2.add(m1,m2)   #等同于m_add = m1 + m2
print('add:',m_add)
m_sub = cv2.subtract(m1,m2)  #等同于m_sub = m1 - m2
print('subtract:',m_sub)
m_mul = cv2.multiply(m1,m2)  #等同于m_mul = m1 * m2
print('multiply:',m_mul)
m_div = cv2.divide(m1,m2)   #等同于m_div = m1 / m2
print('divide:',m_div)
 
m_num = m1+5   #直接加减数字相当于矩阵中的元素都加减该数字
m_num2 = cv2.add(m1,5)
 
print('m_num:\n',m_num)
print('m_num2:\n',m_num2)

2) 位运算

opencv中定义了位运算函数:

按位与:dst = bitwise_and(src1, src2, mask=None)   按位或:dst = bitwise_or(src1,src2, mask=None)   按位异或:dst = bitwise_xor(src1, src2, mask=None) 非运算:dst = bitwise_not(src, mask=None) 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import cv2  #矩阵/图像位运算
import numpy as np
 
m1 = np.array([[1,2],[3,1]])
m2 = np.array([[5,3],[4,6]])
 
m_and = cv2.bitwise_and(m1,m2)   #按位与(转换为二进制,对应位均为1时,结果为1,其余为0)
print('m_and:',m_and)
 
m_or = cv2.bitwise_or(m1,m2)  #按位或(如果两个相应的二进制位有一个为1,则该结果为1,否则为0)
print('m_or:',m_or)
 
m_xor = cv2.bitwise_xor(m1,m2) #异或运算(如果两个相应的二进制位值不同则为1,否则为0)
print('m_xor:',m_xor)
 
m_not = cv2.bitwise_not(m1) #非运算(转换为二进制,对应位取反)
print('m_not:',m_not)<br>

3)代数运算

计算矩阵均值的函数:retval = mean(src,mask=None)   

对矩阵进行归一化:dst = normalize(src, dst, alpha=None, beta=None, norm_type=None, dtype=None, mask=None) alpha表示归一化的上界,beta表示归一化的下界。norm_type表示归一化类型(归一化是机器学习和深度学习很重要的一个技巧,可以减小数据之间的差异对模型训练结果的影响,还可以加速模型收敛)

平方根:dst = sqrt(src)   幂运算:dst = pow(src, power) 也可以直接 src**power   指数运算:dst = exp(src)  对数运算:dst = log(src) 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import cv2
import numpy as np      #矩阵代数运算
 
m1 = np.array([[1,2,3],[3,4,5]],dtype=float
 
mean_res = cv2.mean(m1)   #矩阵均值返回值类型是tuple,有四个元素,第一个是均值
print('the mean is:',mean_res)
print(type(mean_res))
 
dst = np.array([])       #均值归一化参数的返回值需要一个对象
norm_res = cv2.normalize(m1,dst,norm_type=cv2.NORM_MINMAX)  #线性归一化
print('norm_res:',norm_res)
 
sqrt_res = cv2.sqrt(m1)
print('sqrt_res:',sqrt_res) #平方根
 
pow_res = cv2.pow(m1,3)
print('pow:',(m1)**3)   #幂运算
print('pow_res:',pow_res)  #幂运算
 
exp_res = cv2.exp(m1)     #指数运算
print('exp_res:',exp_res)
 
log_res = cv2.log(m1)
print('log_res:',log_res)  #对数运算

 4) 比较运算

两个矩阵的比较:dst = compare(src1, src2, cmpop)  cmpop表示比较方式。(CMP_EQ=0,相等;CMP_GT=1, 大于等于;CMP_GE=2,大于;CMP_LT=3, 小于等于;CMP_LE=4, 小于;CMP_NE=5, 不等于) 求最大值:dst = max(src1, src2)    求最小值:dst = min(src1, src2)   还有一个比较有用的函数:minval, maxval, minloc,maxloc = minMaxLoc(src, mask=None) 可以输出矩阵最大最小值和其对应的位置。

矩阵排序:dst = sort(src, flags) flags表示排序方式,由SortFlags定义。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import cv2
import numpy as np      #矩阵比较运算
 
m1 = np.array([[1,6,3],[15,12,5]],dtype=float
m2 = np.array([[9,5,3],[14,12,16]],dtype=float)
 
compare_res1 = cv2.compare(m1,m2,cv2.CMP_EQ) #比较两个矩阵对应的元素是否相等,等返回255,不等返回0
compare_res2 = cv2.compare(m1,m2,cv2.CMP_GT) #判断m1的元素是否大于等于m2,是返回255,非返回0
 
max_res =cv2.max(m1,m2)  #求两个矩阵中的最大值,元素比较
min_res =cv2.min(m1,m2)  #求两个矩阵中的最小值,元素比较
minmax_loc = cv2.minMaxLoc(m1)  #求矩阵中的最小值,最大值和对应的坐标,不是下标(cv是列优先,(0,2)代表第一列第三行)
                                  #OpenCV读取的图像矩阵坐标与图像坐标系下的坐标横纵正好相反 
     
sort_res = cv2.sort(m1,cv2.SORT_ASCENDING) #升序排序
 
print('res1:',compare_res1)
print('res2:',compare_res2)
print('max_res:',max_res)
print('min_res:',min_res)
print('minmax_loc:',minmax_loc)
print('sort_res:',sort_res)
 
print('m1[1][0]:',m1[1][0])

 5)特征值和特征向量

特征值和特征向量在机器学习中很常见,opencv提供了函数eigen来计算对称矩阵的特征值和特征向量,非对称矩阵用eigenNonSymmetric。

retval, eigenvalues, eigenvectors = eigen(src)  retval是返回状态,eigenvalues是返回的特征值,eigenvectors 是返回的特征向量。

opencv提供了生成随机数矩阵的函数randn和randu,randn生成的矩阵服从正态分布,randu生成的矩阵服从均匀分布。dst = randn(dst, mean, stddev) mean表示均值,stddev表示随机数的标准差。dst = randu(dst, low, high) low表示随机数的生成下界,high表示随机数生成的上界。

opencv还提供了将矩阵的行/列视为一组一维向量,并对向量执行指定的操作(REDUCE_AVG=1, 计算均值;REDUCE_MAX=2, 计算最大值;REDUCE_MIN=3, 计算最小值;REDUCE_SUM=0, 计算行/列的和),直到获得单个行/列,从而将矩阵缩减为一个向量。 dst = reduce(src, dim, rtype)  dim为0表示矩阵降维为单行,1表示矩阵降维为单列。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import cv2          #生成随机数矩阵,计算矩阵的特征值和特征向量,矩阵转向量
import numpy as np
 
m1 = np.zeros((2,3),dtype=np.int) #创建全0矩阵整型
m2 = np.ones((3,3),dtype=np.float) #创建全1矩阵浮点型
 
m1 = cv2.randn(m1,3,1#生成服从正态分布的矩阵,均值3,标准差1
m2 = cv2.randu(m2,1,10#生成服从均匀分布的矩阵,下界1,上界10
print('m1:\n',m1,'\nm2:\n',m2)
 
eigen_res = cv2.eigen(m2)  #计算对称矩阵的特征值和特征向量,矩阵必须是方阵,元素是float
print('eigen_res:\n',eigen_res)
 
eigen_res2 = cv2.eigenNonSymmetric(m2) ##计算非对称矩阵的特征值和特征向量,矩阵必须是方阵,元素是float
print('eigen_res2:\n',eigen_res2)
 
img = cv2.imread('./cat.jpg')
 
dst = cv2.reduce(img,0,cv2.REDUCE_AVG) #矩阵转向量,对矩阵的行/列视为一组向量单独操作(取均值,最大,最小,和),参数0表示降为单行,1为单列
                                          #每行/列返回一个值,从而将矩阵缩减为一个向量
 
print('dst:',dst.shape)  #将输入矩阵的每一列取均值,组成一个单行的向量
print('cat:',img.shape)

 6)图像通道分离与通道合并

对于一幅RGB格式的图像,包括R,G,B三个通道,opencv提供了通道分离函数split函数,和通道合并函数merge。

通道分离:b,g,r = split(img)    通道合并:dst = merge(mv)   mv = [b,g,r]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import cv2  #图像通道分离/合并
import numpy as np
 
img = cv2.imread('cat.jpg')
 
 
#img[:,:,0]=0  #img[]前两个参数是指的h,w,冒号指全部取得,最后一个参数是指的通道序列号,图像的通道为BGR,分别对应012
 
b,g,r = cv2.split(img)  #图像通道分离
 
cv2.imshow('cat',img)
cv2.imshow('img_r',r)  #显示红色通道图像,单通道图像是灰色
cv2.imshow('img_g',g)
cv2.imshow('img_b',b)
 
g[:] = 0    #绿色图像设置为0 
b[:] = 0    #蓝色图像设置为0 
merge_res = cv2.merge([b,g,r]) #图像通道合并,只剩下红色通道没变,图像会显示红色
 
cv2.imshow('merge:',merge_res)
 
cv2.waitKey(0)
cv2.destroyAllWindows()

有趣的事1:对单通道进行运算,用来改变图像的整体颜色:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import cv2   #对图像单通道进行操作
 
img = cv2.imread('./cat.jpg')
print(img.shape)
 
b,g,r = cv2.split(img)  
 
r2 = cv2.add(r,30#只增加红色通道的像素值,给图像加红
b2 = cv2.add(r,30)    #只增加蓝色通道的像素值,给图像加蓝
 
img2 = cv2.merge([b,g,r2])
img3 = cv2.merge([b2,g,r])
 
#img2 = cv2.add(img,-30)   #用cv的add算法加减,只有第一列r像素值改变了,bg通道像素值不变,且像素值最大255,最小0(加变红紫,减变黄)
#img3 = img - 30    #直接用+号加减数字,所有像素值都改变了,且超过255的像素值对256取余。
 
 
cv2.imshow('img',img)
cv2.imshow('red',img2)
cv2.imshow('blue',img3)
 
 
cv2.waitKey(0)
cv2.destroyAllWindows()

 

有趣的事2:计算一幅rgb图像中有多少种不同的颜色:

首先,什么是不同的颜色:对rgb图像来说,只要红绿蓝三个通道的任何一个通道的像素值不相同,那么就是不同的颜色。也就是说,要计算有多少中颜色,就是要计算三通道的不同像素值的排列组合有多少种。用split把图像分为三个通道brg,每个通道都是m*n的矩阵,每个矩阵的像素值范围是0-255。统计每个通道(矩阵)内不重复元素的个数(1 可以用count函数统计每个像素值出现的次数,然后相加。2 先用set集合去重,再用len统计个数。3 想要统计每个元素出现的次数,可以使用collections模块提供的Counter函数。4 numpy中的unique()函数可以用来统计一个数组中不同元素的个数,此处使用unique,然后用len计算),然后把三个通道的统计数相乘就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import cv2
import numpy as np
 
img = cv2.imread('./cat.jpg')
 
b,g,r = cv2.split(img)
 
 
count_b = len(np.unique(b))
count_g = len(np.unique(g))
count_r = len(np.unique(r))
 
 
count = count_b * count_g * count_r
print('color number:',count)      #<em id="__mceDel">color number: 16386304</em>

 

有趣的事3:利用进度条实现一个简单的颜色混合器(调色板),即在图像窗口中创建三个进度条,进度条的值为0-255,3个进度条的值对于图像的RGB 3个通道的值,调节进度条可以查看颜色混合后的效果。

opencv提供了创建进度条的函数 createTrackbar,createTrackbar(trackbarName, windowname, minval, maxval, callback)

opencv还提供了用于获取进度条位置的函数 getTrackbarPos,retval = getTrackbarPos(trackbarname, winname)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import cv2
import numpy as np  #利用trackbar显示RGB颜色通道,方法一
 
cv2.namedWindow('trackbar',cv2.WINDOW_NORMAL)  #定义窗口
cv2.resizeWindow('trackbar',640,480)
 
def callback(value):   #回调函数(回调函数不做操作)
    pass
 
cv2.createTrackbar('R','trackbar',0,255,callback) #定义三个trackbar
cv2.createTrackbar('G','trackbar',0,255,callback)
cv2.createTrackbar('B','trackbar',0,255,callback)
 
img = np.zeros((480,640,3),np.uint8)  #定义一个全黑图像
 
while True:
    r = cv2.getTrackbarPos('R','trackbar'#循环获取trackbar的返回值
    g = cv2.getTrackbarPos('G','trackbar')
    b = cv2.getTrackbarPos('B','trackbar')
     
    img[:] = [b,g,r]    #给图像的brg三个颜色通道赋值<br>
    cv2.imshow('trackbar',img)   #显示赋值后的当前图像<br>
    if cv2.waitKey(1) == ord('q'):  #等待1ms或者键盘输入q进入下一次循环
        break
cv2.destroyAllWindows()

  可以把获取进度条的值和把值赋给图像的代码放到回调函数中去:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import cv2
import numpy as np  #利用trackbar显示RGB颜色通道,方法二
 
cv2.namedWindow('trackbar',cv2.WINDOW_NORMAL)
cv2.resizeWindow('trackbar',(640,480))
 
def callback(pos):
    r = cv2.getTrackbarPos('R','trackbar'#回调函数(把获取进度条的值放在回调函数中)
    g = cv2.getTrackbarPos('G','trackbar')
    b = cv2.getTrackbarPos('B','trackbar')
    img[:] = [b,g,r]               #给图像的三个颜色通道赋值
    cv2.imshow('trackbar',img)   #只要trackbar的值改变,就重置图片颜色
     
img = np.zeros((480,640,3),np.uint8)
 
cv2.createTrackbar('R','trackbar',0,255,callback)
cv2.createTrackbar('G','trackbar',0,255,callback)
cv2.createTrackbar('B','trackbar',0,255,callback)
 
 
 
while True:
    cv2.imshow('trackbar',img)  #循环显示图片
    key = cv2.waitKey(0)
    if key == ord('q'):
        break
cv2.destroyAllWindows()

 两种方法都可以实现拖动进度条来达到颜色混合的目的,如下:

  

 

 利用进度条直接改变图片的颜色呢,比如直接通过进度条来加红加蓝,然后观察效果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import cv2
import numpy as np  #输入图片,将图片整体加红/加绿/加蓝
 
cv2.namedWindow('change_color',cv2.WINDOW_NORMAL)
cv2.resizeWindow('change_color',(600,600))
 
def callback(value):   #回调函数
    pass
 
cv2.createTrackbar('R','change_color',0,255,callback)  #创建三个进度条
cv2.createTrackbar('G','change_color',0,255,callback)
cv2.createTrackbar('B','change_color',0,255,callback)
 
img = cv2.imread('./cat.jpg')
     
while True:
    r = cv2.getTrackbarPos('R','change_color')
    g = cv2.getTrackbarPos('G','change_color')
    b = cv2.getTrackbarPos('B','change_color')
     
    img_b,img_g,img_r = cv2.split(img)   #只增加红色通道的像素值,给图像加红
    img_r = cv2.add(img_r,r)
    img2 = cv2.merge([img_b,img_g,img_r])
 
    img_b,img_g,img_r = cv2.split(img2)   #只增加绿色通道的像素值,给图像加绿
    img_g = cv2.add(img_g,g)
    img3 = cv2.merge([img_b,img_g,img_r])
 
    img_b,img_g,img_r = cv2.split(img3)   #只增加蓝色通道的像素值,给图像加蓝
    img_b = cv2.add(img_b,b)
    img4 = cv2.merge([img_b,img_g,img_r])   
     
    cv2.imshow('change_color',img4)
    key = cv2.waitKey(1)
    if key == ord('q'):
        break
 
cv2.destroyAllWindows()
    

  

 

 

 

  

 

 

 

  

 

posted @   寒水浮云  阅读(379)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
点击右上角即可分享
微信分享提示