openCV部分基础知识

1.获取图像属性
常用的图像属性包括图像的行(height)、列(width)、通道(channel)、像素点数目、像素点数据类型等
row,col,channel=img.shape   #获取图像的行列通道
pixels=img.size  #图像像素数目
type=img.dtype   #图像的数据类型,常用的为uint8
ROI=img[a:b,c:d] #可以获取某一区域内的像素值

2.图像通道的拆分合并
openCV彩图的三通道分别为(B,G,R),和我们常用的(R,G,B)顺序不一样
    拆分
    b,g,r=cv2.split(img)#比较耗时
    合并
    img=cv2.merge([r,g,b])
 对单一通道进行操作可以采用
    img[:,:,channel]进行索引channel=[0,1,2]
   
3.图像的操作
3.1 扩边(边缘填充)
实例1
若你想在图片边缘再向外扩展(在卷积运算中有时会用到)
函数:cv2.copyMakeBorder(src,top,bottom,left,right,borderType)
(top,bottom,left,righ)对应边界填充数目
borderType:cv2.BORDER_CONSTANT 添加有颜色的常熟边界,需要下一个参数(value)
           cv2.BORDER_REFLECT  边界元素镜像,如fedcbd|abcdefgh|hgfedcb
           cv2.BORDER_REFLECT_101 or cv2.BORDER_DEFAULT  和上面类似,但有改动, gfedcb|abcdegfh|gfedcba
           cv2.BORDER_REPLICATE  重复最后一个元素,aaaaaa|abcdefgh|hhhhhhh
           cv2.BORDER_WRAP  截断,复制  cdefgh|abcdegfh|abcdefg
value,当borderType为cv2.BORDER_CONSTANT时需要输入边界颜色
3.2 图像上的算术运算
包括:加法,减法,位运算等
cv2.add(),cv2.addWidgeted()
3.2.1 图像加法
cv2.add(image1,image2)或者使用numpy,img=img1+img2
:加法要求做加法的两张图像大小,像素格式必须一致,或者第二张图像只是一个标量值
opencv中的加法运算与numpy加法有所不同
前者是对图像做一种饱和操作,后者是一种模运算
相对图像领域来说,我们更喜欢openCV的加法
实例2
3.3 图像混合
也是一种加法,不过对于加法的元素取不同的权重,给人一种混合或者透明的感觉,计算公式
                    g(x)=(1-alpha)*f0(x)+alpha*f1(x)+gama   (gama为其他信号)
听说通过修改alpha值可以实现非常炫酷的混合(实例3)
3.4 按位运算
常见的按位运算有:AND,OR,NOT,XOR等
有时,我们可以将一张图像中某个特征提取出来,将其显示在另外一张图像中,类似抠图,可以利用按位运算
来实现(实例4,下一节附上,非常好玩实用的技能)
3.5程序性能
3.5.1 获取程序运行时间,默认优化
cv2.getTickCount,  #获取从参考点到该处所花的时钟数
cv2.getTickFrequency   #每秒钟的时钟数
#(timeout-timestart)/frequency
优化默认为开启状态,可以使用cv2.useOptimized()来查看优化是否开启
cv2.setUseOptimized(boolean)来开启
在代码中,尽量避免使用循环,尤其是双层三层循环,尽量使用向量操作,numpy和openCV都对向量操作进行了优化,
没有必要就不要复制数组,使用视图来代替复制
3.6 颜色空间转换
BGR←→GRAY    BGR←→HSV
函数cv2.cvtColor(src,flag)  #flag为转换类型,常用有cv2.COLOR_BGR2GRAY,cv2,COLOR_BGR2HSV  #(H(色度)取值[0,179]S(饱和度)取值[0,255],V(亮度)取值[0,255])
cv2.inRange()
HSV不同的软件使用的值可能不同,进行对比时,记得归一化
查询flag的方法
import cv2
flags=[i for i in dir(cv2) if i.startswith('COLOR_')]#很多种(274)
print(flags)

实例1(扩充边界)

import cv2
import numpy as np
import pylab
from matplotlib import pyplot as plt
pylab.rcParams['figure.figsize'] = (25.0, 12.0) # 显示大小

Blue=[0,0,255]

img=cv2.imread('rectAndPolylines.jpg')

b,g,r=cv2.split(img)
img=cv2.merge([r,g,b])
#不同的扩充方法
replicate=cv2.copyMakeBorder(img,30,10,10,30,cv2.BORDER_REPLICATE)
reflect=cv2.copyMakeBorder(img,30,10,10,30,cv2.BORDER_REFLECT)
reflect101=cv2.copyMakeBorder(img,30,10,10,30,cv2.BORDER_REFLECT_101)
wrap=cv2.copyMakeBorder(img,30,10,10,30,cv2.BORDER_WRAP)
constant=cv2.copyMakeBorder(img,30,10,10,30,cv2.BORDER_CONSTANT,value=Blue)

plt.subplot(231),plt.imshow(img,'gray'),plt.title('Original')
plt.subplot(232),plt.imshow(replicate,'gray'),plt.title('Replicate')
plt.subplot(233),plt.imshow(reflect,'gray'),plt.title('Reflect')
plt.subplot(234),plt.imshow(reflect101,'gray'),plt.title('Reflect101')
plt.subplot(235),plt.imshow(wrap,'gray'),plt.title('Wrap')
plt.subplot(236),plt.imshow(constant,'gray'),plt.title('Constant')
plt.xticks([]),plt.yticks([])

plt.show()

openCV部分基础知识_第1张图片

图1 不同的扩充方法实验效果

可以明显看出各种方法的不同之处,Reflect的两种方法效果非常接近,只是在边缘细节的地方不一样,可以根据实际的效果来选择,而wrap则与前者不一样,尤其在边界的效果上,如果需要做到无缝的扩充则是reflect效果好。常数的扩充则在卷积过程中用的较为广泛。reflect和wrap可以做出很漂亮的印花图案(下图)。

openCV部分基础知识_第2张图片

实例2(openCV与Numpy的图像加法)

在前面的知识简介中已经作了描述,这里就直接附上效果图。

#区域加法
img1=240*np.ones((50,50,3),np.uint8)
img2=60*np.ones((50,50,3),np.uint8)
addValue=100#可以加上一个常数
#利用opencv的add函数
imgCVAdd=cv2.add(img1,img2)
#直接像素矩阵相加numpy
imgNumpyAdd=img1+img2
imgConstantAdd=cv2.add(img1,addValue)
imgConstantNumpyAdd=img1+addValue
openCV部分基础知识_第3张图片
图2 图像加法效果图

OpenCV的加法在图像领域还是要用的广泛,知道这种加法做起来会简便很多。

实例3 做一个可以调节权重的图像混合GUI

通过调节滑动条,我们可以实时控制两张图所占的比例,实现过程如下:

#读取图片
img1=cv2.imread('bob.png')
img2=cv2.imread('edithFinch2.jpg')
#可以在创建滑动条时做的事情,此处没想到可以做什么特别的,可以初始化一些数据
def doNothing(x):
    pass

cv2.namedWindow('AddPictures')
cv2.createTrackbar("weight(%)",'AddPictures',30,100,doNothing)#创建滑动条来控制权重

while(1):
    weight=cv2.getTrackbarPos("weight(%)",'AddPictures')
    #图像融合,根据比例来确定两张图片所占比重
    dstImage=cv2.addWeighted(img1,0.01*weight,img2,0.01*(100-weight),0)#两张图像的大小得一致
    cv2.imshow('AddPictures',dstImage)
    if cv2.waitKey(10) & 0xFF==ord('q'):#按下q,退出程序
        break
cv2.destroyAllWindows()
openCV部分基础知识_第4张图片

参考文献:OpenCV官方教程中文版for python

你可能感兴趣的:(计算机视觉)